From: Seth P. <se...@us...> - 2004-03-15 21:44:04
|
Update of /cvsroot/sunxacml/sunxacml/com/sun/xacml/cond In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10845/com/sun/xacml/cond Modified Files: FunctionFactory.java StandardFunctionFactory.java Added Files: BaseFunctionFactory.java Log Message: setup new, more flexible factory scheme Index: StandardFunctionFactory.java =================================================================== RCS file: /cvsroot/sunxacml/sunxacml/com/sun/xacml/cond/StandardFunctionFactory.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** StandardFunctionFactory.java 13 Feb 2004 17:54:33 -0000 1.1 --- StandardFunctionFactory.java 15 Mar 2004 21:34:51 -0000 1.2 *************** *** 37,75 **** package com.sun.xacml.cond; ! import com.sun.xacml.ParsingException; ! import com.sun.xacml.UnknownIdentifierException; ! ! import com.sun.xacml.attr.BooleanAttribute; import java.net.URI; import java.net.URISyntaxException; - import java.util.Collection; import java.util.Iterator; - import java.util.HashMap; - - import org.w3c.dom.NamedNodeMap; - import org.w3c.dom.Node; /** * This factory supports the standard set of functions specified in XACML ! * 1.0 and 1.1. It is the default factory used by the system. * * @author Seth Proctor */ ! public class StandardFunctionFactory extends FunctionFactory { ! // internal identifiers for each of the three types private static final int TARGET_FACTORY = 0; private static final int CONDITION_FACTORY = 1; private static final int GENERAL_FACTORY = 2; - // the backing maps for the Function objects - private static HashMap targetFunctionMap = null; - private static HashMap conditionFunctionMap = null; - private static HashMap generalFunctionMap = null; - // the three singleton instances private static FunctionFactory targetFactory = null; --- 37,85 ---- package com.sun.xacml.cond; ! import com.sun.xacml.cond.cluster.AbsFunctionCluster; ! import com.sun.xacml.cond.cluster.AddFunctionCluster; ! import com.sun.xacml.cond.cluster.ComparisonFunctionCluster; ! import com.sun.xacml.cond.cluster.ConditionBagFunctionCluster; ! import com.sun.xacml.cond.cluster.ConditionSetFunctionCluster; ! import com.sun.xacml.cond.cluster.DateMathFunctionCluster; ! import com.sun.xacml.cond.cluster.DivideFunctionCluster; ! import com.sun.xacml.cond.cluster.EqualFunctionCluster; ! import com.sun.xacml.cond.cluster.FloorFunctionCluster; ! import com.sun.xacml.cond.cluster.GeneralBagFunctionCluster; ! import com.sun.xacml.cond.cluster.GeneralSetFunctionCluster; ! import com.sun.xacml.cond.cluster.HigherOrderFunctionCluster; ! import com.sun.xacml.cond.cluster.LogicalFunctionCluster; ! import com.sun.xacml.cond.cluster.MatchFunctionCluster; ! import com.sun.xacml.cond.cluster.ModFunctionCluster; ! import com.sun.xacml.cond.cluster.MultiplyFunctionCluster; ! import com.sun.xacml.cond.cluster.NOfFunctionCluster; ! import com.sun.xacml.cond.cluster.NotFunctionCluster; ! import com.sun.xacml.cond.cluster.NumericConvertFunctionCluster; ! import com.sun.xacml.cond.cluster.RoundFunctionCluster; ! import com.sun.xacml.cond.cluster.StringNormalizeFunctionCluster; ! import com.sun.xacml.cond.cluster.SubtractFunctionCluster; import java.net.URI; import java.net.URISyntaxException; import java.util.Iterator; /** * This factory supports the standard set of functions specified in XACML ! * 1.0 and 1.1. It is the default factory used by the system. Like the other ! * standard factories, there is only one instance used, so changing the ! * contents of one instance will affect all other instances. * * @author Seth Proctor */ ! public class StandardFunctionFactory extends BaseFunctionFactory { ! // internal identifiers for the three kinds of factories private static final int TARGET_FACTORY = 0; private static final int CONDITION_FACTORY = 1; private static final int GENERAL_FACTORY = 2; // the three singleton instances private static FunctionFactory targetFactory = null; *************** *** 77,90 **** private static FunctionFactory generalFactory = null; - /** - * A mapping of the three types from the *_FACTORY fields to their String - * representations. This is particularly useful for error messages. - */ - private static final String [] - NAMES = { "Target", "Condition", "General" }; - - // the type of this instance - private int factoryType; - // dummy object used as a lock for the getFactory routines // FIXME: this needs a better mechanism --- 87,90 ---- *************** *** 95,174 **** * maps are initialized correctly. */ ! private StandardFunctionFactory(int type) { ! factoryType = type; ! ! // first off, we always have to fill in the target map, since this ! // is the base that all three types use ! if (targetFunctionMap == null) { ! targetFunctionMap = new HashMap(); // add EqualFunction ! EqualFunction.addFunctions(targetFunctionMap); // add LogicalFunction ! LogicalFunction.addFunctions(targetFunctionMap); // add NOfFunction ! NOfFunction.addFunctions(targetFunctionMap); // add NotFunction ! NotFunction.addFunctions(targetFunctionMap); // add ComparisonFunction ! ComparisonFunction.addFunctions(targetFunctionMap); // add MatchFunction ! MatchFunction.addFunctions(targetFunctionMap); ! } ! ! // next, initialize the condition map if that's what kind we are (or ! // if we're a GENERAL, in which case we need all the functions) and if ! // it hasn't been initialized yet ! if (((type == CONDITION_FACTORY) || (type == GENERAL_FACTORY)) ! && (conditionFunctionMap == null)) { ! conditionFunctionMap = new HashMap(targetFunctionMap); ! // add condition functions from BagFunction ! BagFunction.addConditionFunctions(conditionFunctionMap); // add condition functions from SetFunction ! SetFunction.addConditionFunctions(conditionFunctionMap); // add condition functions from HigherOrderFunction ! HigherOrderFunction.addConditionFunctions(conditionFunctionMap); ! } ! ! // finally, initialize the general map if that's what kind we are and ! // if it hasn't been initialized yet ! if ((type == GENERAL_FACTORY) && (generalFunctionMap == null)) { ! generalFunctionMap = new HashMap(conditionFunctionMap); ! // add AddFunction ! AddFunction.addFunctions(generalFunctionMap); // add SubtractFunction ! SubtractFunction.addFunctions(generalFunctionMap); // add MultiplyFunction ! MultiplyFunction.addFunctions(generalFunctionMap); // add DivideFunction ! DivideFunction.addFunctions(generalFunctionMap); // add ModFunction ! ModFunction.addFunctions(generalFunctionMap); // add AbsFunction ! AbsFunction.addFunctions(generalFunctionMap); // add RoundFunction ! RoundFunction.addFunctions(generalFunctionMap); // add FloorFunction ! FloorFunction.addFunctions(generalFunctionMap); // add DateMathFunction ! DateMathFunction.addFunctions(generalFunctionMap); // add general functions from BagFunction ! BagFunction.addGeneralFunctions(generalFunctionMap); // add NumericConvertFunction ! NumericConvertFunction.addFunctions(generalFunctionMap); // add StringNormalizeFunction ! StringNormalizeFunction.addFunctions(generalFunctionMap); // add general functions from SetFunction ! SetFunction.addGeneralFunctions(generalFunctionMap); ! // add the map function ! generalFunctionMap.put(MapFunction.NAME, new FunctionProxy() { ! public Function getInstance(Node root, String xpathVersion) ! throws Exception { ! return MapFunction.getInstance(root); ! } ! }); } } --- 95,189 ---- * maps are initialized correctly. */ ! private StandardFunctionFactory(int type, FunctionFactory superset) { ! super(superset); + switch (type) { + case TARGET_FACTORY: // add EqualFunction ! addFunctions((new EqualFunctionCluster()).getSupportedFunctions(). ! iterator()); // add LogicalFunction ! addFunctions((new LogicalFunctionCluster()). ! getSupportedFunctions().iterator()); // add NOfFunction ! addFunctions((new NOfFunctionCluster()).getSupportedFunctions(). ! iterator()); // add NotFunction ! addFunctions((new NotFunctionCluster()).getSupportedFunctions(). ! iterator()); // add ComparisonFunction ! addFunctions((new ComparisonFunctionCluster()). ! getSupportedFunctions().iterator()); // add MatchFunction ! addFunctions((new MatchFunctionCluster()).getSupportedFunctions(). ! iterator()); ! break; ! case CONDITION_FACTORY: // add condition functions from BagFunction ! addFunctions((new ConditionBagFunctionCluster()). ! getSupportedFunctions().iterator()); // add condition functions from SetFunction ! addFunctions((new ConditionSetFunctionCluster()). ! getSupportedFunctions().iterator()); // add condition functions from HigherOrderFunction ! addFunctions((new HigherOrderFunctionCluster()). ! getSupportedFunctions().iterator()); ! break; ! case GENERAL_FACTORY: // add AddFunction ! addFunctions((new AddFunctionCluster()).getSupportedFunctions(). ! iterator()); // add SubtractFunction ! addFunctions((new SubtractFunctionCluster()). ! getSupportedFunctions().iterator()); // add MultiplyFunction ! addFunctions((new MultiplyFunctionCluster()). ! getSupportedFunctions().iterator()); // add DivideFunction ! addFunctions((new DivideFunctionCluster()).getSupportedFunctions(). ! iterator()); // add ModFunction ! addFunctions((new ModFunctionCluster()).getSupportedFunctions(). ! iterator()); // add AbsFunction ! addFunctions((new AbsFunctionCluster()).getSupportedFunctions(). ! iterator()); // add RoundFunction ! addFunctions((new RoundFunctionCluster()).getSupportedFunctions(). ! iterator()); // add FloorFunction ! addFunctions((new FloorFunctionCluster()).getSupportedFunctions(). ! iterator()); // add DateMathFunction ! addFunctions((new DateMathFunctionCluster()). ! getSupportedFunctions().iterator()); // add general functions from BagFunction ! addFunctions((new GeneralBagFunctionCluster()). ! getSupportedFunctions().iterator()); // add NumericConvertFunction ! addFunctions((new NumericConvertFunctionCluster()). ! getSupportedFunctions().iterator()); // add StringNormalizeFunction ! addFunctions((new StringNormalizeFunctionCluster()). ! getSupportedFunctions().iterator()); // add general functions from SetFunction ! addFunctions((new GeneralSetFunctionCluster()). ! getSupportedFunctions().iterator()); ! ! // add the map function's proxy ! try { ! addAbstractFunction(new MapFunctionProxy(), ! new URI(MapFunction.NAME)); ! } catch (URISyntaxException e) { ! // this shouldn't ever happen, but just in case... ! throw new IllegalArgumentException("invalid function name"); ! } ! break; ! } ! } ! private void addFunctions(Iterator it) { ! while (it.hasNext()) { ! addFunction((Function)(it.next())); } } *************** *** 176,180 **** /** * Returns a FunctionFactory that will only provide those functions that ! * are usable in Target matching. * * @return a <code>FunctionFactory</code> for target functions --- 191,200 ---- /** * Returns a FunctionFactory that will only provide those functions that ! * are usable in Target matching. This method enforces a singleton ! * model, meaning that this always returns the same instance, creating ! * the factory if it hasn't been requested before. This is the default ! * model used by the <code>FunctionFactory</code>, ensuring quick ! * access to this factory. If you need a new instance of this factory ! * you should use the <code>getNewFactory</code> method. * * @return a <code>FunctionFactory</code> for target functions *************** *** 184,189 **** synchronized (factoryLock) { if (targetFactory == null) ! targetFactory = ! new StandardFunctionFactory(TARGET_FACTORY); } } --- 204,208 ---- synchronized (factoryLock) { if (targetFactory == null) ! setupFactories(); } } *************** *** 194,199 **** /** * Returns a FuntionFactory that will only provide those functions that ! * are usable in the root of the Condition. These Functions are a superset ! * of the Target functions. * * @return a <code>FunctionFactory</code> for condition functions --- 213,223 ---- /** * Returns a FuntionFactory that will only provide those functions that ! * are usable in the root of the Condition. These Functions are a ! * superset of the Target functions. This method enforces a singleton ! * model, meaning that this always returns the same instance, creating ! * the factory if it hasn't been requested before. This is the default ! * model used by the <code>FunctionFactory</code>, ensuring quick ! * access to this factory. If you need a new instance of this factory ! * you should use the <code>getNewFactory</code> method. * * @return a <code>FunctionFactory</code> for condition functions *************** *** 203,208 **** synchronized (factoryLock) { if (conditionFactory == null) ! conditionFactory = ! new StandardFunctionFactory(CONDITION_FACTORY); } } --- 227,231 ---- synchronized (factoryLock) { if (conditionFactory == null) ! setupFactories(); } } *************** *** 213,217 **** /** * Returns a FunctionFactory that provides access to all the functions. ! * These Functions are a superset of the Condition functions. * * @return a <code>FunctionFactory</code> for all functions --- 236,245 ---- /** * Returns a FunctionFactory that provides access to all the functions. ! * These Functions are a superset of the Condition functions. This method ! * enforces a singleton model, meaning that this always returns the same ! * instance, creating the factory if it hasn't been requested before. ! * This is the default model used by the <code>FunctionFactory</code>, ! * ensuring quick access to this factory. If you need a new instance of ! * this factory you should use the <code>getNewFactory</code> method. * * @return a <code>FunctionFactory</code> for all functions *************** *** 221,226 **** synchronized (factoryLock) { if (generalFactory == null) ! generalFactory = ! new StandardFunctionFactory(GENERAL_FACTORY); } } --- 249,253 ---- synchronized (factoryLock) { if (generalFactory == null) ! setupFactories(); } } *************** *** 230,519 **** /** ! * Adds the function to the factory. Most functions have no state, so ! * the singleton model used here is typically desireable. The factory will ! * enforce the requirement that a Target or Condition matching function ! * must be boolean. ! * ! * @param function the <code>Function</code> to add to the factory ! * ! * @throws IllegalArgumentException if the function's identifier is already ! * used or if the function is non-boolean ! * (when this is a Target or Condition ! * factory) ! */ ! public void addFunction(Function function) ! throws IllegalArgumentException ! { ! addFunctionHelper(function, function.getIdentifier()); ! } ! ! /** ! * Adds the abstract function proxy to the factory. This is used for ! * those functions which have state, or change behavior (for instance ! * the standard map function, which changes its return type based on ! * how it is used). ! * ! * @param proxy the <code>FunctionProxy</code> to add to the factory ! * @param identity the function's identifier ! * ! * @throws IllegalArgumentException if the function's identifier is already ! * used ! */ ! public void addAbstractFunction(FunctionProxy proxy, ! URI identity) ! throws IllegalArgumentException ! { ! addFunctionHelper(proxy, identity); ! } ! ! /** ! * This is the first of 4 basic helpers used by the function addition ! * code. This method picks the right starting point based on what kind ! * of factory this is. ! */ ! private void addFunctionHelper(Object object, URI identity) { ! String id = identity.toString(); ! ! switch (factoryType) { ! case TARGET_FACTORY: ! addTargetFunctionHelper(object, id); ! break; ! case CONDITION_FACTORY: ! addConditionFunctionHelper(object, id); ! break; ! case GENERAL_FACTORY: ! addGeneralFunctionHelper(object, id); ! break; ! } ! } ! ! /** ! * Adds the function or proxy to the Target map if it can be added to ! * the other maps as well and if it's not already in the Target map. ! */ ! private void addTargetFunctionHelper(Object object, String id) ! throws IllegalArgumentException ! { ! // make sure this doesn't already exist ! if (targetFunctionMap.containsKey(id)) ! throw new IllegalArgumentException("function already exists"); ! ! // next, add to the Condition list, since all Target functions are ! // also availabe as Condition functions ! addConditionFunctionHelper(object, id); ! ! // finally, add it to our list ! targetFunctionMap.put(id, object); ! } ! ! /** ! * Adds the function or proxy to the Condition map if it can be added to ! * the General map as well and if it's not already in the Condition map. ! */ ! private void addConditionFunctionHelper(Object object, String id) ! throws IllegalArgumentException ! { ! // in case we haven't created the Condition factory, do it now ! getConditionFactory(); ! ! // make sure this doesn't already exist ! if (conditionFunctionMap.containsKey(id)) ! throw new IllegalArgumentException("function already exists"); ! ! // next, add to the General list, since all Condition functions are ! // also availabe as General functions ! addGeneralFunctionHelper(object, id); ! ! // finally, add it to our list ! conditionFunctionMap.put(id, object); ! } ! ! /** ! * Adds the function or proxy to the General map if it's not already in ! * that map. ! */ ! private void addGeneralFunctionHelper(Object object, String id) ! throws IllegalArgumentException ! { ! // in case we haven't created the General factory, do it now ! getGeneralFactory(); ! ! // make sure this doesn't already exist ! if (generalFunctionMap.containsKey(id)) ! throw new IllegalArgumentException("function already exists"); ! ! // now add it to our list ! generalFunctionMap.put(id, object); ! } ! ! /** ! * Tries to get an instance of the specified function. ! * ! * @param identity the name of the function ! * ! * @throws UnknownIdentifierException if the name isn't known ! * @throws FunctionTypeException if the name is known to map to an ! * abstract function, and should therefore ! * be created through createAbstractFunction ! */ ! public Function createFunction(URI identity) ! throws UnknownIdentifierException, FunctionTypeException ! { ! return createFunction(identity.toString()); ! } ! ! /** ! * Tries to get an instance of the specified function. ! * ! * @param identity the name of the function ! * ! * @throws UnknownIdentifierException if the name isn't known ! * @throws FunctionTypeException if the name is known to map to an ! * abstract function, and should therefore ! * be created through createAbstractFunction ! */ ! public Function createFunction(String identity) ! throws UnknownIdentifierException, FunctionTypeException ! { ! Object entry = createFunctionHelper(identity); ! ! if (entry != null) { ! if (entry instanceof Function) { ! return (Function)entry; ! } else { ! // this is actually a proxy, which means the other create ! // method should have been called ! throw new FunctionTypeException("function is abstract"); ! } ! } else { ! // we couldn't find a match ! throw new UnknownIdentifierException(NAMES[factoryType] + ! " functions of type " + ! identity + " not supported"); ! } ! } ! ! /** ! * Tries to get an instance of the specified abstract function. ! * ! * @param identity the name of the function ! * @param root the DOM root containing info used to create the function ! * ! * @throws UnknownIdentifierException if the name isn't known ! * @throws FunctionTypeException if the name is known to map to a ! * concrete function, and should therefore ! * be created through createFunction ! * @throws ParsingException if the function can't be created with the ! * given inputs ! */ ! public Function createAbstractFunction(URI identity, Node root) ! throws UnknownIdentifierException, ParsingException, ! FunctionTypeException ! { ! return createAbstractFunction(identity.toString(), root, null); ! } ! ! /** ! * Tries to get an instance of the specified abstract function. ! * ! * @param identity the name of the function ! * @param root the DOM root containing info used to create the function ! * @param xpathVersion the version specified in the contianing policy, or ! * null if no version was specified ! * ! * @throws UnknownIdentifierException if the name isn't known ! * @throws FunctionTypeException if the name is known to map to a ! * concrete function, and should therefore ! * be created through createFunction ! * @throws ParsingException if the function can't be created with the ! * given inputs ! */ ! public Function createAbstractFunction(URI identity, Node root, ! String xpathVersion) ! throws UnknownIdentifierException, ParsingException, ! FunctionTypeException ! { ! return createAbstractFunction(identity.toString(), root, xpathVersion); ! } ! ! /** ! * Tries to get an instance of the specified abstract function. ! * ! * @param identity the name of the function ! * @param root the DOM root containing info used to create the function ! * ! * @throws UnknownIdentifierException if the name isn't known ! * @throws FunctionTypeException if the name is known to map to a ! * concrete function, and should therefore ! * be created through createFunction ! * @throws ParsingException if the function can't be created with the ! * given inputs */ ! public Function createAbstractFunction(String identity, Node root) ! throws UnknownIdentifierException, ParsingException, ! FunctionTypeException ! { ! return createAbstractFunction(identity, root, null); ! } ! /** ! * Tries to get an instance of the specified abstract function. ! * ! * @param identity the name of the function ! * @param root the DOM root containing info used to create the function ! * @param xpathVersion the version specified in the contianing policy, or ! * null if no version was specified ! * ! * @throws UnknownIdentifierException if the name isn't known ! * @throws FunctionTypeException if the name is known to map to a ! * concrete function, and should therefore ! * be created through createFunction ! * @throws ParsingException if the function can't be created with the ! * given inputs ! */ ! public Function createAbstractFunction(String identity, Node root, ! String xpathVersion) ! throws UnknownIdentifierException, ParsingException, ! FunctionTypeException ! { ! Object entry = createFunctionHelper(identity); ! ! if (entry != null) { ! if (entry instanceof FunctionProxy) { ! try { ! return ((FunctionProxy)entry).getInstance(root, ! xpathVersion); ! } catch (Exception e) { ! throw new ParsingException("couldn't create abstract" + ! " function " + identity, e); ! } ! } else { ! // this is actually a concrete function, which means that ! // the other create method should have been called ! throw new FunctionTypeException("function is concrete"); ! } ! } else { ! // we couldn't find a match ! throw new UnknownIdentifierException(NAMES[factoryType] + ! " abstract functions of " + ! "type " + identity + ! " not supported"); ! } } /** ! * Looks in the right map for the given key */ ! private Object createFunctionHelper(String identity) { ! switch (factoryType) { ! case TARGET_FACTORY: ! return targetFunctionMap.get(identity); ! case CONDITION_FACTORY: ! return conditionFunctionMap.get(identity); ! case GENERAL_FACTORY: ! return generalFunctionMap.get(identity); ! } ! ! return null; } --- 257,284 ---- /** ! * Returns a new instance of <code>FunctionFactoryProxy</code> with ! * new factories that support all the standard functions. */ ! public static FunctionFactoryProxy getNewFactory() { ! StandardFunctionFactory general = ! new StandardFunctionFactory(GENERAL_FACTORY, null); ! StandardFunctionFactory condition = ! new StandardFunctionFactory(CONDITION_FACTORY, general); ! StandardFunctionFactory target = ! new StandardFunctionFactory(TARGET_FACTORY, condition); ! return new BasicFunctionFactoryProxy(target, condition, general); } /** ! * Private helper that sets up the three factory instances with the ! * right dependencies on each other. */ ! private static void setupFactories() { ! generalFactory = new StandardFunctionFactory(GENERAL_FACTORY, null); ! conditionFactory = new StandardFunctionFactory(CONDITION_FACTORY, ! generalFactory); ! targetFactory = new StandardFunctionFactory(TARGET_FACTORY, ! conditionFactory); } Index: FunctionFactory.java =================================================================== RCS file: /cvsroot/sunxacml/sunxacml/com/sun/xacml/cond/FunctionFactory.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** FunctionFactory.java 13 Feb 2004 17:52:14 -0000 1.4 --- FunctionFactory.java 15 Mar 2004 21:34:51 -0000 1.5 *************** *** 132,136 **** * Adds the function to the factory. Most functions have no state, so * the singleton model used here is typically desireable. The factory will ! * enforce the requirement that a Target or Condition matching function * must be boolean. * --- 132,136 ---- * Adds the function to the factory. Most functions have no state, so * the singleton model used here is typically desireable. The factory will ! * not enforce the requirement that a Target or Condition matching function * must be boolean. * *************** *** 138,147 **** * * @throws IllegalArgumentException if the function's identifier is already ! * used or if the function is non-boolean ! * (when this is a Target or Condition ! * factory) */ ! public abstract void addFunction(Function function) ! throws IllegalArgumentException; /** --- 138,144 ---- * * @throws IllegalArgumentException if the function's identifier is already ! * used */ ! public abstract void addFunction(Function function); /** *************** *** 158,163 **** */ public abstract void addAbstractFunction(FunctionProxy proxy, ! URI identity) ! throws IllegalArgumentException; /** --- 155,159 ---- */ public abstract void addAbstractFunction(FunctionProxy proxy, ! URI identity); /** *************** *** 176,182 **** * @throws IllegalArgumentException if the name is already in use */ ! public static void addTargetFunction(Function function) ! throws IllegalArgumentException ! { getTargetInstance().addFunction(function); } --- 172,176 ---- * @throws IllegalArgumentException if the name is already in use */ ! public static void addTargetFunction(Function function) { getTargetInstance().addFunction(function); } *************** *** 199,205 **** */ public static void addAbstractTargetFunction(FunctionProxy proxy, ! URI identity) ! throws IllegalArgumentException ! { getTargetInstance().addAbstractFunction(proxy, identity); } --- 193,197 ---- */ public static void addAbstractTargetFunction(FunctionProxy proxy, ! URI identity) { getTargetInstance().addAbstractFunction(proxy, identity); } *************** *** 220,226 **** * @throws IllegalArgumentException if the name is already in use */ ! public static void addConditionFunction(Function function) ! throws IllegalArgumentException ! { getConditionInstance().addFunction(function); } --- 212,216 ---- * @throws IllegalArgumentException if the name is already in use */ ! public static void addConditionFunction(Function function) { getConditionInstance().addFunction(function); } *************** *** 243,249 **** */ public static void addAbstractConditionFunction(FunctionProxy proxy, ! URI identity) ! throws IllegalArgumentException ! { getConditionInstance().addAbstractFunction(proxy, identity); } --- 233,237 ---- */ public static void addAbstractConditionFunction(FunctionProxy proxy, ! URI identity) { getConditionInstance().addAbstractFunction(proxy, identity); } *************** *** 264,270 **** * @throws IllegalArgumentException if the name is already in use */ ! public static void addGeneralFunction(Function function) ! throws IllegalArgumentException ! { getGeneralInstance().addFunction(function); } --- 252,256 ---- * @throws IllegalArgumentException if the name is already in use */ ! public static void addGeneralFunction(Function function) { getGeneralInstance().addFunction(function); } *************** *** 287,293 **** */ public static void addAbstractGeneralFunction(FunctionProxy proxy, ! URI identity) ! throws IllegalArgumentException ! { getGeneralInstance().addAbstractFunction(proxy, identity); } --- 273,277 ---- */ public static void addAbstractGeneralFunction(FunctionProxy proxy, ! URI identity) { getGeneralInstance().addAbstractFunction(proxy, identity); } --- NEW FILE: BaseFunctionFactory.java --- /* * @(#)BaseCombiningAlgFactory.java * * Copyright 2004 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.cond; import com.sun.xacml.ParsingException; import com.sun.xacml.UnknownIdentifierException; import java.net.URI; import java.util.HashMap; import org.w3c.dom.Node; /** * This is a basic implementation of <code>FunctionFactory</code>. It * implements the insertion and retrieval methods, but it doesn't actually * setup the factory with any functions. It also assumes a certain model * with regard to the different kinds of functions (Target, Condition, and * General). For this reason, you may want to re-use this class, or you * may want to extend FunctionFactory directly, if you're writing a new * factory implementation. * * @author Seth Proctor */ public class BaseFunctionFactory extends FunctionFactory { // the backing maps for the Function objects private HashMap functionMap = null; // the superset factory chained to this factory private FunctionFactory superset = null; /** * Default constructor. No superset factory is used. */ public BaseFunctionFactory() { this(null); } /** * Constructor that sets a "superset factory." This is useful since * the different function factories (Target, Condition, and General) * have a superset relationship (Condition functions are a superset * of Target functions, etc.). Adding a function to this factory will * automatically add the same function to the superset factory. * * @param superset the superset factory or null */ public BaseFunctionFactory(FunctionFactory superset) { functionMap = new HashMap(); this.superset = superset; } /** * Adds the function to the factory. Most functions have no state, so * the singleton model used here is typically desireable. The factory will * not enforce the requirement that a Target or Condition matching function * must be boolean. * * @param function the <code>Function</code> to add to the factory * * @throws IllegalArgumentException if the function's identifier is already * used or if the function is non-boolean * (when this is a Target or Condition * factory) */ public void addFunction(Function function) throws IllegalArgumentException { String id = function.getIdentifier().toString(); // make sure this doesn't already exist if (functionMap.containsKey(id)) throw new IllegalArgumentException("function already exists"); // add to the superset factory if (superset != null) superset.addFunction(function); // finally, add to this factory functionMap.put(id, function); } /** * Adds the abstract function proxy to the factory. This is used for * those functions which have state, or change behavior (for instance * the standard map function, which changes its return type based on * how it is used). * * @param proxy the <code>FunctionProxy</code> to add to the factory * @param identity the function's identifier * * @throws IllegalArgumentException if the function's identifier is already * used */ public void addAbstractFunction(FunctionProxy proxy, URI identity) throws IllegalArgumentException { String id = identity.toString(); // make sure this doesn't already exist if (functionMap.containsKey(id)) throw new IllegalArgumentException("function already exists"); // add to the superset factory if (superset != null) superset.addAbstractFunction(proxy, identity); // finally, add to this factory functionMap.put(id, proxy); } /** * Tries to get an instance of the specified function. * * @param identity the name of the function * * @throws UnknownIdentifierException if the name isn't known * @throws FunctionTypeException if the name is known to map to an * abstract function, and should therefore * be created through createAbstractFunction */ public Function createFunction(URI identity) throws UnknownIdentifierException, FunctionTypeException { return createFunction(identity.toString()); } /** * Tries to get an instance of the specified function. * * @param identity the name of the function * * @throws UnknownIdentifierException if the name isn't known * @throws FunctionTypeException if the name is known to map to an * abstract function, and should therefore * be created through createAbstractFunction */ public Function createFunction(String identity) throws UnknownIdentifierException, FunctionTypeException { Object entry = functionMap.get(identity); if (entry != null) { if (entry instanceof Function) { return (Function)entry; } else { // this is actually a proxy, which means the other create // method should have been called throw new FunctionTypeException("function is abstract"); } } else { // we couldn't find a match throw new UnknownIdentifierException("functions of type " + identity + " are not "+ "supported by this factory"); } } /** * Tries to get an instance of the specified abstract function. * * @param identity the name of the function * @param root the DOM root containing info used to create the function * * @throws UnknownIdentifierException if the name isn't known * @throws FunctionTypeException if the name is known to map to a * concrete function, and should therefore * be created through createFunction * @throws ParsingException if the function can't be created with the * given inputs */ public Function createAbstractFunction(URI identity, Node root) throws UnknownIdentifierException, ParsingException, FunctionTypeException { return createAbstractFunction(identity.toString(), root, null); } /** * Tries to get an instance of the specified abstract function. * * @param identity the name of the function * @param root the DOM root containing info used to create the function * @param xpathVersion the version specified in the contianing policy, or * null if no version was specified * * @throws UnknownIdentifierException if the name isn't known * @throws FunctionTypeException if the name is known to map to a * concrete function, and should therefore * be created through createFunction * @throws ParsingException if the function can't be created with the * given inputs */ public Function createAbstractFunction(URI identity, Node root, String xpathVersion) throws UnknownIdentifierException, ParsingException, FunctionTypeException { return createAbstractFunction(identity.toString(), root, xpathVersion); } /** * Tries to get an instance of the specified abstract function. * * @param identity the name of the function * @param root the DOM root containing info used to create the function * * @throws UnknownIdentifierException if the name isn't known * @throws FunctionTypeException if the name is known to map to a * concrete function, and should therefore * be created through createFunction * @throws ParsingException if the function can't be created with the * given inputs */ public Function createAbstractFunction(String identity, Node root) throws UnknownIdentifierException, ParsingException, FunctionTypeException { return createAbstractFunction(identity, root, null); } /** * Tries to get an instance of the specified abstract function. * * @param identity the name of the function * @param root the DOM root containing info used to create the function * @param xpathVersion the version specified in the contianing policy, or * null if no version was specified * * @throws UnknownIdentifierException if the name isn't known * @throws FunctionTypeException if the name is known to map to a * concrete function, and should therefore * be created through createFunction * @throws ParsingException if the function can't be created with the * given inputs */ public Function createAbstractFunction(String identity, Node root, String xpathVersion) throws UnknownIdentifierException, ParsingException, FunctionTypeException { Object entry = functionMap.get(identity); if (entry != null) { if (entry instanceof FunctionProxy) { try { return ((FunctionProxy)entry).getInstance(root, xpathVersion); } catch (Exception e) { throw new ParsingException("couldn't create abstract" + " function " + identity, e); } } else { // this is actually a concrete function, which means that // the other create method should have been called throw new FunctionTypeException("function is concrete"); } } else { // we couldn't find a match throw new UnknownIdentifierException("abstract functions of " + "type " + identity + " are not supported by " + "this factory"); } } } |