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