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