Package org.jboss.security.xacml.sunxacml

Source Code of org.jboss.security.xacml.sunxacml.ConfigurationStore$CAFProxy

/*
* @(#)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 org.jboss.security.xacml.sunxacml;






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

import org.jboss.security.xacml.sunxacml.attr.AttributeFactory;
import org.jboss.security.xacml.sunxacml.attr.AttributeFactoryProxy;
import org.jboss.security.xacml.sunxacml.attr.AttributeProxy;
import org.jboss.security.xacml.sunxacml.attr.BaseAttributeFactory;
import org.jboss.security.xacml.sunxacml.attr.StandardAttributeFactory;
import org.jboss.security.xacml.sunxacml.combine.BaseCombiningAlgFactory;
import org.jboss.security.xacml.sunxacml.combine.CombiningAlgFactory;
import org.jboss.security.xacml.sunxacml.combine.CombiningAlgFactoryProxy;
import org.jboss.security.xacml.sunxacml.combine.CombiningAlgorithm;
import org.jboss.security.xacml.sunxacml.combine.StandardCombiningAlgFactory;
import org.jboss.security.xacml.sunxacml.cond.BaseFunctionFactory;
import org.jboss.security.xacml.sunxacml.cond.BasicFunctionFactoryProxy;
import org.jboss.security.xacml.sunxacml.cond.Function;
import org.jboss.security.xacml.sunxacml.cond.FunctionFactory;
import org.jboss.security.xacml.sunxacml.cond.FunctionFactoryProxy;
import org.jboss.security.xacml.sunxacml.cond.FunctionProxy;
import org.jboss.security.xacml.sunxacml.cond.StandardFunctionFactory;
import org.jboss.security.xacml.sunxacml.cond.cluster.FunctionCluster;
import org.jboss.security.xacml.sunxacml.finder.AttributeFinder;
import org.jboss.security.xacml.sunxacml.finder.PolicyFinder;
import org.jboss.security.xacml.sunxacml.finder.ResourceFinder;
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 pdpConfigMap;

    // attribute factory elements
    private AttributeFactory defaultAttributeFactory;
    private HashMap attributeMap;

    // combining algorithm factory elements
    private CombiningAlgFactory defaultCombiningFactory;
    private HashMap combiningMap;

    // function factory elements
    private FunctionFactoryProxy defaultFunctionFactoryProxy;
    private HashMap 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();
        attributeMap = new HashMap();
        combiningMap = new HashMap();
        functionMap = new HashMap();

        // 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 = SunxacmlUtil.getNodeName(child);
            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 attrModules = new ArrayList();
        HashSet policyModules = new HashSet();
        ArrayList rsrcModules = new ArrayList();

        // 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 = SunxacmlUtil.getNodeName(child);

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

        // 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 (SunxacmlUtil.getNodeName(child).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 (SunxacmlUtil.getNodeName(child).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 = SunxacmlUtil.getNodeName(child);

            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 = SunxacmlUtil.getNodeName(child);

            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 it = cluster.getSupportedFunctions().iterator();
                while (it.hasNext()) {
                    try {
                        factory.addFunction((Function)(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
     */
    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 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) {
                    Iterator 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");

            // 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 getArgs(Node root) {
        List args = new ArrayList();
        NodeList children = root.getChildNodes();

        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            String name = SunxacmlUtil.getNodeName(child);
           
            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 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 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() {
        Iterator it = attributeMap.keySet().iterator();

        while (it.hasNext()) {
            String id = (String)(it.next());
            AttributeFactory af = (AttributeFactory)(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 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() {
        Iterator it = combiningMap.keySet().iterator();

        while (it.hasNext()) {
            String id = (String)(it.next());
            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 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() {
        Iterator it = functionMap.keySet().iterator();

        while (it.hasNext()) {
            String id = (String)(it.next());
            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 org.jboss.security.xacml.sunxacml.ConfigurationStore$CAFProxy

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.