Package com.sun.xacml

Source Code of com.sun.xacml.ConfigurationStore$AFProxy

/*
* @(#)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 java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
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.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

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;
import org.xml.sax.SAXException;

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.FunctionFactory;
import com.sun.xacml.cond.FunctionFactoryProxy;
import com.sun.xacml.cond.FunctionProxy;
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.ResourceFinder;
import com.sun.xacml.finder.ResourceFinderModule;

/**
* 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
*
*         Adding generic type support by Christian Mueller (geotools)
*/
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;

    // the classloader we'll use for loading classes
    private ClassLoader loader;

    // 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.severe("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(configFile));
        } catch (ParsingException pe) {
            logger.log(Level.SEVERE, "Runtime config file 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.
     *
     * @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 {
        try {
            setupConfig(configFile);
        } catch (ParsingException pe) {
            logger.log(Level.SEVERE, "Runtime config file couldn't be loaded"
                    + " so no configurations will be available", pe);
            throw pe;
        }
    }

    /**
     * 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.
     */
    private void setupConfig(File configFile) throws ParsingException {
        logger.config("Loading runtime configuration");

        // load our classloader
        loader = getClass().getClassLoader();

        // get the root node from the configuration file
        Node root = getRootNode(configFile);

        // initialize all the maps
        pdpConfigMap = new HashMap<String, PDPConfig>();
        attributeMap = new HashMap<String, AttributeFactory>();
        combiningMap = new HashMap<String, CombiningAlgFactory>();
        functionMap = new HashMap<String, FunctionFactoryProxy>();

        // 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)
                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.isLoggable(Level.CONFIG))
                    logger.config("Loading PDP: " + elementName);
                if (pdpConfigMap.containsKey(elementName))
                    throw new ParsingException("more that one pdp with " + "name \"" + elementName
                            + "\"");
                pdpConfigMap.put(elementName, parsePDPConfig(child));
            } else if (childName.equals("attributeFactory")) {
                if (logger.isLoggable(Level.CONFIG))
                    logger.config("Loading AttributeFactory: " + elementName);
                if (attributeMap.containsKey(elementName))
                    throw new ParsingException("more that one " + "attributeFactory with name "
                            + elementName + "\"");
                attributeMap.put(elementName, parseAttributeFactory(child));
            } else if (childName.equals("combiningAlgFactory")) {
                if (logger.isLoggable(Level.CONFIG))
                    logger.config("Loading CombiningAlgFactory: " + elementName);
                if (combiningMap.containsKey(elementName))
                    throw new ParsingException("more that one " + "combiningAlgFactory with "
                            + "name \"" + elementName + "\"");
                combiningMap.put(elementName, parseCombiningAlgFactory(child));
            } else if (childName.equals("functionFactory")) {
                if (logger.isLoggable(Level.CONFIG))
                    logger.config("Loading FunctionFactory: " + elementName);
                if (functionMap.containsKey(elementName))
                    throw new ParsingException("more that one functionFactory" + " with name \""
                            + elementName + "\"");
                functionMap.put(elementName, parseFunctionFactory(child));
            }
        }

        // finally, extract the default elements
        defaultPDPConfig = (PDPConfig) (pdpConfigMap.get(defaultPDP));

        defaultAttributeFactory = (AttributeFactory) (attributeMap.get(defaultAF));
        if (defaultAttributeFactory == null) {
            try {
                defaultAttributeFactory = AttributeFactory.getInstance(defaultAF);
            } catch (Exception e) {
                throw new ParsingException("Unknown AttributeFactory", e);
            }
        }

        defaultCombiningFactory = (CombiningAlgFactory) (combiningMap.get(defaultCAF));
        if (defaultCombiningFactory == null) {
            try {
                defaultCombiningFactory = CombiningAlgFactory.getInstance(defaultCAF);
            } catch (Exception e) {
                throw new ParsingException("Unknown CombininAlgFactory", e);
            }
        }

        defaultFunctionFactoryProxy = (FunctionFactoryProxy) (functionMap.get(defaultFF));
        if (defaultFunctionFactoryProxy == null) {
            try {
                defaultFunctionFactoryProxy = FunctionFactory.getInstance(defaultFF);
            } catch (Exception e) {
                throw new ParsingException("Unknown FunctionFactory", e);
            }
        }
    }

    /**
     * Private helper that gets a default factory identifier, or fills in the default value if no
     * identifier is provided.
     */
    private String getDefaultFactory(NamedNodeMap attrs, String factoryName) {
        Node node = attrs.getNamedItem(factoryName);
        if (node != null)
            return node.getNodeValue();
        else
            return PolicyMetaData.XACML_1_0_IDENTIFIER;
    }

    /**
     * Private helper that parses the file and sets up the DOM tree.
     */
    private Node getRootNode(File configFile) 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.
     */
    private PDPConfig parsePDPConfig(Node root) throws ParsingException {
        ArrayList<AttributeFinderModule> attrModules = new ArrayList<AttributeFinderModule>();
        HashSet<PolicyFinderModule> policyModules = new HashSet<PolicyFinderModule>();
        ArrayList<ResourceFinderModule> rsrcModules = new ArrayList<ResourceFinderModule>();

        // 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));
            }
        }

        // 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);

        return new PDPConfig(attrFinder, policyFinder, rsrcFinder);
    }

    /**
     * Private helper that handles the attributeFactory elements.
     */
    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.config("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.config("Starting with standard Combining Algorithms");

            factory = StandardCombiningAlgFactory.getNewFactory();
        } else {
            factory = new BaseCombiningAlgFactory();
        }

        // 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.config("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.config("Loading [TARGET] functions");
                functionParserHelper(child, targetFactory);
            } else if (name.equals("condition")) {
                logger.config("Loading [CONDITION] functions");
                functionParserHelper(child, conditionFactory);
            } else if (name.equals("general")) {
                logger.config("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));

                for (Function function : cluster.getSupportedFunctions()) {
                    try {
                        factory.addFunction(function);
                    } 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
     */
    private Object loadClass(String prefix, Node root) throws ParsingException {
        // get the name of the class
        String className = root.getAttributes().getNamedItem("class").getNodeValue();

        if (logger.isLoggable(Level.CONFIG))
            logger.config("Loading [ " + prefix + ": " + className + " ]");

        // load the given class using the local classloader
        Class<?> c = null;
        try {
            c = 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()) {
            // 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);
            }
        } else {
            // parse the arguments to the constructor
            List<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<?>[] cons = c.getConstructors();
            Constructor<?> constructor = null;

            for (int i = 0; i < cons.length; i++) {
                // get the parameters for this constructor
                Class<?>[] params = cons[i].getParameterTypes();
                if (params.length == argLength) {

                    int j = 0;

                    // loop through the parameters and see if each one is
                    // assignable from the coresponding input argument
                    for (Object obj : args) {
                        if (!params[j].isAssignableFrom(obj.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");

            // 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);
            }
        }

        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 (defaultPDPConfig == null)
            throw new UnknownIdentifierException("no default available");

        return defaultPDPConfig;
    }

    /**
     * Returns the PDP configuration with the given name. If no such configuration exists then an
     * exception is thrown.
     *
     * @return the matching PDP configuation
     *
     * @throws UnknownIdentifierException
     *             if the name is unknown
     */
    public PDPConfig getPDPConfig(String name) throws UnknownIdentifierException {
        Object object = 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(pdpConfigMap.keySet());
    }

    /**
     * Returns the default attribute factory.
     *
     * @return the default attribute factory
     */
    public AttributeFactory getDefaultAttributeFactory() {
        return defaultAttributeFactory;
    }

    /**
     * Returns the attribute factory with the given name. If no such factory exists then an
     * exception is thrown.
     *
     * @return the matching attribute factory
     *
     * @throws UnknownIdentifierException
     *             if the name is unknown
     */
    public AttributeFactory getAttributeFactory(String name) throws UnknownIdentifierException {
        Object object = 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(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() {
        for (String id : attributeMap.keySet()) {
            AttributeFactory af = attributeMap.get(id);

            try {
                AttributeFactory.registerFactory(id, new AFProxy(af));
            } catch (IllegalArgumentException iae) {
                logger.log(Level.WARNING, "Couldn't register AttributeFactory:" + id
                        + " (already in use)", iae);
            }
        }
    }

    /**
     * Returns the default combiningAlg factory.
     *
     * @return the default combiningAlg factory
     */
    public CombiningAlgFactory getDefaultCombiningAlgFactory() {
        return defaultCombiningFactory;
    }

    /**
     * Returns the combiningAlg factory with the given name. If no such factory exists then an
     * exception is thrown.
     *
     * @return the matching combiningAlg factory
     *
     * @throws UnknownIdentifierException
     *             if the name is unknown
     */
    public CombiningAlgFactory getCombiningAlgFactory(String name)
            throws UnknownIdentifierException {
        Object object = 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(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() {

        for (String id : combiningMap.keySet()) {
            CombiningAlgFactory cf = (CombiningAlgFactory) (combiningMap.get(id));

            try {
                CombiningAlgFactory.registerFactory(id, new CAFProxy(cf));
            } catch (IllegalArgumentException iae) {
                logger.log(Level.WARNING, "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 defaultFunctionFactoryProxy;
    }

    /**
     * Returns the function factory proxy with the given name. If no such proxy exists then an
     * exception is thrown.
     *
     * @return the matching function factory proxy
     *
     * @throws UnknownIdentifierException
     *             if the name is unknown
     */
    public FunctionFactoryProxy getFunctionFactoryProxy(String name)
            throws UnknownIdentifierException {
        Object object = 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(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() {

        for (String id : functionMap.keySet()) {
            FunctionFactoryProxy ffp = (FunctionFactoryProxy) (functionMap.get(id));

            try {
                FunctionFactory.registerFactory(id, ffp);
            } catch (IllegalArgumentException iae) {
                logger.log(Level.WARNING, "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.fine("Switching to default factories from configuration");

        // set the default attribute factory, if it exists here
        if (defaultAttributeFactory != null) {
            AttributeFactory.setDefaultFactory(new AFProxy(defaultAttributeFactory));
        }

        // set the default combining algorithm factory, if it exists here
        if (defaultCombiningFactory != null) {
            CombiningAlgFactory.setDefaultFactory(new CAFProxy(defaultCombiningFactory));
        }

        // set the default function factories, if they exists here
        if (defaultFunctionFactoryProxy != null)
            FunctionFactory.setDefaultFactory(defaultFunctionFactoryProxy);
    }

    /**
     *
     */
    class AFProxy implements AttributeFactoryProxy {
        private AttributeFactory factory;

        public AFProxy(AttributeFactory factory) {
            this.factory = factory;
        }

        public AttributeFactory getFactory() {
            return factory;
        }
    }

    /**
     *
     */
    class CAFProxy implements CombiningAlgFactoryProxy {
        private CombiningAlgFactory factory;

        public CAFProxy(CombiningAlgFactory factory) {
            this.factory = factory;
        }

        public CombiningAlgFactory getFactory() {
            return factory;
        }
    }

}
TOP

Related Classes of com.sun.xacml.ConfigurationStore$AFProxy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.