From: <se...@us...> - 2004-02-13 17:58:04
|
Update of /cvsroot/sunxacml/sunxacml/com/sun/xacml/cond In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30760/com/sun/xacml/cond Modified Files: FunctionFactory.java Added Files: FunctionFactoryProxy.java Log Message: introducing new, pluggable, still unstable factory interfaces --- NEW FILE: FunctionFactoryProxy.java --- /* * @(#)FunctionFactoryProxy.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; /** * A simple proxy interface used to install new <code>FunctionFactory</code>s. * The three kinds of factory (Target, Condition, and General) are tied * together in this interface because implementors writing new factories * should always implement all three types and provide them together. * * @author Seth Proctor */ public interface FunctionFactoryProxy { /** * Returns the Target version of an instance of the * <code>FunctionFactory</code> for which this is a proxy. * * @return a <code>FunctionFactory</code> instance */ public FunctionFactory getTargetFactory(); /** * Returns the Condition version of an instance of the * <code>FunctionFactory</code> for which this is a proxy. * * @return a <code>FunctionFactory</code> instance */ public FunctionFactory getConditionFactory(); /** * Returns the General version of an instance of the * <code>FunctionFactory</code> for which this is a proxy. * * @return a <code>FunctionFactory</code> instance */ public FunctionFactory getGeneralFactory(); } Index: FunctionFactory.java =================================================================== RCS file: /cvsroot/sunxacml/sunxacml/com/sun/xacml/cond/FunctionFactory.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** FunctionFactory.java 27 Oct 2003 04:55:07 -0000 1.3 --- FunctionFactory.java 13 Feb 2004 17:52:14 -0000 1.4 *************** *** 3,7 **** * @(#)FunctionFactory.java * ! * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without --- 3,7 ---- * @(#)FunctionFactory.java * ! * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without *************** *** 40,226 **** 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; /** ! * Factory used to create all functions. There are three singleton factories: ! * a general factory, a condition factory, and a target factory, which provide ! * functions that can be used anywhere, only in a condition's root and only in ! * a target (respectively). The factories initially have all of the standard ! * XACML functions, and new functions can be added as needed. * <p> ! * Note that this factory is not thread safe, so care should be taken when ! * using this code in a multi-threaded application. Also note that all ! * functions, except for abstract functions, are singletons, so any instance ! * that is added to the factory will be the same one returned from the ! * create methods. This is done because most functions don't have state, so ! * there is no need to have more than one, or to spend the time creating ! * multiple instances that all do the same thing. * * @author Marco Barreno * @author Seth Proctor */ ! public class FunctionFactory { ! // 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; ! private static FunctionFactory conditionFactory = null; ! private static FunctionFactory generalFactory = null; ! ! // 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 names of the three types, used for error messages ! private static final String [] ! NAMES = { "Target", "Condition", "General" }; ! ! // the type of this instance ! private int factoryType; /** ! * Creates a new FunctionFactory, making sure that the default maps ! * are initialized correctly. */ ! private FunctionFactory(int which) { ! ! factoryType = which; ! ! // 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 (((which == CONDITION_FACTORY) || (which == 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 ((which == 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); - } - }); - } } /** ! * Returns a FunctionFactory that will only provide those functions that ! * are usable in Target matching. * * @return a <code>FunctionFactory</code> for target functions */ ! public static FunctionFactory getTargetInstance() { ! if (targetFactory == null) ! targetFactory = new FunctionFactory(TARGET_FACTORY); ! ! return targetFactory; } /** ! * 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 */ ! public static FunctionFactory getConditionInstance() { ! if (conditionFactory == null) ! conditionFactory = new FunctionFactory(CONDITION_FACTORY); ! ! return conditionFactory; } /** ! * 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 */ ! public static FunctionFactory getGeneralInstance() { ! if (generalFactory == null) ! generalFactory = new FunctionFactory(GENERAL_FACTORY); ! return generalFactory; } /** * Adds a target function. * * @param function the function to add * --- 40,175 ---- import com.sun.xacml.UnknownIdentifierException; import java.net.URI; import org.w3c.dom.Node; /** ! * Factory used to create all functions. There are three kinds of factories: ! * general, condition, and target. These provide functions that can be used ! * anywhere, only in a condition's root and only in a target (respectively). * <p> ! * Note that all functions, except for abstract functions, are singletons, so ! * any instance that is added to a factory will be the same one returned ! * from the create methods. This is done because most functions don't have ! * state, so there is no need to have more than one, or to spend the time ! * creating multiple instances that all do the same thing. * * @author Marco Barreno * @author Seth Proctor */ ! public abstract class FunctionFactory { ! // the proxies used to get the default factorys ! private static FunctionFactoryProxy defaultFactoryProxy; /** ! * static intialiazer that sets up the default factory proxies ! * NOTE: this will change when the right setup mechanism is in place */ ! static { ! defaultFactoryProxy = new FunctionFactoryProxy() { ! public FunctionFactory getTargetFactory() { ! return StandardFunctionFactory.getTargetFactory(); ! } ! public FunctionFactory getConditionFactory() { ! return StandardFunctionFactory.getConditionFactory(); ! } ! public FunctionFactory getGeneralFactory() { ! return StandardFunctionFactory.getGeneralFactory(); ! } ! }; ! }; ! /** ! * Default constructor. Used only by subclasses. ! */ ! protected FunctionFactory() { } /** ! * Returns the default FunctionFactory that will only provide those ! * functions that are usable in Target matching. * * @return a <code>FunctionFactory</code> for target functions */ ! public static final FunctionFactory getTargetInstance() { ! return defaultFactoryProxy.getTargetFactory(); } /** ! * Returns the default 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 */ ! public static final FunctionFactory getConditionInstance() { ! return defaultFactoryProxy.getConditionFactory(); } /** ! * Returns the default 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 */ ! public static final FunctionFactory getGeneralInstance() { ! return defaultFactoryProxy.getGeneralFactory(); ! } ! /** ! * Sets the default factory. Note that this is just a placeholder for ! * now, and will be replaced with a more useful mechanism soon. ! */ ! public static final void setDefaultFactory(FunctionFactoryProxy proxy) { ! defaultFactoryProxy = proxy; } /** + * 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 abstract void addFunction(Function function) + throws IllegalArgumentException; + + /** + * 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 abstract void addAbstractFunction(FunctionProxy proxy, + URI identity) + throws IllegalArgumentException; + + /** * Adds a target function. * + * @deprecated As of version 1.2, replaced by + * {@link #addFunction(Function)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * * @param function the function to add * *************** *** 230,234 **** throws IllegalArgumentException { ! addTargetFunctionHelper(function, function.getIdentifier()); } --- 179,183 ---- throws IllegalArgumentException { ! getTargetInstance().addFunction(function); } *************** *** 236,239 **** --- 185,196 ---- * Adds an abstract target function. * + * @deprecated As of version 1.2, replaced by + * {@link #addAbstractFunction(FunctionProxy,URI)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * * @param proxy the function proxy to add * @param identity the name of the function *************** *** 245,272 **** throws IllegalArgumentException { ! addTargetFunctionHelper(proxy, identity); ! } ! ! /** ! * Adds the given function, and makes sure all the other factories ! * also know about the new function. Throws an exception if the name ! * is already in use. ! */ ! private static void addTargetFunctionHelper(Object object, URI identity) ! throws IllegalArgumentException ! { ! // make sure that the single instance has been created ! getTargetInstance(); ! ! // make sure this doesn't already exist ! if (targetFunctionMap.containsKey(identity.toString())) ! throw new IllegalArgumentException("function already exists"); ! ! // next, add to the Condition list, since all Target functions are ! // also availabe as Condition functions ! addConditionFunctionHelper(object, identity); ! ! // finally, add it to our list ! targetFunctionMap.put(identity.toString(), object); } --- 202,206 ---- throws IllegalArgumentException { ! getTargetInstance().addAbstractFunction(proxy, identity); } *************** *** 274,277 **** --- 208,219 ---- * Adds a condition function. * + * @deprecated As of version 1.2, replaced by + * {@link #addFunction(Function)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * * @param function the function to add * *************** *** 281,285 **** throws IllegalArgumentException { ! addConditionFunctionHelper(function, function.getIdentifier()); } --- 223,227 ---- throws IllegalArgumentException { ! getConditionInstance().addFunction(function); } *************** *** 287,290 **** --- 229,240 ---- * Adds an abstract condition function. * + * @deprecated As of version 1.2, replaced by + * {@link #addAbstractFunction(FunctionProxy,URI)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * * @param proxy the function proxy to add * @param identity the name of the function *************** *** 296,323 **** throws IllegalArgumentException { ! addConditionFunctionHelper(proxy, identity); ! } ! ! /** ! * Adds the given function, and makes sure the general factory ! * also know about the new function. Throws an exception if the name ! * is already in use. ! */ ! private static void addConditionFunctionHelper(Object object, URI identity) ! throws IllegalArgumentException ! { ! // make sure that the single instance has been created ! getConditionInstance(); ! ! // make sure this doesn't already exist ! if (conditionFunctionMap.containsKey(identity.toString())) ! throw new IllegalArgumentException("function already exists"); ! ! // next, add to the General list, since all Condition functions are ! // also availabe as General functions ! addGeneralFunctionHelper(object, identity); ! ! // finally, add it to our list ! conditionFunctionMap.put(identity.toString(), object); } --- 246,250 ---- throws IllegalArgumentException { ! getConditionInstance().addAbstractFunction(proxy, identity); } *************** *** 325,328 **** --- 252,263 ---- * Adds a general function. * + * @deprecated As of version 1.2, replaced by + * {@link #addFunction(Function)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * * @param function the function to add * *************** *** 332,336 **** throws IllegalArgumentException { ! addGeneralFunctionHelper(function, function.getIdentifier()); } --- 267,271 ---- throws IllegalArgumentException { ! getGeneralInstance().addFunction(function); } *************** *** 338,341 **** --- 273,284 ---- * Adds an abstract general function. * + * @deprecated As of version 1.2, replaced by + * {@link #addAbstractFunction(FunctionProxy,URI)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * * @param proxy the function proxy to add * @param identity the name of the function *************** *** 347,369 **** throws IllegalArgumentException { ! addGeneralFunctionHelper(proxy, identity); ! } ! ! /** ! * Adds the given function. Throws an exception if the name is already ! * in use. ! */ ! private static void addGeneralFunctionHelper(Object object, URI identity) ! throws IllegalArgumentException ! { ! // make sure that the single instance has been created ! getGeneralInstance(); ! ! // make sure this doesn't already exist ! if (generalFunctionMap.containsKey(identity.toString())) ! throw new IllegalArgumentException("function already exists"); ! ! // now add it to our list ! generalFunctionMap.put(identity.toString(), object); } --- 290,294 ---- throws IllegalArgumentException { ! getGeneralInstance().addAbstractFunction(proxy, identity); } *************** *** 378,386 **** * be created through createAbstractFunction */ ! public Function createFunction(URI identity) ! throws UnknownIdentifierException, FunctionTypeException ! { ! return createFunction(identity.toString()); ! } /** --- 303,308 ---- * be created through createAbstractFunction */ ! public abstract Function createFunction(URI identity) ! throws UnknownIdentifierException, FunctionTypeException; /** *************** *** 394,417 **** * 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"); ! } ! } /** --- 316,321 ---- * be created through createAbstractFunction */ ! public abstract Function createFunction(String identity) ! throws UnknownIdentifierException, FunctionTypeException; /** *************** *** 428,437 **** * given inputs */ ! public Function createAbstractFunction(URI identity, Node root) throws UnknownIdentifierException, ParsingException, ! FunctionTypeException ! { ! return createAbstractFunction(identity.toString(), root, null); ! } /** --- 332,338 ---- * given inputs */ ! public abstract Function createAbstractFunction(URI identity, Node root) throws UnknownIdentifierException, ParsingException, ! FunctionTypeException; /** *************** *** 450,460 **** * given inputs */ ! public Function createAbstractFunction(URI identity, Node root, ! String xpathVersion) throws UnknownIdentifierException, ParsingException, ! FunctionTypeException ! { ! return createAbstractFunction(identity.toString(), root, xpathVersion); ! } /** --- 351,358 ---- * given inputs */ ! public abstract Function createAbstractFunction(URI identity, Node root, ! String xpathVersion) throws UnknownIdentifierException, ParsingException, ! FunctionTypeException; /** *************** *** 471,480 **** * given inputs */ ! public Function createAbstractFunction(String identity, Node root) throws UnknownIdentifierException, ParsingException, ! FunctionTypeException ! { ! return createAbstractFunction(identity, root, null); ! } /** --- 369,375 ---- * given inputs */ ! public abstract Function createAbstractFunction(String identity, Node root) throws UnknownIdentifierException, ParsingException, ! FunctionTypeException; /** *************** *** 493,541 **** * 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; ! } } --- 388,395 ---- * given inputs */ ! public abstract Function createAbstractFunction(String identity, Node root, ! String xpathVersion) throws UnknownIdentifierException, ParsingException, ! FunctionTypeException; } |