< 이전 | 다음 >

제공자 가져오기

이 학습서 레슨에서는 Rational® ClearQuest® 자원에 대해 작업하기 위해 ClearQuest CM API 프로그래밍 모델을 사용하는 첫 번째 단계를 보여 줍니다.
제품 저장소에서 Rational ClearQuest 사용자 데이터베이스와 같은 자원을 검색, 수정, 작성 또는 삭제하려면 먼저 제품 저장소 유형에 맞는 Provider 오브젝트의 인스턴스를 작성해야 합니다.

Provider 오브젝트는 StpProvider 인터페이스를 구현하므로 CM API 라이브러리가 제공하는 구현에 다른 CM API 인터페이스를 연결합니다.

CqProvider 구현 클래스는 리터럴 CqProvider.CQ_ONLY_PROVIDER_CLASS로 이름이 지정됩니다. ProviderFactory.createProvider 메소드로 이를 전달하여 ClearQuest CM API CqProvider 클래스의 인스턴스를 확보하십시오.

또한 ProviderFactory.createProvider는 인스턴스화된 제공자가 Authentication 오브젝트를 얻을 수 있는 Callback 오브젝트를 제공해야 합니다. Authentication 오브젝트는 데이터베이스에서 오퍼레이션을 수행하기 전에(예: 레코드의 상태 변경 또는 필드 값 수정) 사용자를 Rational ClearQuest 사용자로 인증하기 위해 필요한 신임 정보를 제공자에게 제공합니다. 제공하는 Callback 오브젝트를 사용하면 애플리케이션에 사용자 신임 정보(사용자 이름 및 비밀번호) 획득에 대한 완전한 제어가 제공됩니다. 신임 정보는 시작 시 또는 처음 필요할 때 사용자에게 요청하여 애플리케이션에 명시적으로 설정될 수 있습니다.

Provider 오브젝트는 ClearQuest CM API를 사용하는 모든 프로그래밍 유스 케이스에 필요하므로 이 학습서에 있는 모든 예제에서는 모든 애플리케이션에서 사용될 유틸리티 클래스에 정의된 getProvider 메소드를 사용합니다. 유틸리티 클래스에도 정의된 Callback 오브젝트는 사용자가 처음 데이터베이스에 액세스할 때 사용자 이름과 비밀번호를 요청하고 승인 가능한 한 계속해서 해당 신임 정보를 재사용합니다.

/**
 * A simple Authentication object in which the username and password
 * obtained from the user is cached for use by the ClearQuest CM API.
 */
static class UnPw implements Authentication {
    /**
     * Constructs an Authentication object
     * 
     * @param unpw A String[] containing the username and password.
     */
    UnPw(String[] unpw) {  m_data = unpw; }

    public String loginName() { return m_data[0]; }
    public String password() { return m_data.length > 1 ? m_data[1] : ""; };

    /** The cached credentials */
    private String[] m_data;
}


/**
 * Constructs an instance of a CM API provider for ClearQuest.
 * 
 * @return The instantiated CqProvider object
 * @throws Exception
 *             If the provider could not be instantiated
 */
static StpProvider getProvider() throws Exception {
    try {
        Callback callback = new StpCallback() {
            private UnPw m_unpw;

            public Authentication getAuthentication(String r, int c)
            {   return null; /* Will not be called */   }

            public Authentication getAuthenticationEx(Domain domain,
                                                      String realm,
                                                      int retryCount,
                                                      StpProvider provider,
                                                      WvcmException failure) 
            throws WvcmException
            {
                // Try to reuse last credentials on each new repository
                if (m_unpw != null && retryCount == 0)
                    return m_unpw;

                String title = "Enter " + domain 
                        + " Username '+' Password for "
                        + realm + " [" + retryCount + "]";
                
                if (failure != null)
                    title = "Login failed: " + failure + "\n" + title;
                
                String unpw = JOptionPane.showInputDialog(title, "admin+");

                if (unpw == null || unpw.length() == 0)
                    throw new IllegalAccessError("User canceled request");
                
                if (unpw.equals("anonymous"))
                    return null;
                
                if (unpw.startsWith("@")) {
                    File file = new File(unpw.substring(1));

                    try {
                        FileReader reader = new FileReader(file);
                        char[] buf = new char[100];
                        int count = reader.read(buf);

                        unpw = new String(buf, 0, count);
                        reader.close();
                    } catch (Throwable t) {
                        Utilities.exception(null,
                                            "Reading password file " + unpw,
                                            t);
                    }
                }

                return m_unpw = new UnPw(unpw.split("\\+", -2));
            }
        };

        // Instantiate a Provider
        return (StpProvider) ProviderFactory
            .createProvider(StpProvider.PROVIDER_CLASS, callback);
    } catch (InvocationTargetException ite) {
        WvcmException e = (WvcmException) ite.getTargetException();

        System.out.println("*** " + e);
        
        for (Throwable nested: e.getNestedExceptions())
            System.out.println("***  " + nested);

        throw e;
    }
}

이 예제에서는 확장된 StpProvider.StpCallback 인터페이스의 인스턴스를 사용합니다. 인증이 요청될 때 더 많은 정보가 제공되기 때문입니다.

ClearQuest CM API는 StpException을 발생시켜 모든 오류를 보고하므로, 이러한 예외 정보를 텍스트 메시지로 형식화하고 Swing 대화 상자에 표시하는 메소드를 유틸리티 클래스에 포함시킵니다.

/**
 * Extracts the message content from a Throwable and returns it as a
 * hierarchical array of Strings capturing the nesting of the Throwable's
 * message components. This structure formats reasonably in a SWING
 * showMessageDialog invocation.
 * 
 * @param ex The Throwable object whose message content is to be extracted.
 * @return If the given Throwable has nested components, an array consisting
 *         of the Throwable's message and an array of the nested messages.
 */
private static Object messages(Throwable ex) {
    String msg = ex.getLocalizedMessage();

    if (msg == null || msg.length() == 0)
        msg = ex.toString();

    if (ex instanceof StpException) {
        Throwable[] nested = ((StpException) ex).getNestedExceptions();

        if (nested != null && nested.length > 0) {
            Object[] msgs = new Object[nested.length];

            for (int i = 0; i < msgs.length; ++i)
                msgs[i] = messages(nested[i]);

            return new Object[] { msg, msgs };
        }
    } else if (ex.getCause() != null) {
        return new Object[] {msg, new Object[]{messages(ex.getCause())}};
    }

    return msg;
}

/**
 * Displays a Swing dialog containing the messages associated with a given
 * Throwable.
 * 
 * @param frame The parent frame for the message dialog.
 * @param title The title to appear in the dialog window.
 * @param ex The throwable whose messages are to be displayed.
 */
static void exception(Component frame, String title, Throwable ex) {
    JOptionPane.showMessageDialog(frame,
                                    messages(ex),
                                    title,
                                    JOptionPane.ERROR_MESSAGE);
}
이제 제공자를 가져오고 예외를 처리하기 위한 코드를 보유하고 있으므로 Rational ClearQuest 사용자 데이터베이스에서 사용 가능한 자원에 대해 작업을 시작할 수 있습니다.

레슨 체크포인트

ClearQuest CM API를 사용하는 프로그램을 작성할 때 첫 번째 단계는 Callback 오브젝트를 작성하고 제품 특정 자원에 대해 작업할 수 있는 Provider 오브젝트를 가져오는 것입니다.
이 레슨에서 학습한 내용은 다음과 같습니다.
  • Callback 오브젝트에 대한 정보
  • Provider 오브젝트에 대한 정보
  • ClearQuest CM API 예외 처리에 대한 정보
  • ClearQuest CM API를 사용하여 Callback 및 Provider 오브젝트를 인스턴스화하는 방법
  • 예외 처리 시 ClearQuest CM API를 사용하는 방법
< 이전 | 다음 >

피드백