001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package javax.security.jacc;
023:
024: import java.security.SecurityPermission;
025: import java.security.AccessController;
026: import java.security.PrivilegedExceptionAction;
027: import java.security.PrivilegedActionException;
028:
029: /**
030: * @author Scott.Stark@jboss.org
031: * @author Ron Monzillo, Gary Ellison (javadoc)
032: * @version $Revision: 57196 $
033: */
034: public abstract class PolicyConfigurationFactory {
035: /** The standard name of the system property specifying the JACC
036: PolicyConfigurationFactory implementation class name.
037: */
038: private static final String FACTORY_PROP = "javax.security.jacc.PolicyConfigurationFactory.provider";
039: /** The default PolicyConfigurationFactory implementation */
040: private static final String DEFAULT_FACTORY_NAME = "org.jboss.security.jacc.JBossPolicyConfigurationFactory";
041: /** The loaded PolicyConfigurationFactory provider */
042: private static PolicyConfigurationFactory factory;
043:
044: /** This static method uses the javax.security.jacc.PolicyConfigurationFactory.provider
045: * system property to create a provider factory implementation. The provider
046: * class must provide a public no-arg ctor.
047: *
048: * @return the PolicyConfigurationFactory singleton
049: * @throws SecurityException - when the caller does not have a
050: * SecurityPermission(setPolicy) permission.
051: * @throws ClassNotFoundException - when the class named by the system
052: * property could not be found or because the value of the system
053: * property is null.
054: * @throws PolicyContextException - if the PolicyConfigurationFactory ctor
055: * throws an exception other than those in the getPolicyConfigurationFactory
056: * method signature. The exception will be encapsulated in a
057: * PolicyContextException as its cause.
058: */
059: public static PolicyConfigurationFactory getPolicyConfigurationFactory()
060: throws ClassNotFoundException, PolicyContextException {
061: // Validate the caller permission
062: SecurityManager sm = System.getSecurityManager();
063: if (sm != null)
064: sm.checkPermission(new SecurityPermission("setPolicy"));
065:
066: if (factory == null) {
067: String factoryName = null;
068: Class clazz = null;
069: try {
070: LoadAction action = new LoadAction();
071: try {
072: clazz = (Class) AccessController
073: .doPrivileged(action);
074: factoryName = action.getName();
075: } catch (PrivilegedActionException ex) {
076: factoryName = action.getName();
077: Exception e = ex.getException();
078: if (e instanceof ClassNotFoundException)
079: throw (ClassNotFoundException) e;
080: else
081: throw new PolicyContextException(
082: "Failure during load of class: "
083: + action.getName(), e);
084: }
085: factory = (PolicyConfigurationFactory) clazz
086: .newInstance();
087: } catch (ClassNotFoundException e) {
088: String msg = "Failed to find PolicyConfigurationFactory : "
089: + factoryName;
090: throw new ClassNotFoundException(msg, e);
091: } catch (IllegalAccessException e) {
092: String msg = "Unable to access class : " + factoryName;
093: throw new PolicyContextException(msg, e);
094: } catch (InstantiationException e) {
095: String msg = "Failed to create instance of: "
096: + factoryName;
097: throw new PolicyContextException(msg, e);
098: } catch (ClassCastException e) {
099: StringBuffer msg = new StringBuffer(factoryName
100: + " Is not a PolicyConfigurationFactory, ");
101: msg.append("PCF.class.CL: "
102: + PolicyConfigurationFactory.class
103: .getClassLoader());
104: msg.append("\nPCF.class.CS: "
105: + PolicyConfigurationFactory.class
106: .getProtectionDomain().getCodeSource());
107: msg
108: .append("\nPCF.class.hash: "
109: + System
110: .identityHashCode(PolicyConfigurationFactory.class));
111: msg.append("\nclazz.CL: " + clazz.getClassLoader());
112: msg.append("\nclazz.CS: "
113: + clazz.getProtectionDomain().getCodeSource());
114: msg.append("\nclazz.super.CL: "
115: + clazz.getSuperclass().getClassLoader());
116: msg.append("\nclazz.super.CS: "
117: + clazz.getSuperclass().getProtectionDomain()
118: .getCodeSource());
119: msg
120: .append("\nclazz.super.hash: "
121: + System.identityHashCode(clazz
122: .getSuperclass()));
123: ClassCastException cce = new ClassCastException(msg
124: .toString());
125: cce.initCause(e);
126: }
127: }
128: return factory;
129: }
130:
131: /** This method is used to obtain an instance of the provider specific class
132: * that implements the PolicyConfiguration interface that corresponds to the
133: * identified policy context within the provider. The methods of the
134: * PolicyConfiguration interface are used to define the policy statements of
135: * the identified policy context.
136: *
137: * If at the time of the call, the identified policy context does not exist
138: * in the provider, then the policy context will be created in the provider
139: * and the Object that implements the context's PolicyConfiguration Interface
140: * will be returned. If the state of the identified context is "deleted" or
141: * "inService" it will be transitioned to the "open" state as a result of the
142: * call. The states in the lifecycle of a policy context are defined by the
143: * PolicyConfiguration interface.
144: *
145: * For a given value of policy context identifier, this method must always
146: * return the same instance of PolicyConfiguration and there must be at most
147: * one actual instance of a PolicyConfiguration with a given policy context
148: * identifier (during a process context).
149: *
150: * To preserve the invariant that there be at most one PolicyConfiguration
151: * object for a given policy context, it may be necessary for this method to
152: * be thread safe.
153: *
154: * @param contextID - the policy context ID indicates which
155: * PolicyConfiguration to return. This must not be null.
156: * @param remove - A boolean flag that establishes whether or not the policy
157: * statements of an existing policy context are to be removed before its
158: * PolicyConfiguration object is returned. If the value passed to this
159: * parameter is true, the policy statements of an existing policy context
160: * will be removed. If the value is false, they will not be removed.
161: * @return a PolicyConfiguration instance
162: * @throws PolicyContextException
163: */
164: public abstract PolicyConfiguration getPolicyConfiguration(
165: String contextID, boolean remove)
166: throws PolicyContextException;
167:
168: /** This method determines if the identified policy context exists with state
169: * "inService" in the Policy provider associated with the factory.
170: *
171: * @param contextID - the context ID for selecting the policy
172: * @return true if the identified policy context exists within the provider
173: * and its state is "inService", false otherwise.
174: * @throws PolicyContextException
175: */
176: public abstract boolean inService(String contextID)
177: throws PolicyContextException;
178:
179: /** A PrivilegedExceptionAction that looks up the class name identified
180: * by the javax.security.jacc.PolicyConfigurationFactory.provider system
181: * property and loads the class using the thread context class loader.
182: */
183: private static class LoadAction implements
184: PrivilegedExceptionAction {
185: private String name;
186:
187: public String getName() {
188: return name;
189: }
190:
191: public Object run() throws Exception {
192: name = System.getProperty(FACTORY_PROP);
193: if (name == null) {
194: // Use the default factory impl
195: name = DEFAULT_FACTORY_NAME;
196: }
197: ClassLoader loader = Thread.currentThread()
198: .getContextClassLoader();
199: Class factoryClass = loader.loadClass(name);
200: return factoryClass;
201: }
202: }
203: }
|