001    /**
002     *
003     * Copyright 2003-2004 The Apache Software Foundation
004     *
005     *  Licensed under the Apache License, Version 2.0 (the "License");
006     *  you may not use this file except in compliance with the License.
007     *  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    
018    //
019    // This source code implements specifications defined by the Java
020    // Community Process. In order to remain compliant with the specification
021    // DO NOT add / change / or delete method signatures!
022    //
023    
024    package javax.security.jacc;
025    
026    import java.security.AccessController;
027    import java.security.PrivilegedActionException;
028    import java.security.PrivilegedExceptionAction;
029    import java.security.SecurityPermission;
030    
031    /**
032     * Abstract factory and finder class for obtaining the instance of the class
033     * that implements the PolicyConfigurationFactory of a provider. The factory
034     * will be used to instantiate PolicyConfiguration objects that will be used
035     * by the deployment tools of the container to create and manage policy
036     * contexts within the Policy Provider.
037     *
038     * Implementation classes must have a public no argument constructor that may
039     * be used to create an operational instance of the factory implementation class.
040     * @see java.security.Permission
041     * @see PolicyConfiguration
042     * @see PolicyContextException
043     * @version $Rev: 240324 $ $Date: 2005-08-26 12:50:35 -0700 (Fri, 26 Aug 2005) $
044     */
045    public abstract class PolicyConfigurationFactory {
046    
047        private final static String FACTORY_NAME = "javax.security.jacc.PolicyConfigurationFactory.provider";
048        private static PolicyConfigurationFactory policyConfigurationFactory;
049    
050        /**
051         * This static method uses a system property to find and instantiate (via a
052         * public constructor) a provider specific factory implementation class.
053         * The name of the provider specific factory implementation class is
054         * obtained from the value of the system property,<p>
055         * <code>javax.security.jacc.PolicyConfigurationFactory.provider</code>.
056         * @return the singleton instance of the provider specific
057         * PolicyConfigurationFactory implementation class.
058         * @throws ClassNotFoundException when the class named by the system
059         * property could not be found including because the value of the system
060         * property has not be set.
061         * @throws PolicyContextException if the implementation throws a checked
062         * exception that has not been accounted for by the
063         * getPolicyConfigurationFactory method signature. The exception thrown by
064         * the implementation class will be encapsulated (during construction) in
065         * the thrown PolicyContextException
066         */
067        public static PolicyConfigurationFactory getPolicyConfigurationFactory() throws ClassNotFoundException, PolicyContextException {
068            SecurityManager sm = System.getSecurityManager();
069            if (sm != null) sm.checkPermission(new SecurityPermission("setPolicy"));
070    
071            if (policyConfigurationFactory != null) return policyConfigurationFactory;
072    
073            final String[] factoryClassName = { null };
074            try {
075                policyConfigurationFactory = (PolicyConfigurationFactory)AccessController.doPrivileged(new
076                    PrivilegedExceptionAction() {
077                        public Object run() throws Exception
078                        {
079                            factoryClassName[0] = System.getProperty(FACTORY_NAME);
080    
081                            if (factoryClassName[0] == null) throw new ClassNotFoundException("Property " + FACTORY_NAME + " not set");
082                            Thread currentThread = Thread.currentThread();
083                            ClassLoader tccl = currentThread.getContextClassLoader();
084                            return Class.forName(factoryClassName[0], true, tccl).newInstance();
085                        }
086                    });
087            } catch(PrivilegedActionException pae) {
088                if (pae.getException() instanceof ClassNotFoundException) {
089                    throw (ClassNotFoundException)pae.getException();
090                } else if (pae.getException() instanceof InstantiationException) {
091                    throw new ClassNotFoundException(factoryClassName[0] + " could not be instantiated");
092                } else if (pae.getException() instanceof IllegalAccessException) {
093                    throw new ClassNotFoundException("Illegal access to " + factoryClassName);
094                }
095                throw new PolicyContextException(pae.getException());
096            }
097    
098            return policyConfigurationFactory;
099        }
100    
101        /**
102         * This method is used to obtain an instance of the provider specific class
103         * that implements the PolicyConfiguration interface that corresponds to
104         * the identified policy context within the provider. The methods of the
105         * PolicyConfiguration interface are used to define the policy statements
106         * of the identified policy context.<p>
107         *
108         * If at the time of the call, the identified policy context does not exist
109         * in the provider, then the policy context will be created in the provider
110         * and the Object that implements the context's PolicyConfiguration
111         * Interface will be returned. If the state of the identified context is
112         * "deleted" or "inService" it will be transitioned to the "open" state as
113         * a result of the call. The states in the lifecycle of a policy context
114         * are defined by the PolicyConfiguration interface.<p>
115         *
116         * For a given value of policy context identifier, this method must always
117         * return the same instance of PolicyConfiguration and there must be at
118         * most one actual instance of a PolicyConfiguration with a given policy
119         * context identifier (during a process context). <p>
120         *
121         * To preserve the invariant that there be at most one PolicyConfiguration
122         * object for a given policy context, it may be necessary for this method
123         * to be thread safe.
124         * @param contextID A String identifying the policy context whose
125         * PolicyConfiguration interface is to be returned. The value passed to
126         * this parameter must not be null.
127         * @param remove A boolean value that establishes whether or not the policy
128         * statements of an existing policy context are to be removed before its
129         * PolicyConfiguration object is returned. If the value passed to this
130         * parameter is true, the policy statements of an existing policy context
131         * will be removed. If the value is false, they will not be removed.
132         * @return an Object that implements the PolicyConfiguration Interface
133         * matched to the Policy provider and corresponding to the identified
134         * policy context.
135         * @throws PolicyContextException if the implementation throws a checked
136         * exception that has not been accounted for by the getPolicyConfiguration
137         * method signature. The exception thrown by the implementation class will
138         * be encapsulated (during construction) in the thrown PolicyContextException.
139         */
140        public abstract javax.security.jacc.PolicyConfiguration getPolicyConfiguration(String contextID, boolean remove) throws PolicyContextException;
141    
142        /**
143         * This method determines if the identified policy context exists with
144         * state "inService" in the Policy provider associated with the factory.
145         * @param contextID A string identifying a policy context
146         * @return true if the identified policy context exists within the provider
147         * and its state is "inService", false otherwise.
148         * @throws PolicyContextException if the implementation throws a checked
149         * exception that has not been accounted for by the inService method
150         * signature. The exception thrown by the implementation class will be
151         * encapsulated (during construction) in the thrown PolicyContextException.
152         */
153        public abstract boolean inService(String contextID) throws PolicyContextException;
154    }