001/*
002 * file ProviderFactory.java
003 *
004 * Licensed Materials - Property of IBM
005 * Restricted Materials of IBM
006 *
007 * (c) Copyright IBM Corporation 2004, 2008.  All Rights Reserved. 
008 * Note to U.S. Government Users Restricted Rights:  Use, duplication or  
009 * disclosure restricted by GSA ADP  Schedule Contract with IBM Corp. 
010 */
011package javax.wvcm;
012
013import java.lang.reflect.InvocationTargetException;
014import java.util.Map;
015
016/**
017 * A factory class for creating instances of a WVCM provider.
018 * 
019 * This is a convenience class used to simplify the creation of an instance of a WVCM provider. 
020 * A provider is identified by its class name and is runtime loaded. 
021 * 
022 * @since 1.0
023 */
024public final class ProviderFactory {
025
026    // no instantiation permitted
027    private ProviderFactory() {}
028
029    /**
030     * Provides callback functions that can be invoked by a provider.
031     */
032    public interface Callback {
033
034        /**
035         * Authentication information for the current user.
036         */
037        public interface Authentication {
038            /**
039             * Returns the login name of the current user.
040             * 
041             * @return the login name of the current user.
042             */
043            public String loginName();
044
045            /**
046             * Returns the password of the current user.
047             * 
048             * @return the password of the current user.
049             */
050            public String password();
051        }
052
053        /**
054         * Get authentication information for the current user.
055         * <p>
056         * The provider calls Callback.getAuthentication, and the client returns
057         * an object that implements the Authentication interface.
058         * The provider will then call the Authentication interface methods
059         * on that object to obtain authentication information for the current user.
060         * 
061         * @param realm an identifier for the authentication realm that is requesting credentials.
062         *  A single provider instance can access resources in different authentication realms,
063         *  so the user must be provided with the name of the authentication realm in order to
064         *  determine what credentials to provide.
065         * @param retryCount the number of times the provider has unsuccessfully 
066         * attempted to get authentication for this operation.
067         * This parameter helps the client decide when to provide a more detailed authentication
068         * dialog, or potentially abort the operation rather than making additional attempts
069         * to get credentials from the user. 
070         * @return user and password authentication interface.
071         *  If null is returned, the user wishes to login anonymously.
072         * @throws WvcmException if the user aborted the authentication request.
073         */
074        public Authentication getAuthentication(String realm, int retryCount) throws WvcmException;
075
076    }
077
078    /**
079     * Create a WVCM provider with the given class name.
080     * 
081     * @param providerName the fully-qualified class name of the provider.
082     * @param callback the object containing the getAuthentication
083     * method that the Provider will call whenever it needs
084     * to authenticate the current user.
085     * @return an instance of the Provider whose class name is providerName.
086     * @throws Exception if no class of the given name can be found, loaded, or initialized.
087     */
088    public static Provider createProvider(
089            String providerName,
090            Callback callback)
091    throws Exception {
092        try {
093            return (Provider) Class
094            .forName(providerName)
095            .getConstructor(Callback.class)
096            .newInstance(callback);
097        } catch (InvocationTargetException ex) {
098            Throwable cause = ex.getCause();
099            if (cause instanceof WvcmException)
100                throw (WvcmException)cause;
101            else
102                throw ex;
103        }
104    }
105
106    /**
107     * Get a WVCM provider with the given class name, with specified initializers.
108     * 
109     * @param providerName the class name of the provider.
110     * @param callback the object containing the getAuthentication
111     * method that the Provider will call whenever it needs
112     * to authenticate the current user.
113     * @param initArgs a Map containing provider-specific initialization values.
114     * @return an instance of the Provider whose class name is providerName.
115     * @throws Exception if no class of the given name can be found, loaded, or initialized.
116     * 
117     * @since 1.1
118     */
119    public static Provider createProvider(
120            String providerName,
121            Callback callback,
122            Map<String, String> initArgs
123            )
124    throws Exception {
125        try {
126            return (Provider) Class
127            .forName(providerName)
128            .getConstructor(Callback.class, Map.class)
129            .newInstance(callback, initArgs);
130        } catch (InvocationTargetException ex) {
131            Throwable cause = ex.getCause();
132            if (cause instanceof WvcmException)
133                throw (WvcmException)cause;
134            else
135                throw ex;
136        }
137    }
138}