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