diff --git a/api/src/main/java/jakarta/security/jacc/PolicyConfigurationFactory.java b/api/src/main/java/jakarta/security/jacc/PolicyConfigurationFactory.java index 07f89e5..9e87289 100755 --- a/api/src/main/java/jakarta/security/jacc/PolicyConfigurationFactory.java +++ b/api/src/main/java/jakarta/security/jacc/PolicyConfigurationFactory.java @@ -26,8 +26,8 @@ * Provider. * *
- * Implementation classes must have a public no argument constructor that may be used to create an operational instance - * of the factory implementation class. + * Usage: extend this class and push the implementation being wrapped to the constructor and use {@link #getWrapped} to + * access the instance being wrapped. * * @see Permission * @see PolicyConfiguration @@ -43,6 +43,8 @@ public abstract class PolicyConfigurationFactory { private static volatile PolicyConfigurationFactory policyConfigurationFactory; + private PolicyConfigurationFactory wrapped; + /** * This static method uses a system property to find and instantiate (via a public constructor) a provider specific * factory implementation class. @@ -148,6 +150,30 @@ public static PolicyConfigurationFactory get() { } } + /** + * Default constructor for if no wrapping is needed + */ + public PolicyConfigurationFactory() { + } + + /** + * If this factory has been decorated, the implementation doing the decorating should push the implementation being + * wrapped to this constructor. The {@link #getWrapped()} will then return the implementation being wrapped. + * + * @param wrapped The implementation being wrapped. + */ + public PolicyConfigurationFactory(PolicyConfigurationFactory wrapped) { + this.wrapped = wrapped; + } + + /** + * If this factory has been decorated, the implementation doing the decorating may override this method to provide + * access to the implementation being wrapped. + */ + public PolicyConfigurationFactory getWrapped() { + return wrapped; + } + /** * This method is used to obtain an instance of the provider specific class that implements the PolicyConfiguration * interface that corresponds to the identified policy context within the provider. The methods of the diff --git a/api/src/main/java/jakarta/security/jacc/PolicyFactory.java b/api/src/main/java/jakarta/security/jacc/PolicyFactory.java index e3e04e0..9183a93 100644 --- a/api/src/main/java/jakarta/security/jacc/PolicyFactory.java +++ b/api/src/main/java/jakarta/security/jacc/PolicyFactory.java @@ -32,6 +32,8 @@ public abstract class PolicyFactory { private static volatile PolicyFactory policyFactory; + private PolicyFactory wrapped; + /** * Get the system-wide PolicyFactory implementation. * @@ -87,6 +89,30 @@ public static synchronized void setPolicyFactory(PolicyFactory policyFactory) { PolicyFactory.policyFactory = policyFactory; } + /** + * Default constructor for if no wrapping is needed + */ + public PolicyFactory() { + } + + /** + * If this factory has been decorated, the implementation doing the decorating should push the implementation being + * wrapped to this constructor. The {@link #getWrapped()} will then return the implementation being wrapped. + * + * @param wrapped The implementation being wrapped. + */ + public PolicyFactory(PolicyFactory wrapped) { + this.wrapped = wrapped; + } + + /** + * If this factory has been decorated, the implementation doing the decorating may override this method to provide + * access to the implementation being wrapped. + */ + public PolicyFactory getWrapped() { + return wrapped; + } + /** * This method is used to obtain an instance of the provider specific class that implements the {@link Policy} * interface that corresponds to policy context within the provider. The policy context is identified by diff --git a/spec/src/main/asciidoc/chapters/2_provider-configuration.adoc b/spec/src/main/asciidoc/chapters/2_provider-configuration.adoc index 3a3eacc..8873a96 100644 --- a/spec/src/main/asciidoc/chapters/2_provider-configuration.adoc +++ b/spec/src/main/asciidoc/chapters/2_provider-configuration.adoc @@ -28,10 +28,14 @@ although for most common uses this should not be needed. Replacement is done via the `jakarta.security.jacc.PolicyConfigurationFactory` abstract factory class. A default static method, `getPolicyConfigurationFactory` is provided that uses the system property `jakarta.security.jacc.PolicyConfigurationFactory.provider` to locate a concrete implementation. The -application server can alternatively set a custom `PolicyConfigurationFactory` using the +container can alternatively set a custom `PolicyConfigurationFactory` using the `setPolicyConfigurationFactory` method. In that case the `PolicyConfigurationFactory` implementation -can come from an application server specific configuration, or in case of the Servlet Container -from the context property `jakarta.security.jacc.PolicyConfigurationFactory.provider`. +can come from a container specific configuration, or in case of the Servlet Container +from the context property `jakarta.security.jacc.PolicyConfigurationFactory.provider`. If the +`PolicyConfigurationFactory` has a public constructor with one argument of type `PolicyConfigurationFactory`, +then the container should call this constructor with as argument the `PolicyConfigurationFactory` instance +that is being replaced. This allows a replacement `PolicyConfigurationFactory` to wrap the existing one +and selectively provide extra functionality. From this factory class a concrete implementation of the Policy Configuration of type `jakarta.security.jacc.PolicyConfiguration` can be obtained using the method `getPolicyConfiguration`. diff --git a/tck/app-custom-trace-policyconfiguration/src/main/java/ee/jakarta/tck/authorization/test/TSPolicyConfigurationFactoryImpl.java b/tck/app-custom-trace-policyconfiguration/src/main/java/ee/jakarta/tck/authorization/test/TSPolicyConfigurationFactoryImpl.java index 792ec27..b25697b 100644 --- a/tck/app-custom-trace-policyconfiguration/src/main/java/ee/jakarta/tck/authorization/test/TSPolicyConfigurationFactoryImpl.java +++ b/tck/app-custom-trace-policyconfiguration/src/main/java/ee/jakarta/tck/authorization/test/TSPolicyConfigurationFactoryImpl.java @@ -26,7 +26,6 @@ import static java.util.logging.Level.FINER; import static java.util.logging.Level.INFO; -import static java.util.logging.Level.SEVERE; import ee.jakarta.tck.authorization.util.logging.server.TSLogger; import jakarta.security.jacc.PolicyConfiguration; @@ -45,17 +44,12 @@ public class TSPolicyConfigurationFactoryImpl extends PolicyConfigurationFactory private static String FACTORY_NAME = "vendor.jakarta.security.jacc.PolicyConfigurationFactory.provider"; - private static PolicyConfigurationFactory policyConfigurationFactory; - public TSPolicyConfigurationFactoryImpl() throws PolicyContextException { - try { - policyConfigurationFactory = TSPolicyConfigurationFactoryImpl.getPolicyConfigurationFactory(); - } catch (PolicyContextException pce) { - if (logger != null) { - logger.severe("Failed to get PolicyConfigurationFactory"); - } - - throw new PolicyContextException(pce); + public TSPolicyConfigurationFactoryImpl(PolicyConfigurationFactory policyConfigurationFactory) { + super(policyConfigurationFactory); + logger.log(INFO, "PolicyConfigurationFactory instantiated"); + if (policyConfigurationFactory.getClass().getName().equals(FACTORY_NAME)) { + logger.log(INFO, "policyConfigurationFactory equals expected vendor PolicyConfigurationFactory"); } } @@ -109,55 +103,6 @@ public PolicyConfiguration getPolicyConfiguration(String contextId, boolean remo return policyConfiguration; } - /** - * This static method uses a system property to find and instantiate (via a public constructor) a provider specific - * factory implementation class. The name of the provider specific factory implementation class is obtained from the - * value of the system property, - *
- *
- *
- * vendor.jakarta.security.jacc.PolicyConfigurationFactory.provider
- *
- *
- * @return the singleton instance of the provider specific PolicyConfigurationFactory implementation class.
- *
- * @throws SecurityException when called by an AccessControlContext that has not been granted the "getPolicy"
- * SecurityPermission.
- *
- * @throws PolicyContextException when the class named by the system property could not be found including because the
- * value of the system property has not been set.
- */
-
- public static PolicyConfigurationFactory getPolicyConfigurationFactory() throws PolicyContextException {
- if (policyConfigurationFactory != null) {
- return policyConfigurationFactory;
- }
-
- String classname = System.getProperty(FACTORY_NAME);
- if (classname == null) {
- logger.severe("factory.name.notset");
- throw new PolicyContextException("PolicyConfigurationFactory name not set!");
- }
-
- try {
- policyConfigurationFactory = (PolicyConfigurationFactory)
- TSPolicyConfigurationFactoryImpl.class
- .getClassLoader()
- .loadClass(classname)
- .getDeclaredConstructor()
- .newInstance();
-
- if (policyConfigurationFactory != null) {
- logger.log(INFO, "PolicyConfigurationFactory instantiated");
- }
- } catch (Exception e) {
- logger.log(SEVERE, "factory.instantiation.error", e);
- throw new PolicyContextException(e);
- }
-
- return policyConfigurationFactory;
- }
-
/**
* This method determines if the identified policy context exists with state "inService" in the Policy provider
* associated with the factory.
@@ -182,7 +127,7 @@ public boolean inService(String contextId) throws PolicyContextException {
logger.log(INFO, "PolicyConfigurationFactory.inService() invoked");
logger.log(FINER, "PolicyConfiguration.inService() invoked for context id = " + contextId);
- return policyConfigurationFactory.inService(contextId);
+ return getWrapped().inService(contextId);
}
public PolicyConfiguration getPolicyConfiguration(String contextID) {
@@ -190,7 +135,7 @@ public PolicyConfiguration getPolicyConfiguration(String contextID) {
logger.entering("PolicyConfigurationFactoryImpl", "getPolicyConfiguration(String)");
}
- PolicyConfiguration policyConfiguration = policyConfigurationFactory.getPolicyConfiguration(contextID);
+ PolicyConfiguration policyConfiguration = getWrapped().getPolicyConfiguration(contextID);
logger.log(INFO, "PolicyConfigurationFactory.getPolicyConfiguration(String) invoked");
return policyConfiguration;
@@ -202,7 +147,7 @@ public PolicyConfiguration getPolicyConfiguration() {
}
String contextId = PolicyContext.getContextID();
- PolicyConfiguration policyConfiguration = policyConfigurationFactory.getPolicyConfiguration(contextId);
+ PolicyConfiguration policyConfiguration = getWrapped().getPolicyConfiguration(contextId);
logger.log(INFO, "PolicyConfigurationFactory.getPolicyConfiguration(String) invoked");
logger.log(FINER, "Getting PolicyConfiguration object with id = " + contextId);
diff --git a/tck/app-custom-trace-policyconfiguration/src/main/java/ee/jakarta/tck/authorization/test/TSPolicyConfigurationImpl.java b/tck/app-custom-trace-policyconfiguration/src/main/java/ee/jakarta/tck/authorization/test/TSPolicyConfigurationImpl.java
index a6b7428..cd01bc6 100644
--- a/tck/app-custom-trace-policyconfiguration/src/main/java/ee/jakarta/tck/authorization/test/TSPolicyConfigurationImpl.java
+++ b/tck/app-custom-trace-policyconfiguration/src/main/java/ee/jakarta/tck/authorization/test/TSPolicyConfigurationImpl.java
@@ -50,8 +50,8 @@
public class TSPolicyConfigurationImpl implements PolicyConfiguration {
private static TSLogger logger;
- private PolicyConfigurationFactory policyConfigurationFactory;
- private PolicyConfiguration policyConfiguration;
+ private PolicyConfigurationFactory vendorPolicyConfigurationFactory;
+ private PolicyConfiguration vendorPolicyConfiguration;
private String applicationContext;
private String appTime;
@@ -71,11 +71,11 @@ public TSPolicyConfigurationImpl(String contextId, boolean remove, TSLogger tsLo
}
// set vendor's PolicyConfigurationFactory
- policyConfigurationFactory = TSPolicyConfigurationFactoryImpl.getPolicyConfigurationFactory();
+ vendorPolicyConfigurationFactory = PolicyConfigurationFactory.get().getWrapped();
// **** This covers two assertions JACC:SPEC:33 and JACC:SPEC:56 ****
// set vendor's PolicyConfiguration
- policyConfiguration = policyConfigurationFactory.getPolicyConfiguration(contextId, remove);
+ vendorPolicyConfiguration = vendorPolicyConfigurationFactory.getPolicyConfiguration(contextId, remove);
// This(appId record) will be used as an identifier
// for isolating the logs associated with each test run.
@@ -101,9 +101,9 @@ public TSPolicyConfigurationImpl(String contextId, boolean remove, TSLogger tsLo
* encapsulated (during construction) in the thrown PolicyContextException.
*/
public String getContextID() throws PolicyContextException {
- boolean wasInService = policyConfiguration.inService();
+ boolean wasInService = vendorPolicyConfiguration.inService();
- String contextId = policyConfiguration.getContextID();
+ String contextId = vendorPolicyConfiguration.getContextID();
// If the state was inService for our getContextID call, then it must remain
// in that state as its next transitional state (per javadoc table)
@@ -111,7 +111,7 @@ public String getContextID() throws PolicyContextException {
assertIsInserviceState("getContextID");
} else {
// state was not inService so make sure it is still NOT in the
- // inService state after calling policyConfiguration.getContextID()
+ // inService state after calling vendorPolicyConfiguration.getContextID()
assertStateNotInservice("getContextID");
}
@@ -152,8 +152,8 @@ public void addToRole(String roleName, PermissionCollection permissions) throws
return;
}
- policyConfiguration = policyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
- policyConfiguration.addToRole(roleName, permissions);
+ vendorPolicyConfiguration = vendorPolicyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
+ vendorPolicyConfiguration.addToRole(roleName, permissions);
assertStateNotInservice("addToRole");
if (logger.isLoggable(INFO)) {
@@ -226,9 +226,9 @@ public void addToRole(String roleName, Permission permission) throws PolicyConte
if (roleName == null || permission == null)
return;
- policyConfiguration = policyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
+ vendorPolicyConfiguration = vendorPolicyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
- policyConfiguration.addToRole(roleName, permission);
+ vendorPolicyConfiguration.addToRole(roleName, permission);
assertStateNotInservice("addToRole");
// Get the permission type,
@@ -282,8 +282,8 @@ public void addToUncheckedPolicy(PermissionCollection permissions) throws Policy
return;
}
- policyConfiguration = policyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
- policyConfiguration.addToUncheckedPolicy(permissions);
+ vendorPolicyConfiguration = vendorPolicyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
+ vendorPolicyConfiguration.addToUncheckedPolicy(permissions);
assertStateNotInservice("addToUncheckedPolicy");
if (logger.isLoggable(INFO)) {
@@ -346,8 +346,8 @@ public void addToUncheckedPolicy(Permission permission) throws PolicyContextExce
return;
}
- policyConfiguration = policyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
- policyConfiguration.addToUncheckedPolicy(permission);
+ vendorPolicyConfiguration = vendorPolicyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
+ vendorPolicyConfiguration.addToUncheckedPolicy(permission);
assertStateNotInservice("addToUncheckedPolicy");
// Get the permission type,
@@ -391,8 +391,8 @@ public void addToExcludedPolicy(PermissionCollection permissions) throws PolicyC
if (permissions == null)
return;
- policyConfiguration = policyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
- policyConfiguration.addToExcludedPolicy(permissions);
+ vendorPolicyConfiguration = vendorPolicyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
+ vendorPolicyConfiguration.addToExcludedPolicy(permissions);
assertStateNotInservice("addToExcludedPolicy");
if (logger.isLoggable(INFO)) {
@@ -451,8 +451,8 @@ public void addToExcludedPolicy(Permission permission) throws PolicyContextExcep
return;
}
- policyConfiguration = policyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
- policyConfiguration.addToExcludedPolicy(permission);
+ vendorPolicyConfiguration = vendorPolicyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
+ vendorPolicyConfiguration.addToExcludedPolicy(permission);
assertStateNotInservice("addToExcludedPolicy");
// Get the permission type,
@@ -496,8 +496,8 @@ public void removeRole(String roleName) throws PolicyContextException {
return;
}
- policyConfiguration = policyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
- policyConfiguration.removeRole(roleName);
+ vendorPolicyConfiguration = vendorPolicyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
+ vendorPolicyConfiguration.removeRole(roleName);
assertStateNotInservice("removeRole");
if (logger.isLoggable(INFO)) {
@@ -526,8 +526,8 @@ public void removeUncheckedPolicy() throws PolicyContextException {
logger.entering("TSPolicyConfigurationImpl", "removeUncheckedPolicy");
}
- policyConfiguration = policyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
- policyConfiguration.removeUncheckedPolicy();
+ vendorPolicyConfiguration = vendorPolicyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
+ vendorPolicyConfiguration.removeUncheckedPolicy();
assertStateNotInservice("removeUncheckedPolicy");
if (logger.isLoggable(INFO)) {
@@ -556,8 +556,8 @@ public void removeExcludedPolicy() throws PolicyContextException {
logger.entering("TSPolicyConfigurationImpl", "removeExcludedPolicy");
}
- policyConfiguration = policyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
- policyConfiguration.removeExcludedPolicy();
+ vendorPolicyConfiguration = vendorPolicyConfigurationFactory.getPolicyConfiguration(applicationContext, false);
+ vendorPolicyConfiguration.removeExcludedPolicy();
assertStateNotInservice("removeExcludedPolicy");
if (logger.isLoggable(INFO)) {
@@ -593,8 +593,8 @@ public void commit() throws PolicyContextException {
logger.entering("TSPolicyConfigurationImpl", "commit");
}
- policyConfiguration.inService();
- policyConfiguration.commit();
+ vendorPolicyConfiguration.inService();
+ vendorPolicyConfiguration.commit();
assertIsInserviceState("commit");
@@ -673,7 +673,7 @@ public void linkConfiguration(PolicyConfiguration link) throws PolicyContextExce
}
}
- // policyConfiguration.linkConfiguration(link);
+ // vendorPolicyConfiguration.linkConfiguration(link);
//
// Note:
// The Passed varibale "link" may be an instance of
@@ -686,12 +686,12 @@ public void linkConfiguration(PolicyConfiguration link) throws PolicyContextExce
// get vendor's Policy configuration from "link"
// Note: pcf is vendor's PolicyConfigurationFactory
- PolicyConfiguration vendorPC = policyConfigurationFactory.getPolicyConfiguration(vendorContextId, false);
+ PolicyConfiguration vendorPC = vendorPolicyConfigurationFactory.getPolicyConfiguration(vendorContextId, false);
// Now link the vendor's PolicyConfiguration
- policyConfiguration.inService();
- policyConfiguration.linkConfiguration(vendorPC);
+ vendorPolicyConfiguration.inService();
+ vendorPolicyConfiguration.linkConfiguration(vendorPC);
assertStateNotInservice("linkConfiguration");
@@ -720,7 +720,7 @@ public void delete() throws PolicyContextException {
logger.entering("TSPolicyConfigurationImpl", "delete");
}
- policyConfiguration.delete();
+ vendorPolicyConfiguration.delete();
assertStateNotInservice("delete");
if (logger.isLoggable(INFO)) {
@@ -749,11 +749,11 @@ public boolean inService() throws PolicyContextException {
logger.entering("TSPolicyConfigurationImpl", "inService");
}
- boolean wasInservice = policyConfiguration.inService();
+ boolean wasInservice = vendorPolicyConfiguration.inService();
- boolean ret = policyConfiguration.inService();
+ boolean ret = vendorPolicyConfiguration.inService();
- // If the state was inService befor our policyConfiguration.inService()
+ // If the state was inService befor our vendorPolicyConfiguration.inService()
// call, then it must remain in that state as its next transitional
// state (per javadoc table)
if (wasInservice) {
@@ -814,20 +814,20 @@ public static String stuffData(String inputStr) {
}
public PermissionCollection getExcludedPermissions() {
- return policyConfiguration.getExcludedPermissions();
+ return vendorPolicyConfiguration.getExcludedPermissions();
}
public PermissionCollection getUncheckedPermissions() {
- return policyConfiguration.getUncheckedPermissions();
+ return vendorPolicyConfiguration.getUncheckedPermissions();
}
public Map