📄 configurationstore.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.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.PolicyFinder;
import com.sun.xacml.finder.ResourceFinder;
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.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 = 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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -