1409 lines
45 KiB
Java
1409 lines
45 KiB
Java
|
|
/*
|
|
* @(#)ConfigurationStore.java
|
|
*
|
|
* Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistribution of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistribution in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
|
|
* be used to endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
*
|
|
* This software is provided "AS IS," without a warranty of any kind. ALL
|
|
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
|
|
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
|
|
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
|
|
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
|
|
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
|
|
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
|
|
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
|
|
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
|
|
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
|
|
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
*
|
|
* You acknowledge that this software is not designed or intended for use in
|
|
* the design, construction, operation or maintenance of any nuclear facility.
|
|
*/
|
|
|
|
package com.sun.xacml;
|
|
|
|
import com.sun.xacml.attr.AttributeDesignator;
|
|
import com.sun.xacml.attr.AttributeFactory;
|
|
import com.sun.xacml.attr.AttributeFactoryProxy;
|
|
import com.sun.xacml.attr.AttributeProxy;
|
|
import com.sun.xacml.attr.BaseAttributeFactory;
|
|
import com.sun.xacml.attr.StandardAttributeFactory;
|
|
|
|
import com.sun.xacml.combine.BaseCombiningAlgFactory;
|
|
import com.sun.xacml.combine.CombiningAlgFactory;
|
|
import com.sun.xacml.combine.CombiningAlgFactoryProxy;
|
|
import com.sun.xacml.combine.CombiningAlgorithm;
|
|
import com.sun.xacml.combine.StandardCombiningAlgFactory;
|
|
|
|
import com.sun.xacml.cond.BaseFunctionFactory;
|
|
import com.sun.xacml.cond.BasicFunctionFactoryProxy;
|
|
import com.sun.xacml.cond.Function;
|
|
import com.sun.xacml.cond.FunctionProxy;
|
|
import com.sun.xacml.cond.FunctionFactory;
|
|
import com.sun.xacml.cond.FunctionFactoryProxy;
|
|
import com.sun.xacml.cond.StandardFunctionFactory;
|
|
|
|
import com.sun.xacml.cond.cluster.FunctionCluster;
|
|
|
|
import com.sun.xacml.finder.AttributeFinder;
|
|
import com.sun.xacml.finder.AttributeFinderModule;
|
|
import com.sun.xacml.finder.PolicyFinder;
|
|
import com.sun.xacml.finder.PolicyFinderModule;
|
|
import com.sun.xacml.finder.RequiredAttributesModule;
|
|
import com.sun.xacml.finder.ResourceFinder;
|
|
import com.sun.xacml.finder.ResourceFinderModule;
|
|
import com.sun.xacml.finder.RevocationFinder;
|
|
import com.sun.xacml.finder.RevocationFinderModule;
|
|
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
|
|
import java.lang.reflect.Constructor;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.lang.reflect.Method;
|
|
|
|
import java.net.URI;
|
|
import java.net.URISyntaxException;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
import org.apache.log4j.Logger;
|
|
|
|
import javax.xml.parsers.DocumentBuilder;
|
|
import javax.xml.parsers.DocumentBuilderFactory;
|
|
import javax.xml.parsers.ParserConfigurationException;
|
|
|
|
import org.xml.sax.SAXException;
|
|
|
|
import org.w3c.dom.Document;
|
|
import org.w3c.dom.Element;
|
|
import org.w3c.dom.NamedNodeMap;
|
|
import org.w3c.dom.Node;
|
|
import org.w3c.dom.NodeList;
|
|
|
|
|
|
/**
|
|
* This class supports run-time loading of configuration data. It loads the
|
|
* configurations from an XML file that conforms to the configuration schema.
|
|
* By design this class does not get used automatically, nor does it change
|
|
* the state of the system directly. A programmer must choose to support this
|
|
* mechanism in their program, and then must explicitly use loaded elements.
|
|
* This way, the programmer still has full control over their security model,
|
|
* but also has the convenience of re-using a common configuration
|
|
* mechanism. See http://sunxacml.sourceforge.net/schema/config-0.4.xsd for
|
|
* the valid schema.
|
|
* <p>
|
|
* Note that becuase this doesn't tie directly into the rest of the code, you
|
|
* are still free to design your own run-time configuration mechanisms. This
|
|
* is simply provided as a convenience, and so that all programmers can start
|
|
* from a common point.
|
|
*
|
|
* @since 1.2
|
|
* @author Seth Proctor
|
|
*/
|
|
public class ConfigurationStore
|
|
{
|
|
|
|
/**
|
|
* Property used to specify the configuration file.
|
|
*/
|
|
public static final String PDP_CONFIG_PROPERTY =
|
|
"com.sun.xacml.PDPConfigFile";
|
|
|
|
// pdp elements
|
|
private PDPConfig defaultPDPConfig;
|
|
private HashMap<String, PDPConfig> pdpConfigMap;
|
|
|
|
// attribute factory elements
|
|
private AttributeFactory defaultAttributeFactory;
|
|
private HashMap<String, AttributeFactory> attributeMap;
|
|
|
|
// combining algorithm factory elements
|
|
private CombiningAlgFactory defaultCombiningFactory;
|
|
private HashMap<String, CombiningAlgFactory> combiningMap;
|
|
|
|
// function factory elements
|
|
private FunctionFactoryProxy defaultFunctionFactoryProxy;
|
|
private HashMap<String, FunctionFactoryProxy> functionMap;
|
|
|
|
private Map<String, Object> customAttr = new HashMap<String, Object>();
|
|
|
|
// the classloader we'll use for loading classes
|
|
private ClassLoader loader;
|
|
|
|
// // directory as base, where all files are searched
|
|
// @Deprecated
|
|
// private static String static_baseDir;
|
|
//
|
|
private String baseDir;
|
|
|
|
public static final String BASEDIR = "BASEDIR";
|
|
|
|
// the logger we'll use for all messages
|
|
private static final Logger logger =
|
|
Logger.getLogger(ConfigurationStore.class.getName());
|
|
|
|
/**
|
|
* Default constructor. This constructor uses the
|
|
* <code>PDP_CONFIG_PROPERTY</code> property to load the configuration.
|
|
* If the property isn't set, if it names a file that can't be accessed,
|
|
* or if the file is invalid, then an exception is thrown.
|
|
*
|
|
* @throws ParsingException if anything goes wrong during the parsing
|
|
* of the configuration file, the class loading,
|
|
* or the factory and pdp setup
|
|
*/
|
|
public ConfigurationStore() throws ParsingException {
|
|
String configFile = System.getProperty(PDP_CONFIG_PROPERTY);
|
|
|
|
// make sure that the right property was set
|
|
if (configFile == null) {
|
|
logger.warn("A property defining a config file was expected, " +
|
|
"but none was provided");
|
|
|
|
throw new ParsingException("Config property " +
|
|
PDP_CONFIG_PROPERTY +
|
|
" needs to be set");
|
|
}
|
|
|
|
try {
|
|
//setupConfig(new File(static_baseDir + configFile));
|
|
setupConfig(new File(configFile));
|
|
} catch (ParsingException pe) {
|
|
logger.error("Runtime config file (" + configFile + ") couldn't be loaded" +
|
|
" so no configurations will be available", pe);
|
|
throw pe;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Constructor that explicitly specifies the configuration file to load.
|
|
* This is useful if your security model doesn't allow the use of
|
|
* properties, if you don't want to use a property to specify a
|
|
* configuration file, or if you want to use more then one configuration
|
|
* file. If the file can't be accessed, or if the file is invalid, then
|
|
* an exception is thrown.
|
|
*
|
|
* @param configFile The configuration file.
|
|
*
|
|
* @throws ParsingException if anything goes wrong during the parsing
|
|
* of the configuration file, the class loading,
|
|
* or the factory and pdp setup
|
|
*/
|
|
public ConfigurationStore(File configFile) throws ParsingException {
|
|
// if there is no baseDir, it is assumed that the rest of the
|
|
//configuration files are stored in the same directory as the confFile
|
|
// if there is no file.separator, baseDir is set to ""
|
|
String absPath = configFile.getAbsolutePath();
|
|
String baseDir = absPath.substring(0,
|
|
absPath.lastIndexOf(System.getProperty("file.separator")) + 1 );
|
|
init(configFile, baseDir);
|
|
}
|
|
|
|
|
|
/**
|
|
* Constructor that explicitly specifies the configuration file to load.
|
|
* This is useful if your security model doesn't allow the use of
|
|
* properties, if you don't want to use a property to specify a
|
|
* configuration file, or if you want to use more then one configuration
|
|
* file. If the file can't be accessed, or if the file is invalid, then
|
|
* an exception is thrown.
|
|
*
|
|
* @param configFile The configuration file.
|
|
*
|
|
* @throws ParsingException if anything goes wrong during the parsing
|
|
* of the configuration file, the class loading,
|
|
* or the factory and pdp setup
|
|
*/
|
|
public ConfigurationStore(File configFile, String baseDir) throws ParsingException {
|
|
init(configFile, baseDir);
|
|
}
|
|
|
|
public ConfigurationStore(InputStream configFile, String baseDir) throws ParsingException {
|
|
init(configFile, baseDir);
|
|
}
|
|
|
|
public ConfigurationStore(String configuration, Map<String, Object> customAttrs) throws ParsingException {
|
|
this.customAttr = customAttrs;
|
|
if ( customAttrs.containsKey(BASEDIR)) {
|
|
this.baseDir = (String) customAttrs.get(BASEDIR);
|
|
}
|
|
init(configuration);
|
|
}
|
|
|
|
private void init(File configFile, String baseDir) throws ParsingException {
|
|
setBaseDir(baseDir);
|
|
try {
|
|
setupConfig(configFile);
|
|
} catch (ParsingException pe) {
|
|
logger.warn("Runtime config file (" + configFile + ")couldn't be loaded" +
|
|
" so no configurations will be available", pe);
|
|
throw pe;
|
|
}
|
|
}
|
|
|
|
private void init(InputStream configFile, String baseDir) throws ParsingException {
|
|
setBaseDir(baseDir);
|
|
try {
|
|
setupConfig(configFile);
|
|
} catch (ParsingException pe) {
|
|
logger.warn("Runtime config file (" + configFile + ")couldn't be loaded" +
|
|
" so no configurations will be available", pe);
|
|
throw pe;
|
|
}
|
|
}
|
|
|
|
protected void init(String configuration) throws ParsingException {
|
|
setBaseDir("");
|
|
try {
|
|
setupConfig(configuration);
|
|
} catch (ParsingException pe) {
|
|
logger.warn("Runtime configuration couldn't be loaded" +
|
|
" so no configurations will be available (" + pe.getMessage() + ")", pe);
|
|
throw pe;
|
|
}
|
|
}
|
|
|
|
private void setBaseDir(String baseDir) {
|
|
if ( baseDir == null ) {
|
|
baseDir = "";
|
|
}
|
|
this.baseDir = baseDir;
|
|
customAttr.put(BASEDIR, baseDir);
|
|
}
|
|
|
|
private void setupConfig(String configuration) throws ParsingException {
|
|
setupConfig(getRootNode(configuration));
|
|
}
|
|
|
|
private void setupConfig(InputStream configuration) throws ParsingException {
|
|
setupConfig(getRootNode(configuration));
|
|
}
|
|
|
|
private void setupConfig(File configFile) throws ParsingException {
|
|
setupConfig(getRootNode(configFile));
|
|
}
|
|
|
|
/**
|
|
* Private helper function used by both constructors to actually load the
|
|
* configuration data. This is the root of several private methods used
|
|
* to setup all the pdps and factories.
|
|
*
|
|
* @param configFile The configuration file.
|
|
*
|
|
* @throws ParsingException
|
|
*/
|
|
//private void setupConfig(File configFile) throws ParsingException {
|
|
private void setupConfig(Node root) throws ParsingException {
|
|
logger.info("Loading runtime configuration");
|
|
|
|
// load our classloader
|
|
this.loader = getClass().getClassLoader();
|
|
|
|
// get the root node from the configuration file
|
|
//Node root = getRootNode(configFile);
|
|
|
|
// initialize all the maps
|
|
this.pdpConfigMap = new HashMap<String, PDPConfig>();
|
|
this.attributeMap = new HashMap<String, AttributeFactory>();
|
|
this.combiningMap = new HashMap<String, CombiningAlgFactory>();
|
|
this.functionMap = new HashMap<String, FunctionFactoryProxy>();
|
|
if ( customAttr == null ) {
|
|
this.customAttr = new HashMap<String, Object>();
|
|
}
|
|
|
|
// get the default names
|
|
NamedNodeMap attrs = root.getAttributes();
|
|
String defaultPDP = attrs.getNamedItem("defaultPDP").getNodeValue();
|
|
String defaultAF = getDefaultFactory(attrs, "defaultAttributeFactory");
|
|
String defaultCAF = getDefaultFactory(attrs,
|
|
"defaultCombiningAlgFactory");
|
|
String defaultFF = getDefaultFactory(attrs, "defaultFunctionFactory");
|
|
|
|
// loop through all the root-level elements, for each one getting its
|
|
// name and then loading the right kind of element
|
|
NodeList children = root.getChildNodes();
|
|
for (int i = 0; i < children.getLength(); i++) {
|
|
Node child = children.item(i);
|
|
String childName = child.getNodeName();
|
|
String elementName = null;
|
|
|
|
// get the element's name
|
|
if (child.getNodeType() == Node.ELEMENT_NODE &&
|
|
child.getAttributes().getNamedItem("name") != null ) {
|
|
elementName = child.getAttributes().
|
|
getNamedItem("name").getNodeValue();
|
|
}
|
|
|
|
// see if this is a pdp or a factory, and load accordingly,
|
|
// putting the new element into the respective map...make sure
|
|
// that we're never loading something with the same name twice
|
|
if (childName.equals("pdp")) {
|
|
if (logger.isDebugEnabled()) {
|
|
logger.debug("Loading PDP: " + elementName);
|
|
}
|
|
if (this.pdpConfigMap.containsKey(elementName)) {
|
|
throw new ParsingException("more that one pdp with " +
|
|
"name \"" + elementName +"\"");
|
|
}
|
|
this.pdpConfigMap.put(elementName, parsePDPConfig(child));
|
|
} else if (childName.equals("attributeFactory")) {
|
|
if (logger.isDebugEnabled()) {
|
|
logger.debug("Loading AttributeFactory: " + elementName);
|
|
}
|
|
if (this.attributeMap.containsKey(elementName)) {
|
|
throw new ParsingException("more that one " +
|
|
"attributeFactory with name " +
|
|
elementName +"\"");
|
|
}
|
|
this.attributeMap.put(elementName,
|
|
parseAttributeFactory(child));
|
|
} else if (childName.equals("combiningAlgFactory")) {
|
|
if (logger.isDebugEnabled()) {
|
|
logger.debug("Loading CombiningAlgFactory: " +
|
|
elementName);
|
|
}
|
|
if (this.combiningMap.containsKey(elementName)) {
|
|
throw new ParsingException("more that one " +
|
|
"combiningAlgFactory with " +
|
|
"name \"" + elementName +"\"");
|
|
}
|
|
this.combiningMap.put(elementName,
|
|
parseCombiningAlgFactory(child));
|
|
} else if (childName.equals("functionFactory")) {
|
|
if (logger.isDebugEnabled()) {
|
|
logger.debug("Loading FunctionFactory: " + elementName);
|
|
}
|
|
if (this.functionMap.containsKey(elementName)) {
|
|
throw new ParsingException("more that one functionFactory"
|
|
+ " with name \"" +
|
|
elementName +"\"");
|
|
}
|
|
this.functionMap.put(elementName, parseFunctionFactory(child));
|
|
} else {
|
|
//custom attribtue
|
|
if ( child.getNodeType() == Node.ELEMENT_NODE ) {
|
|
String key = null, value = null;
|
|
if ( child.getFirstChild() != null ) {
|
|
key = childName;
|
|
if ( child.getFirstChild().getNodeType() == Node.TEXT_NODE ) {
|
|
value = child.getFirstChild().getNodeValue().trim();
|
|
}
|
|
} else {
|
|
NamedNodeMap foo = child.getAttributes();
|
|
if (foo != null ) {
|
|
key = foo.getNamedItem("key").getNodeValue();
|
|
value = foo.getNamedItem("value").getNodeValue();
|
|
}
|
|
}
|
|
if ( key != null && value != null ) {
|
|
if (logger.isDebugEnabled()) {
|
|
logger.debug("Read custom attribute " + key + " with value " + value);
|
|
}
|
|
customAttr.put(key, value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// copy custom attributes to PDP configs
|
|
if ( customAttr.size() > 0 ) {
|
|
for (String pdpKey : this.pdpConfigMap.keySet()) {
|
|
pdpConfigMap.get(pdpKey).addCutomAttrs(customAttr);
|
|
}
|
|
}
|
|
|
|
// finally, extract the default elements
|
|
this.defaultPDPConfig = (PDPConfig)(this.pdpConfigMap.get(defaultPDP));
|
|
|
|
this.defaultAttributeFactory = (AttributeFactory)
|
|
(this.attributeMap.get(defaultAF));
|
|
if (this.defaultAttributeFactory == null) {
|
|
try {
|
|
this.defaultAttributeFactory =
|
|
AttributeFactory.getInstance(defaultAF);
|
|
} catch (Exception e) {
|
|
throw new ParsingException("Unknown AttributeFactory", e);
|
|
}
|
|
}
|
|
/* start hack: required to include datatypes configured in pdp configuration */
|
|
AttributeFactoryProxy attrProxy = new AttributeFactoryProxy() {
|
|
public AttributeFactory getFactory() {
|
|
return defaultAttributeFactory;
|
|
}
|
|
};
|
|
BaseAttributeFactory.setDefaultFactory(attrProxy);
|
|
/* end hack */
|
|
|
|
this.defaultCombiningFactory = (CombiningAlgFactory)
|
|
(this.combiningMap.get(defaultCAF));
|
|
if (this.defaultCombiningFactory == null) {
|
|
try {
|
|
this.defaultCombiningFactory =
|
|
CombiningAlgFactory.getInstance(defaultCAF);
|
|
} catch (Exception e) {
|
|
throw new ParsingException("Unknown CombininAlgFactory", e);
|
|
}
|
|
}
|
|
|
|
this.defaultFunctionFactoryProxy = (FunctionFactoryProxy)
|
|
(this.functionMap.get(defaultFF));
|
|
if (this.defaultFunctionFactoryProxy == null) {
|
|
try {
|
|
this.defaultFunctionFactoryProxy =
|
|
FunctionFactory.getInstance(defaultFF);
|
|
} catch (Exception e) {
|
|
throw new ParsingException("Unknown FunctionFactory", e);
|
|
}
|
|
}
|
|
/* start hack: required to include functions configured in pdp configuration */
|
|
BaseFunctionFactory.setDefaultFactory(defaultFunctionFactoryProxy);
|
|
/* end hack */
|
|
}
|
|
|
|
/**
|
|
* Private helper that gets a default factory identifier, or fills in
|
|
* the default value if no identifier is provided.
|
|
*
|
|
* @param attrs The XML-attributes of the configuration.
|
|
* @param factoryName The name of the default factory XML-attribute.
|
|
*
|
|
* @return The identifier of the default factory.
|
|
*/
|
|
private String getDefaultFactory(NamedNodeMap attrs, String factoryName) {
|
|
Node node = attrs.getNamedItem(factoryName);
|
|
if (node != null) {
|
|
return node.getNodeValue();
|
|
}
|
|
return Constants.XACML_1_0_IDENTIFIER;
|
|
}
|
|
|
|
private Node getRootNode(File configFile) throws ParsingException {
|
|
try {
|
|
return getRootNode(new FileInputStream(configFile));
|
|
} catch(IOException ioe) {
|
|
throw new ParsingException("failed to load the file ", ioe);
|
|
}
|
|
}
|
|
|
|
private Node getRootNode(InputStream configFile) throws ParsingException {
|
|
DocumentBuilder db = createDocumentBuilder();
|
|
|
|
Document doc = null;
|
|
try {
|
|
doc = db.parse(configFile);
|
|
} catch (IOException ioe) {
|
|
throw new ParsingException("failed to load the file ", ioe);
|
|
} catch (SAXException saxe) {
|
|
throw new ParsingException("error parsing the XML tree", saxe);
|
|
} catch (IllegalArgumentException iae) {
|
|
throw new ParsingException("no data to parse", iae);
|
|
}
|
|
|
|
return getRootNode(doc);
|
|
}
|
|
|
|
private Node getRootNode(String configuration) throws ParsingException {
|
|
DocumentBuilder db = createDocumentBuilder();
|
|
|
|
Document doc = null;
|
|
try {
|
|
doc = db.parse(new ByteArrayInputStream(configuration.getBytes()));
|
|
} catch (IOException ioe) {
|
|
throw new ParsingException("failed to load the configuration from string ", ioe);
|
|
} catch (SAXException saxe) {
|
|
throw new ParsingException("error parsing the XML tree", saxe);
|
|
} catch (IllegalArgumentException iae) {
|
|
throw new ParsingException("no data to parse", iae);
|
|
}
|
|
|
|
return getRootNode(doc);
|
|
}
|
|
|
|
private DocumentBuilder createDocumentBuilder() throws ParsingException {
|
|
DocumentBuilderFactory dbFactory =
|
|
DocumentBuilderFactory.newInstance();
|
|
|
|
dbFactory.setIgnoringComments(true);
|
|
dbFactory.setNamespaceAware(false);
|
|
dbFactory.setValidating(false);
|
|
|
|
try {
|
|
return dbFactory.newDocumentBuilder();
|
|
} catch (ParserConfigurationException pce) {
|
|
throw new ParsingException("couldn't get a document builder", pce);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Private helper that parses the file and sets up the DOM tree.
|
|
*
|
|
* @param configFile The filename of the configuration file.
|
|
*
|
|
* @return The DOM-tree containing the configuration.
|
|
*
|
|
* @throws ParsingException
|
|
*/
|
|
//private Node getRootNode(File configFile) throws ParsingException {
|
|
private Node getRootNode(Document doc) throws ParsingException {
|
|
// DocumentBuilderFactory dbFactory =
|
|
// DocumentBuilderFactory.newInstance();
|
|
//
|
|
// dbFactory.setIgnoringComments(true);
|
|
// dbFactory.setNamespaceAware(false);
|
|
// dbFactory.setValidating(false);
|
|
//
|
|
// DocumentBuilder db = null;
|
|
// try {
|
|
// db = dbFactory.newDocumentBuilder();
|
|
// } catch (ParserConfigurationException pce) {
|
|
// throw new ParsingException("couldn't get a document builder", pce);
|
|
// }
|
|
//
|
|
// Document doc = null;
|
|
// try {
|
|
// doc = db.parse(new FileInputStream(configFile));
|
|
// } catch (IOException ioe) {
|
|
// throw new ParsingException("failed to load the file ", ioe);
|
|
// } catch (SAXException saxe) {
|
|
// throw new ParsingException("error parsing the XML tree", saxe);
|
|
// } catch (IllegalArgumentException iae) {
|
|
// throw new ParsingException("no data to parse", iae);
|
|
// }
|
|
|
|
Element root = doc.getDocumentElement();
|
|
|
|
if (! root.getTagName().equals("config")) {
|
|
throw new ParsingException("unknown document type: " +
|
|
root.getTagName());
|
|
}
|
|
|
|
return root;
|
|
}
|
|
|
|
/**
|
|
* Private helper that handles the pdp elements.
|
|
*
|
|
* @param root The node containing the finder module class names.
|
|
*
|
|
* @return The PDP configuration object.
|
|
*
|
|
* @throws ParsingException
|
|
*/
|
|
private PDPConfig parsePDPConfig(Node root) throws ParsingException {
|
|
|
|
// ArrayList attrModules = new ArrayList();
|
|
// HashSet policyModules = new HashSet();
|
|
// ArrayList rsrcModules = new ArrayList();
|
|
// ArrayList revocationModules = new ArrayList();
|
|
//
|
|
// PDPConfig pdpConfig = new PDPConfig();
|
|
//
|
|
// // go through all elements of the pdp, loading the specified modules
|
|
// NodeList children = root.getChildNodes();
|
|
// for (int i = 0; i < children.getLength(); i++) {
|
|
// Node child = children.item(i);
|
|
// String name = child.getNodeName();
|
|
//
|
|
// if (name.equals("policyFinderModule")) {
|
|
// policyModules.add(loadClass("module", child));
|
|
// } else if (name.equals("attributeFinderModule")) {
|
|
// attrModules.add(loadClass("module", child));
|
|
// } else if (name.equals("resourceFinderModule")) {
|
|
// rsrcModules.add(loadClass("module", child));
|
|
// } else if (name.equals("revocationFinderModule")) {
|
|
// revocationModules.add(loadClass("module", child));
|
|
// }
|
|
// }
|
|
//
|
|
// // after loading the modules, use the collections to setup a
|
|
// // PDPConfig based on this pdp element
|
|
//
|
|
// AttributeFinder attrFinder = new AttributeFinder();
|
|
// attrFinder.setModules(attrModules);
|
|
//
|
|
// PolicyFinder policyFinder = new PolicyFinder();
|
|
// policyFinder.setModules(policyModules);
|
|
//
|
|
// ResourceFinder rsrcFinder = new ResourceFinder();
|
|
// rsrcFinder.setModules(rsrcModules);
|
|
//
|
|
// RevocationFinder revocationFinder = new RevocationFinder();
|
|
// revocationFinder.setModules(revocationModules);
|
|
//
|
|
// pdpConfig.setFinder(attrFinder, policyFinder, rsrcFinder,
|
|
// revocationFinder);
|
|
//
|
|
// return pdpConfig;
|
|
|
|
|
|
ArrayList<AttributeFinderModule> attrModules = new ArrayList<AttributeFinderModule>();
|
|
HashSet<PolicyFinderModule> policyModules = new HashSet<PolicyFinderModule>();
|
|
ArrayList<ResourceFinderModule> rsrcModules = new ArrayList<ResourceFinderModule>();
|
|
ArrayList<RevocationFinderModule> revocationModules = new ArrayList<RevocationFinderModule>();
|
|
ArrayList<RequiredAttributesModule> requiredAttrModules = new ArrayList<RequiredAttributesModule>();
|
|
|
|
// go through all elements of the pdp, loading the specified modules
|
|
NodeList children = root.getChildNodes();
|
|
for (int i = 0; i < children.getLength(); i++) {
|
|
Node child = children.item(i);
|
|
String name = child.getNodeName();
|
|
|
|
if (name.equals("policyFinderModule")) {
|
|
policyModules.add((PolicyFinderModule)loadClass("module", child));
|
|
} else if (name.equals("attributeFinderModule")) {
|
|
attrModules.add((AttributeFinderModule)loadClass("module", child));
|
|
} else if (name.equals("resourceFinderModule")) {
|
|
rsrcModules.add((ResourceFinderModule)loadClass("module", child));
|
|
} else if (name.equals("revocationFinderModule")) {
|
|
revocationModules.add((RevocationFinderModule)loadClass("module", child));
|
|
} else if (name.equals("requiredAttributesModule")) {
|
|
requiredAttrModules.add((RequiredAttributesModule) loadClass("module", child));
|
|
}
|
|
}
|
|
|
|
// after loading the modules, use the collections to setup a
|
|
// PDPConfig based on this pdp element
|
|
|
|
AttributeFinder attrFinder = new AttributeFinder();
|
|
attrFinder.setModules(attrModules);
|
|
|
|
PolicyFinder policyFinder = new PolicyFinder();
|
|
policyFinder.setModules(policyModules);
|
|
|
|
ResourceFinder rsrcFinder = new ResourceFinder();
|
|
rsrcFinder.setModules(rsrcModules);
|
|
|
|
RevocationFinder revocationFinder = new RevocationFinder();
|
|
revocationFinder.setModules(revocationModules);
|
|
|
|
AttributeDesignator.setRequiredAttrModules(requiredAttrModules);
|
|
|
|
return new PDPConfig(attrFinder, policyFinder, rsrcFinder,
|
|
revocationFinder);
|
|
}
|
|
|
|
/**
|
|
* Private helper that handles the attributeFactory elements.
|
|
*
|
|
* @param root The node containing the attribute factory definition.
|
|
*
|
|
* @return The attribute factory object.
|
|
*
|
|
* @throws ParsingException
|
|
*/
|
|
private AttributeFactory parseAttributeFactory(Node root)
|
|
throws ParsingException
|
|
{
|
|
AttributeFactory factory = null;
|
|
|
|
// check if we're starting with the standard factory setup
|
|
if (useStandard(root, "useStandardDatatypes")) {
|
|
logger.debug("Starting with standard Datatypes");
|
|
|
|
factory = StandardAttributeFactory.getNewFactory();
|
|
} else {
|
|
factory = new BaseAttributeFactory();
|
|
}
|
|
|
|
// now look for all datatypes specified for this factory, adding
|
|
// them as we go
|
|
NodeList children = root.getChildNodes();
|
|
for (int i = 0; i < children.getLength(); i++) {
|
|
Node child = children.item(i);
|
|
|
|
if (child.getNodeName().equals("datatype")) {
|
|
// a datatype is a class with an identifier
|
|
String identifier = child.getAttributes().
|
|
getNamedItem("identifier").getNodeValue();
|
|
AttributeProxy proxy =
|
|
(AttributeProxy)(loadClass("datatype", child));
|
|
|
|
try {
|
|
factory.addDatatype(identifier, proxy);
|
|
} catch (IllegalArgumentException iae) {
|
|
throw new ParsingException("duplicate datatype: " +
|
|
identifier, iae);
|
|
}
|
|
}
|
|
}
|
|
|
|
return factory;
|
|
}
|
|
|
|
/**
|
|
* Private helper that handles the combiningAlgFactory elements.
|
|
*/
|
|
private CombiningAlgFactory parseCombiningAlgFactory(Node root)
|
|
throws ParsingException
|
|
{
|
|
CombiningAlgFactory factory = null;
|
|
|
|
// check if we're starting with the standard factory setup
|
|
if (useStandard(root, "useStandardAlgorithms")) {
|
|
logger.debug("Starting with standard Combining Algorithms");
|
|
|
|
factory = StandardCombiningAlgFactory.getNewFactory();
|
|
} else {
|
|
factory = new BaseCombiningAlgFactory();
|
|
}
|
|
CombiningAlgFactory.setAllFactories(factory);
|
|
|
|
|
|
// now look for all algorithms specified for this factory, adding
|
|
// them as we go
|
|
NodeList children = root.getChildNodes();
|
|
for (int i = 0; i < children.getLength(); i++) {
|
|
Node child = children.item(i);
|
|
|
|
if (child.getNodeName().equals("algorithm")) {
|
|
// an algorithm is a simple class element
|
|
CombiningAlgorithm alg =
|
|
(CombiningAlgorithm)(loadClass("algorithm", child));
|
|
try {
|
|
factory.addAlgorithm(alg);
|
|
} catch (IllegalArgumentException iae) {
|
|
throw new ParsingException("duplicate combining " +
|
|
"algorithm: " +
|
|
alg.getIdentifier().toString(),
|
|
iae);
|
|
}
|
|
}
|
|
}
|
|
|
|
return factory;
|
|
}
|
|
|
|
/**
|
|
* Private helper that handles the functionFactory elements. This one
|
|
* is a little more complex than the other two factory helper methods,
|
|
* since it consists of three factories (target, condition, and general).
|
|
*/
|
|
private FunctionFactoryProxy parseFunctionFactory(Node root)
|
|
throws ParsingException
|
|
{
|
|
FunctionFactoryProxy proxy = null;
|
|
FunctionFactory generalFactory = null;
|
|
FunctionFactory conditionFactory = null;
|
|
FunctionFactory targetFactory = null;
|
|
|
|
// check if we're starting with the standard factory setup, and
|
|
// make sure that the proxy is pre-configured
|
|
if (useStandard(root, "useStandardFunctions")) {
|
|
logger.debug("Starting with standard Functions");
|
|
|
|
proxy = StandardFunctionFactory.getNewFactoryProxy();
|
|
|
|
targetFactory = proxy.getTargetFactory();
|
|
conditionFactory = proxy.getConditionFactory();
|
|
generalFactory = proxy.getGeneralFactory();
|
|
} else {
|
|
generalFactory = new BaseFunctionFactory();
|
|
conditionFactory = new BaseFunctionFactory(generalFactory);
|
|
targetFactory = new BaseFunctionFactory(conditionFactory);
|
|
|
|
proxy = new BasicFunctionFactoryProxy(targetFactory,
|
|
conditionFactory,
|
|
generalFactory);
|
|
}
|
|
|
|
// go through and load the three sections, putting the loaded
|
|
// functions into the appropriate factory
|
|
NodeList children = root.getChildNodes();
|
|
for (int i = 0; i < children.getLength(); i++) {
|
|
Node child = children.item(i);
|
|
String name = child.getNodeName();
|
|
|
|
if (name.equals("target")) {
|
|
logger.debug("Loading [TARGET] functions");
|
|
functionParserHelper(child, targetFactory);
|
|
} else if (name.equals("condition")) {
|
|
logger.debug("Loading [CONDITION] functions");
|
|
functionParserHelper(child, conditionFactory);
|
|
} else if (name.equals("general")) {
|
|
logger.debug("Loading [GENERAL] functions");
|
|
functionParserHelper(child, generalFactory);
|
|
}
|
|
}
|
|
|
|
return proxy;
|
|
}
|
|
|
|
/**
|
|
* Private helper used by the function factory code to load a specific
|
|
* target, condition, or general section.
|
|
*/
|
|
private void functionParserHelper(Node root, FunctionFactory factory)
|
|
throws ParsingException
|
|
{
|
|
// go through all elements in the section
|
|
NodeList children = root.getChildNodes();
|
|
for (int i = 0; i < children.getLength(); i++) {
|
|
Node child = children.item(i);
|
|
String name = child.getNodeName();
|
|
|
|
if (name.equals("function")) {
|
|
// a function section is a simple class element
|
|
Function function =
|
|
(Function)(loadClass("function", child));
|
|
try {
|
|
factory.addFunction(function);
|
|
} catch (IllegalArgumentException iae) {
|
|
throw new ParsingException("duplicate function", iae);
|
|
}
|
|
} else if (name.equals("abstractFunction")) {
|
|
// an abstract function is a class with an identifier
|
|
URI identifier = null;
|
|
try {
|
|
identifier = new URI(child.getAttributes().
|
|
getNamedItem("identifier").
|
|
getNodeValue());
|
|
} catch (URISyntaxException urise) {
|
|
throw new ParsingException("invalid function identifier",
|
|
urise);
|
|
}
|
|
|
|
FunctionProxy proxy =
|
|
(FunctionProxy)(loadClass("abstract function", child));
|
|
try {
|
|
factory.addAbstractFunction(proxy, identifier);
|
|
} catch (IllegalArgumentException iae) {
|
|
throw new ParsingException("duplicate abstract function",
|
|
iae);
|
|
}
|
|
} else if (name.equals("functionCluster")) {
|
|
// a cluster is a class that will give us a collection of
|
|
// functions that need to be added one by one into the factory
|
|
FunctionCluster cluster =
|
|
(FunctionCluster)(loadClass("function cluster", child));
|
|
|
|
Iterator<Function> it = cluster.getSupportedFunctions().iterator();
|
|
while (it.hasNext()) {
|
|
try {
|
|
factory.addFunction(it.next());
|
|
} catch (IllegalArgumentException iae) {
|
|
throw new ParsingException("duplicate function", iae);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Private helper that is used by all the code to load an instance of
|
|
* the given class...this assumes that the class is in the classpath,
|
|
* both for simplicity and for stronger security
|
|
*/
|
|
protected Object loadClass(String prefix, Node root)
|
|
throws ParsingException
|
|
{
|
|
// get the name of the class
|
|
String className =
|
|
root.getAttributes().getNamedItem("class").getNodeValue();
|
|
|
|
if (logger.isDebugEnabled()) {
|
|
logger.debug("Loading [ " + prefix + ": " + className + " ]");
|
|
}
|
|
|
|
// load the given class using the local classloader
|
|
Class<? extends Object> c = null;
|
|
try {
|
|
c = this.loader.loadClass(className);
|
|
} catch (ClassNotFoundException cnfe) {
|
|
throw new ParsingException("couldn't load class " + className,
|
|
cnfe);
|
|
}
|
|
Object instance = null;
|
|
|
|
// figure out if there are any parameters to the constructor
|
|
if (root.hasChildNodes()) {
|
|
// parse the arguments to the constructor
|
|
List<? extends Object> args = null;
|
|
try {
|
|
args = getArgs(root);
|
|
} catch (IllegalArgumentException iae) {
|
|
throw new ParsingException("illegal class arguments", iae);
|
|
}
|
|
int argLength = args.size();
|
|
|
|
// next we need to see if there's a constructor that matches the
|
|
// arguments provided...this has to be done by hand since
|
|
// Class.getConstructor(Class []) doesn't handle sub-classes and
|
|
// generic types (for instance, a constructor taking List won't
|
|
// match a parameter list containing ArrayList)
|
|
|
|
// get the list of all available constructors
|
|
Constructor<? extends Object> [] cons = c.getConstructors();
|
|
Constructor<? extends Object> constructor = null;
|
|
|
|
for (int i = 0; i < cons.length; i++) {
|
|
// get the parameters for this constructor
|
|
Class<? extends Object> [] params = cons[i].getParameterTypes();
|
|
if (params.length == argLength) {
|
|
Iterator<? extends Object> it = args.iterator();
|
|
int j = 0;
|
|
|
|
// loop through the parameters and see if each one is
|
|
// assignable from the coresponding input argument
|
|
while (it.hasNext()) {
|
|
if (! params[j].isAssignableFrom(it.next().getClass())) {
|
|
break;
|
|
}
|
|
j++;
|
|
}
|
|
|
|
// if we looked at all the parameters, then this
|
|
// constructor matches the input
|
|
if (j == argLength) {
|
|
constructor = cons[i];
|
|
}
|
|
}
|
|
|
|
// if we've found a matching constructor then stop looping
|
|
if (constructor != null) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// make sure we found a matching constructor
|
|
if (constructor == null) {
|
|
throw new ParsingException("couldn't find a matching " +
|
|
"constructor for " + c);
|
|
}
|
|
|
|
// finally, instantiate the class
|
|
try {
|
|
instance = constructor.newInstance(args.toArray());
|
|
} catch (InstantiationException ie) {
|
|
throw new ParsingException("couldn't instantiate " + className,
|
|
ie);
|
|
} catch (IllegalAccessException iae) {
|
|
throw new ParsingException("couldn't get access to instance " +
|
|
"of " + className, iae);
|
|
} catch (InvocationTargetException ite) {
|
|
throw new ParsingException("couldn't create " + className,
|
|
ite);
|
|
}
|
|
} else {
|
|
// we're using a null constructor, so this is easy
|
|
try {
|
|
instance = c.newInstance();
|
|
} catch (InstantiationException ie) {
|
|
throw new ParsingException("couldn't instantiate " + className
|
|
+ " with empty constructor", ie);
|
|
} catch (IllegalAccessException iae) {
|
|
throw new ParsingException("couldn't get access to instance " +
|
|
"of " + className, iae);
|
|
}
|
|
}
|
|
Method setConfigurationStore = null;
|
|
try {
|
|
setConfigurationStore = c.getMethod("setConfigurationStore", this.getClass());
|
|
setConfigurationStore.invoke(instance, this);
|
|
//logger.debug("set ConfigurationStore to " + c);
|
|
} catch ( NoSuchMethodException e) {
|
|
logger.debug(c + " does not have a \"setConfigurationStore\" method to retreive the current configuration");
|
|
} catch (Exception e) {
|
|
logger.debug("Error at setting the ConfigurationStore to " + c + ": " + e.getClass() + ": " + e.getMessage() + ")");
|
|
e.printStackTrace();
|
|
}
|
|
|
|
return instance;
|
|
}
|
|
|
|
/**
|
|
* Private helper that gets the constructor arguments for a given class.
|
|
* Right now this just supports String and List, but it's trivial to
|
|
* add support for other types should that be needed. Right now, it's not
|
|
* clear that there's any need for other types.
|
|
*/
|
|
private List<Object> getArgs(Node root) {
|
|
List<Object> args = new ArrayList<Object>();
|
|
NodeList children = root.getChildNodes();
|
|
|
|
for (int i = 0; i < children.getLength(); i++) {
|
|
Node child = children.item(i);
|
|
String name = child.getNodeName();
|
|
|
|
if (child.getNodeType() == Node.ELEMENT_NODE) {
|
|
if (name.equals("string")) {
|
|
args.add(child.getFirstChild().getNodeValue());
|
|
} else if (name.equals("list")) {
|
|
args.add(getArgs(child));
|
|
} else {
|
|
throw new IllegalArgumentException("unkown arg type: " +
|
|
name);
|
|
}
|
|
}
|
|
}
|
|
return args;
|
|
}
|
|
|
|
/**
|
|
* Private helper used by the three factory routines to see if the
|
|
* given factory should be based on the standard setup
|
|
*/
|
|
private boolean useStandard(Node node, String attributeName) {
|
|
NamedNodeMap map = node.getAttributes();
|
|
if (map == null) {
|
|
return true;
|
|
}
|
|
|
|
Node attrNode = map.getNamedItem(attributeName);
|
|
if (attrNode == null) {
|
|
return true;
|
|
}
|
|
|
|
return attrNode.getNodeValue().equals("true");
|
|
}
|
|
|
|
/**
|
|
* Returns the default PDP configuration. If no default was specified
|
|
* then this throws an exception.
|
|
*
|
|
* @return the default PDP configuration
|
|
*
|
|
* @throws UnknownIdentifierException if there is no default config
|
|
*/
|
|
public PDPConfig getDefaultPDPConfig() throws UnknownIdentifierException {
|
|
if (this.defaultPDPConfig == null) {
|
|
throw new UnknownIdentifierException("no default available");
|
|
}
|
|
|
|
return this.defaultPDPConfig;
|
|
}
|
|
|
|
/**
|
|
* Returns the PDP configuration with the given name. If no such
|
|
* configuration exists then an exception is thrown.
|
|
*
|
|
* @param name The name of the configuration.
|
|
*
|
|
* @return the matching PDP configuation
|
|
*
|
|
* @throws UnknownIdentifierException if the name is unknown
|
|
*/
|
|
public PDPConfig getPDPConfig(String name)
|
|
throws UnknownIdentifierException
|
|
{
|
|
Object object = this.pdpConfigMap.get(name);
|
|
|
|
if (object == null) {
|
|
throw new UnknownIdentifierException("unknown pdp: " + name);
|
|
}
|
|
|
|
return (PDPConfig)object;
|
|
}
|
|
|
|
/**
|
|
* Returns a set of identifiers representing each PDP configuration
|
|
* available.
|
|
*
|
|
* @return a <code>Set</code> of <code>String</code>s
|
|
*/
|
|
public Set<String> getSupportedPDPConfigurations() {
|
|
return Collections.unmodifiableSet(this.pdpConfigMap.keySet());
|
|
}
|
|
|
|
/**
|
|
* Returns the default attribute factory.
|
|
*
|
|
* @return The default attribute factory.
|
|
*/
|
|
public AttributeFactory getDefaultAttributeFactory() {
|
|
return this.defaultAttributeFactory;
|
|
}
|
|
|
|
/**
|
|
* Returns the attribute factory with the given name. If no such
|
|
* factory exists then an exception is thrown.
|
|
*
|
|
* @param name The name of the attribute factory.
|
|
*
|
|
* @return the matching attribute factory
|
|
*
|
|
* @throws UnknownIdentifierException if the name is unknown
|
|
*/
|
|
public AttributeFactory getAttributeFactory(String name)
|
|
throws UnknownIdentifierException
|
|
{
|
|
Object object = this.attributeMap.get(name);
|
|
|
|
if (object == null) {
|
|
throw new UnknownIdentifierException("unknown factory: " + name);
|
|
}
|
|
|
|
return (AttributeFactory)object;
|
|
}
|
|
|
|
/**
|
|
* Returns a set of identifiers representing each attribute factory
|
|
* available.
|
|
*
|
|
* @return a <code>Set</code> of <code>String</code>s
|
|
*/
|
|
public Set<String> getSupportedAttributeFactories() {
|
|
return Collections.unmodifiableSet(this.attributeMap.keySet());
|
|
}
|
|
|
|
/**
|
|
* Registers all the supported factories with the given identifiers. If
|
|
* a given identifier is already in use, then that factory is not
|
|
* registered. This method is provided only as a convenience, and
|
|
* any registration that may involve identifier clashes should be done
|
|
* by registering each factory individually.
|
|
*/
|
|
public void registerAttributeFactories() {
|
|
Iterator<String> it = this.attributeMap.keySet().iterator();
|
|
|
|
while (it.hasNext()) {
|
|
String id = it.next();
|
|
AttributeFactory af = this.attributeMap.get(id);
|
|
|
|
try {
|
|
AttributeFactory.registerFactory(id, new AFProxy(af));
|
|
} catch (IllegalArgumentException iae) {
|
|
logger.warn("Couldn't register AttributeFactory:"
|
|
+ id + " (already in use)", iae);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the default combiningAlg factory.
|
|
*
|
|
* @return the default combiningAlg factory
|
|
*/
|
|
public CombiningAlgFactory getDefaultCombiningAlgFactory() {
|
|
return this.defaultCombiningFactory;
|
|
}
|
|
|
|
/**
|
|
* Returns the combiningAlg factory with the given name. If no such
|
|
* factory exists then an exception is thrown.
|
|
*
|
|
* @param name The name of the combining algorithm factory.
|
|
*
|
|
* @return the matching combiningAlg factory
|
|
*
|
|
* @throws UnknownIdentifierException if the name is unknown
|
|
*/
|
|
public CombiningAlgFactory getCombiningAlgFactory(String name)
|
|
throws UnknownIdentifierException
|
|
{
|
|
Object object = this.combiningMap.get(name);
|
|
|
|
if (object == null) {
|
|
throw new UnknownIdentifierException("unknown factory: " + name);
|
|
}
|
|
|
|
return (CombiningAlgFactory)object;
|
|
}
|
|
|
|
/**
|
|
* Returns a set of identifiers representing each combiningAlg factory
|
|
* available.
|
|
*
|
|
* @return a <code>Set</code> of <code>String</code>s
|
|
*/
|
|
public Set<String>getSupportedCombiningAlgFactories() {
|
|
return Collections.unmodifiableSet(this.combiningMap.keySet());
|
|
}
|
|
|
|
/**
|
|
* Registers all the supported factories with the given identifiers. If
|
|
* a given identifier is already in use, then that factory is not
|
|
* registered. This method is provided only as a convenience, and
|
|
* any registration that may involve identifier clashes should be done
|
|
* by registering each factory individually.
|
|
*/
|
|
public void registerCombiningAlgFactories() {
|
|
Iterator<String> it = this.combiningMap.keySet().iterator();
|
|
|
|
while (it.hasNext()) {
|
|
String id = it.next();
|
|
CombiningAlgFactory cf = this.combiningMap.get(id);
|
|
|
|
try {
|
|
CombiningAlgFactory.registerFactory(id, new CAFProxy(cf));
|
|
} catch (IllegalArgumentException iae) {
|
|
logger.warn("Couldn't register " +
|
|
"CombiningAlgFactory: " + id + " (already in use)",
|
|
iae);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the default function factory proxy.
|
|
*
|
|
* @return the default function factory proxy
|
|
*/
|
|
public FunctionFactoryProxy getDefaultFunctionFactoryProxy() {
|
|
return this.defaultFunctionFactoryProxy;
|
|
}
|
|
|
|
/**
|
|
* Returns the function factory proxy with the given name. If no such
|
|
* proxy exists then an exception is thrown.
|
|
*
|
|
* @param name The name of the function factory proxy.
|
|
*
|
|
* @return the matching function factory proxy
|
|
*
|
|
* @throws UnknownIdentifierException if the name is unknown
|
|
*/
|
|
public FunctionFactoryProxy getFunctionFactoryProxy(String name)
|
|
throws UnknownIdentifierException
|
|
{
|
|
Object object = this.functionMap.get(name);
|
|
|
|
if (object == null) {
|
|
throw new UnknownIdentifierException("unknown factory: " + name);
|
|
}
|
|
|
|
return (FunctionFactoryProxy)object;
|
|
}
|
|
|
|
/**
|
|
* Returns a set of identifiers representing each function factory proxy
|
|
* available.
|
|
*
|
|
* @return a <code>Set</code> of <code>String</code>s
|
|
*/
|
|
public Set<String> getSupportedFunctionFactories() {
|
|
return Collections.unmodifiableSet(this.functionMap.keySet());
|
|
}
|
|
|
|
/**
|
|
* Registers all the supported factories with the given identifiers. If
|
|
* a given identifier is already in use, then that factory is not
|
|
* registered. This method is provided only as a convenience, and
|
|
* any registration that may involve identifier clashes should be done
|
|
* by registering each factory individually.
|
|
*/
|
|
public void registerFunctionFactories() {
|
|
Iterator<String> it = this.functionMap.keySet().iterator();
|
|
|
|
while (it.hasNext()) {
|
|
String id = it.next();
|
|
FunctionFactoryProxy ffp = this.functionMap.get(id);
|
|
|
|
try {
|
|
FunctionFactory.registerFactory(id, ffp);
|
|
} catch (IllegalArgumentException iae) {
|
|
logger.warn("Couldn't register FunctionFactory: "
|
|
+ id + " (already in use)", iae);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Uses the default configuration to re-set the default factories used
|
|
* by the system (attribute, combining algorithm, and function). If
|
|
* a default is not provided for a given factory, then that factory
|
|
* will not be set as the system's default.
|
|
*/
|
|
public void useDefaultFactories() {
|
|
logger.debug("Switching to default factories from configuration");
|
|
|
|
// set the default attribute factory, if it exists here
|
|
if (this.defaultAttributeFactory != null) {
|
|
AttributeFactory.setDefaultFactory(
|
|
new AFProxy(this.defaultAttributeFactory));
|
|
}
|
|
|
|
// set the default combining algorithm factory, if it exists here
|
|
if (this.defaultCombiningFactory != null) {
|
|
CombiningAlgFactory.setDefaultFactory(
|
|
new CAFProxy(this.defaultCombiningFactory));
|
|
|
|
}
|
|
|
|
// set the default function factories, if they exists here
|
|
if (this.defaultFunctionFactoryProxy != null) {
|
|
FunctionFactory.setDefaultFactory(
|
|
this.defaultFunctionFactoryProxy);
|
|
}
|
|
}
|
|
|
|
public String getBaseDir() {
|
|
return baseDir;
|
|
}
|
|
|
|
// public Map<String, String> getCustumAttrs() {
|
|
// return this.customAttr;
|
|
// }
|
|
|
|
public Object getCustomAttr(String key) {
|
|
return this.customAttr.get(key);
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
static class AFProxy implements AttributeFactoryProxy {
|
|
private AttributeFactory factory;
|
|
|
|
/**
|
|
* @param factory
|
|
*/
|
|
public AFProxy(AttributeFactory factory) {
|
|
this.factory = factory;
|
|
}
|
|
|
|
/**
|
|
* @see com.sun.xacml.attr.AttributeFactoryProxy#getFactory()
|
|
*/
|
|
public AttributeFactory getFactory() {
|
|
return this.factory;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
static class CAFProxy implements CombiningAlgFactoryProxy {
|
|
private CombiningAlgFactory factory;
|
|
|
|
/**
|
|
* @param factory
|
|
*/
|
|
public CAFProxy(CombiningAlgFactory factory) {
|
|
this.factory = factory;
|
|
}
|
|
/**
|
|
* @see com.sun.xacml.combine.CombiningAlgFactoryProxy#getFactory()
|
|
*/
|
|
public CombiningAlgFactory getFactory() {
|
|
return this.factory;
|
|
}
|
|
}
|
|
}
|