From: Seth P. <se...@us...> - 2005-01-07 23:46:44
|
Update of /cvsroot/sunxacml/sunxacml/com/sun/xacml In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16789/com/sun/xacml Modified Files: AbstractPolicy.java Policy.java PolicySet.java Log Message: added core support for policy versioning, variable referencing, and combining algorithm parameters, three of the major new features in XACML 2.0 Index: PolicySet.java =================================================================== RCS file: /cvsroot/sunxacml/sunxacml/com/sun/xacml/PolicySet.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** PolicySet.java 17 Mar 2004 18:03:37 -0000 1.5 --- PolicySet.java 7 Jan 2005 23:46:33 -0000 1.6 *************** *** 3,7 **** * @(#)PolicySet.java * ! * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without --- 3,7 ---- * @(#)PolicySet.java * ! * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without *************** *** 37,40 **** --- 37,42 ---- package com.sun.xacml; + import com.sun.xacml.combine.CombinerParameter; + import com.sun.xacml.combine.PolicyCombinerElement; import com.sun.xacml.combine.PolicyCombiningAlgorithm; *************** *** 49,52 **** --- 51,55 ---- import java.util.ArrayList; + import java.util.HashMap; import java.util.Iterator; import java.util.List; *************** *** 79,83 **** public PolicySet(URI id, PolicyCombiningAlgorithm combiningAlg, Target target) { ! this(id, combiningAlg, null, target, null, null, null); } --- 82,86 ---- public PolicySet(URI id, PolicyCombiningAlgorithm combiningAlg, Target target) { ! this(id, null, combiningAlg, null, target, null, null, null); } *************** *** 98,122 **** public PolicySet(URI id, PolicyCombiningAlgorithm combiningAlg, Target target, List policies) { ! this(id, combiningAlg, null, target, policies, null, null); ! } ! ! /** ! * Creates a new <code>PolicySet</code> with the required elements plus ! * some policies and policy defaults. ! * ! * @param id the policy set identifier ! * @param combiningAlg the <code>CombiningAlgorithm</code> used on the ! * policies in this set ! * @param target the <code>Target</code> for this set ! * @param policies a list of <code>AbstractPolicy</code> objects ! * @param defaultVersion the XPath version to use ! * ! * @throws IllegalArgumentException if the <code>List</code> of policies ! * contains an object that is not an ! * <code>AbstractPolicy</code> ! */ ! public PolicySet(URI id, PolicyCombiningAlgorithm combiningAlg, ! Target target, List policies, String defaultVersion) { ! this(id, combiningAlg, null, target, policies, defaultVersion, null); } --- 101,105 ---- public PolicySet(URI id, PolicyCombiningAlgorithm combiningAlg, Target target, List policies) { ! this(id, null, combiningAlg, null, target, policies, null, null); } *************** *** 126,129 **** --- 109,114 ---- * * @param id the policy set identifier + * @param version the policy version or null for the default (this is + * always null for pre-2.0 policies) * @param combiningAlg the <code>CombiningAlgorithm</code> used on the * policies in this set *************** *** 136,142 **** * <code>AbstractPolicy</code> */ ! public PolicySet(URI id, PolicyCombiningAlgorithm combiningAlg, String description, Target target, List policies) { ! this(id, combiningAlg, description, target, policies, null, null); } --- 121,129 ---- * <code>AbstractPolicy</code> */ ! public PolicySet(URI id, String version, ! PolicyCombiningAlgorithm combiningAlg, String description, Target target, List policies) { ! this(id, version, combiningAlg, description, target, policies, null, ! null); } *************** *** 146,149 **** --- 133,138 ---- * * @param id the policy set identifier + * @param version the policy version or null for the default (this is + * always null for pre-2.0 policies) * @param combiningAlg the <code>CombiningAlgorithm</code> used on the * policies in this set *************** *** 157,165 **** * <code>AbstractPolicy</code> */ ! public PolicySet(URI id, PolicyCombiningAlgorithm combiningAlg, String description, Target target, List policies, String defaultVersion) { ! this(id, combiningAlg, description, target, policies, defaultVersion, ! null); } --- 146,155 ---- * <code>AbstractPolicy</code> */ ! public PolicySet(URI id, String version, ! PolicyCombiningAlgorithm combiningAlg, String description, Target target, List policies, String defaultVersion) { ! this(id, version, combiningAlg, description, target, policies, ! defaultVersion, null); } *************** *** 169,172 **** --- 159,164 ---- * * @param id the policy set identifier + * @param version the policy version or null for the default (this is + * always null for pre-2.0 policies) * @param combiningAlg the <code>CombiningAlgorithm</code> used on the * policies in this set *************** *** 181,192 **** * <code>AbstractPolicy</code> */ ! public PolicySet(URI id, PolicyCombiningAlgorithm combiningAlg, String description, Target target, List policies, String defaultVersion, Set obligations) { ! super(id, combiningAlg, description, target, defaultVersion, ! obligations); // check that the list contains only AbstractPolicy objects if (policies != null) { Iterator it = policies.iterator(); while (it.hasNext()) { --- 173,188 ---- * <code>AbstractPolicy</code> */ ! public PolicySet(URI id, String version, ! PolicyCombiningAlgorithm combiningAlg, String description, Target target, List policies, String defaultVersion, Set obligations) { ! super(id, version, combiningAlg, description, target, defaultVersion, ! obligations, null); ! ! List list = null; // check that the list contains only AbstractPolicy objects if (policies != null) { + list = new ArrayList(); Iterator it = policies.iterator(); while (it.hasNext()) { *************** *** 195,205 **** throw new IllegalArgumentException("non-AbstractPolicy " + "in policies"); } } ! setChildren(policies); } /** * Creates a new PolicySet based on the given root node. This is * private since every class is supposed to use a getInstance() method --- 191,253 ---- throw new IllegalArgumentException("non-AbstractPolicy " + "in policies"); + list.add(new PolicyCombinerElement((AbstractPolicy)o)); } } ! setChildren(list); } /** + * Creates a new <code>PolicySet</code> with the required and optional + * elements. If you need to provide combining algorithm parameters, you + * need to use this constructor. Note that unlike the other constructors + * in this class, the policies list is actually a list of + * <code>CombinerElement</code>s used to match a policy with any + * combiner parameters it may have. + * + * @param id the policy set identifier + * @param version the policy version or null for the default (this is + * always null for pre-2.0 policies) + * @param combiningAlg the <code>CombiningAlgorithm</code> used on the + * rules in this set + * @param description a <code>String</code> describing the policy or + * null if there is no description + * @param target the <code>Target</code> for this policy + * @param policyElements a list of <code>CombinerElement</code> objects or + * null if there are no policies + * @param defaultVersion the XPath version to use or null if there is + * no default version + * @param obligations a set of <code>Obligations</code> objects or null + * if there are no obligations + * @param parameters the <code>List</code> of + * <code>CombinerParameter</code>s provided for general + * use by the combining algorithm + * + * @throws IllegalArgumentException if the <code>List</code> of rules + * contains an object that is not a + * <code>Rule</code> + */ + public PolicySet(URI id, String version, + PolicyCombiningAlgorithm combiningAlg, + String description, Target target, List policyElements, + String defaultVersion, Set obligations, List parameters) { + super(id, version, combiningAlg, description, target, defaultVersion, + obligations, parameters); + + // check that the list contains only CombinerElements + if (policyElements != null) { + Iterator it = policyElements.iterator(); + while (it.hasNext()) { + Object o = it.next(); + if (! (o instanceof PolicyCombinerElement)) + throw new IllegalArgumentException("non-AbstractPolicy " + + "in policies"); + } + } + + setChildren(policyElements); + } + + /** * Creates a new PolicySet based on the given root node. This is * private since every class is supposed to use a getInstance() method *************** *** 211,215 **** --- 259,266 ---- List policies = new ArrayList(); + HashMap policyParameters = new HashMap(); + HashMap policySetParameters = new HashMap(); + // collect the PolicySet-specific elements NodeList children = root.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { *************** *** 225,232 **** } else if (name.equals("PolicyIdReference")) { policies.add(PolicyReference.getInstance(child, finder)); ! } } ! setChildren(policies); } --- 276,361 ---- } else if (name.equals("PolicyIdReference")) { policies.add(PolicyReference.getInstance(child, finder)); ! } else if (name.equals("PolicyCombinerParameters")) { ! paramaterHelper(policyParameters, child, "Policy"); ! } else if (name.equals("PolicySetCombinerParameters")) { ! paramaterHelper(policySetParameters, child, "PolicySet"); ! } } ! // now make sure that we can match up any parameters we may have ! // found to a cooresponding Policy or PolicySet... ! List elements = new ArrayList(); ! Iterator it = policies.iterator(); ! ! // right now we have to go though each policy and based on several ! // possible cases figure out what paranmeters might apply...but ! // there should be a better way to do this ! ! while (it.hasNext()) { ! AbstractPolicy policy = (AbstractPolicy)(it.next()); ! List list = null; ! ! if (policy instanceof Policy) { ! list = (List)(policyParameters.remove(policy.getId(). ! toString())); ! } else if (policy instanceof PolicySet) { ! list = (List)(policySetParameters.remove(policy.getId(). ! toString())); ! } else { ! PolicyReference ref = (PolicyReference)policy; ! String id = ref.getReference().toString(); ! ! if (ref.getReferenceType() == ! PolicyReference.POLICY_REFERENCE) ! list = (List)(policyParameters.remove(id)); ! else ! list = (List)(policySetParameters.remove(id)); ! } ! ! elements.add(new PolicyCombinerElement(policy, list)); ! } ! ! // ...and that there aren't extra parameters ! if (! policyParameters.isEmpty()) ! throw new ParsingException("Unmatched parameters in Policy"); ! if (! policySetParameters.isEmpty()) ! throw new ParsingException("Unmatched parameters in PolicySet"); ! ! // finally, set the list of Rules ! setChildren(elements); ! } ! ! /** ! * Private helper method that handles parsing a collection of ! * parameters ! */ ! private void paramaterHelper(HashMap parameters, Node root, ! String prefix) throws ParsingException { ! String ref = root.getAttributes().getNamedItem(prefix + "IdRef"). ! getNodeValue(); ! ! if (parameters.containsKey(ref)) { ! List list = (List)(parameters.get(ref)); ! parseParameters(list, root); ! } else { ! List list = new ArrayList(); ! parseParameters(list, root); ! parameters.put(ref, list); ! } ! } ! ! /** ! * Private helper method that handles parsing a single parameter. ! */ ! private void parseParameters(List parameters, Node root) ! throws ParsingException ! { ! NodeList nodes = root.getChildNodes(); ! ! for (int i = 0; i < nodes.getLength(); i++) { ! Node node = nodes.item(i); ! if (node.getNodeName().equals("CombinerParameter")) ! parameters.add(CombinerParameter.getInstance(node)); ! } } *************** *** 309,312 **** --- 438,442 ---- "</XPathVersion></PolicySetDefaults>"); + getTarget().encode(output, indenter); encodeCommonElements(output, indenter); Index: AbstractPolicy.java =================================================================== RCS file: /cvsroot/sunxacml/sunxacml/com/sun/xacml/AbstractPolicy.java,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** AbstractPolicy.java 4 Jun 2004 17:50:39 -0000 1.11 --- AbstractPolicy.java 7 Jan 2005 23:46:32 -0000 1.12 *************** *** 3,7 **** * @(#)AbstractPolicy.java * ! * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without --- 3,7 ---- * @(#)AbstractPolicy.java * ! * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without *************** *** 37,40 **** --- 37,42 ---- package com.sun.xacml; + import com.sun.xacml.combine.CombinerElement; + import com.sun.xacml.combine.CombinerParameter; import com.sun.xacml.combine.CombiningAlgorithm; import com.sun.xacml.combine.CombiningAlgFactory; *************** *** 82,85 **** --- 84,88 ---- // atributes associated with this policy private URI idAttr; + private String version; private CombiningAlgorithm combiningAlg; *************** *** 91,100 **** private String defaultVersion; ! // the elements we run through the combining algorithm private List children; // any obligations held by this policy private Set obligations; // the logger we'll use for all messages private static final Logger logger = --- 94,108 ---- private String defaultVersion; ! // the elements we run through the combining algorithm and the same list ! // paired with with their cooresponding elements private List children; + private List childElements; // any obligations held by this policy private Set obligations; + // the list of combiner parameters + private List parameters; + // the logger we'll use for all messages private static final Logger logger = *************** *** 113,123 **** * * @param id the policy id * @param combiningAlg the combining algorithm to use * @param description describes the policy or null if there is none * @param target the policy's target */ ! protected AbstractPolicy(URI id, CombiningAlgorithm combiningAlg, String description, Target target) { ! this(id, combiningAlg, description, target, null); } --- 121,134 ---- * * @param id the policy id + * @param version the policy version or null for the default (this is + * always null for pre-2.0 policies) * @param combiningAlg the combining algorithm to use * @param description describes the policy or null if there is none * @param target the policy's target */ ! protected AbstractPolicy(URI id, String version, ! CombiningAlgorithm combiningAlg, String description, Target target) { ! this(id, version, combiningAlg, description, target, null); } *************** *** 126,129 **** --- 137,142 ---- * * @param id the policy id + * @param version the policy version or null for the default (this is + * always null for pre-2.0 policies) * @param combiningAlg the combining algorithm to use * @param description describes the policy or null if there is none *************** *** 131,138 **** * @param defaultVersion the XPath version to use for selectors */ ! protected AbstractPolicy(URI id, CombiningAlgorithm combiningAlg, String description, Target target, String defaultVersion) { ! this(id, combiningAlg, description, target, defaultVersion, null); } --- 144,153 ---- * @param defaultVersion the XPath version to use for selectors */ ! protected AbstractPolicy(URI id, String version, ! CombiningAlgorithm combiningAlg, String description, Target target, String defaultVersion) { ! this(id, version, combiningAlg, description, target, defaultVersion, ! null, null); } *************** *** 141,144 **** --- 156,161 ---- * * @param id the policy id + * @param version the policy version or null for the default (this is + * always null for pre-2.0 policies) * @param combiningAlg the combining algorithm to use * @param description describes the policy or null if there is none *************** *** 147,153 **** * @param obligations the policy's obligations */ ! protected AbstractPolicy(URI id, CombiningAlgorithm combiningAlg, String description, Target target, ! String defaultVersion, Set obligations) { idAttr = id; this.combiningAlg = combiningAlg; --- 164,172 ---- * @param obligations the policy's obligations */ ! protected AbstractPolicy(URI id, String version, ! CombiningAlgorithm combiningAlg, String description, Target target, ! String defaultVersion, Set obligations, ! List parameters) { idAttr = id; this.combiningAlg = combiningAlg; *************** *** 156,159 **** --- 175,183 ---- this.defaultVersion = defaultVersion; + if (version == null) + this.version = "1.0"; + else + this.version = version; + if (obligations == null) this.obligations = Collections.EMPTY_SET; *************** *** 161,164 **** --- 185,194 ---- this.obligations = Collections. unmodifiableSet(new HashSet(obligations)); + + if (parameters == null) + this.parameters = Collections.EMPTY_LIST; + else + this.parameters = Collections. + unmodifiableList(new ArrayList(parameters)); } *************** *** 186,190 **** policyPrefix + "Id", e); } ! // now get the combining algorithm... try { --- 216,229 ---- policyPrefix + "Id", e); } ! ! // see if there's a version ! Node versionNode = attrs.getNamedItem("Version"); ! if (versionNode != null) { ! version = versionNode.getNodeValue(); ! } else { ! // assign the default version ! version = "1.0"; ! } ! // now get the combining algorithm... try { *************** *** 210,213 **** --- 249,253 ---- obligations = new HashSet(); + parameters = new ArrayList(); // now read the policy elements *************** *** 225,228 **** --- 265,270 ---- } else if (cname.equals(policyPrefix + "Defaults")) { handleDefaults(child); + } else if (cname.equals("CombinerParameters")) { + handleParameters(child); } } *************** *** 267,270 **** --- 309,325 ---- /** + * Handles all the CombinerParameters in the policy or policy set + */ + private void handleParameters(Node root) throws ParsingException { + NodeList nodes = root.getChildNodes(); + + for (int i = 0; i < nodes.getLength(); i++) { + Node node = nodes.item(i); + if (node.getNodeName().equals("CombinerParameter")) + parameters.add(CombinerParameter.getInstance(node)); + } + } + + /** * Returns the id of this policy * *************** *** 276,279 **** --- 331,343 ---- /** + * Returns the version of this policy + * + * @return the policy version + */ + public String getVersion() { + return version; + } + + /** * Returns the combining algorithm used by this policy * *************** *** 325,328 **** --- 389,404 ---- /** + * Returns the <code>List</code> of <code>CombinerElement</code>s that + * is provided to the combining algorithm. This returns the same set + * of children that <code>getChildren</code> provides along with any + * associated combiner parameters. + * + * @return a <code>List</code> of <code>CombinerElement</code>s + */ + public List getChildElements() { + return childElements; + } + + /** * Returns the Set of obligations for this policy, which may be empty * *************** *** 351,356 **** * Sets the child policy tree elements for this node, which are passed * to the combining algorithm on evaluation. The <code>List</code> must ! * contain <code>Rule</code>s or <code>AbstractPolicy</code>s, but may ! * not contain both types of elements. * * @param children the child elements used by the combining algorithm --- 427,433 ---- * Sets the child policy tree elements for this node, which are passed * to the combining algorithm on evaluation. The <code>List</code> must ! * contain <code>CombinerElement</code>s, which in turn will contain ! * <code>Rule</code>s or <code>AbstractPolicy</code>s, but may not ! * contain both types of elements. * * @param children the child elements used by the combining algorithm *************** *** 364,368 **** // NOTE: since this is only getting called by known child // classes we don't check that the types are all the same ! this.children = Collections.unmodifiableList(children); } } --- 441,454 ---- // NOTE: since this is only getting called by known child // classes we don't check that the types are all the same ! List list = new ArrayList(); ! Iterator it = children.iterator(); ! ! while (it.hasNext()) { ! CombinerElement element = (CombinerElement)(it.next()); ! list.add(element.getElement()); ! } ! ! this.children = Collections.unmodifiableList(list); ! childElements = Collections.unmodifiableList(children); } } *************** *** 380,384 **** public Result evaluate(EvaluationCtx context) { // evaluate ! Result result = combiningAlg.combine(context, children); // if we have no obligations, we're done --- 466,471 ---- public Result evaluate(EvaluationCtx context) { // evaluate ! Result result = combiningAlg.combine(context, parameters, ! childElements); // if we have no obligations, we're done *************** *** 415,423 **** protected void encodeCommonElements(OutputStream output, Indenter indenter) { - target.encode(output, indenter); - Iterator it = children.iterator(); while (it.hasNext()) { ! ((PolicyTreeElement)(it.next())).encode(output, indenter); } --- 502,508 ---- protected void encodeCommonElements(OutputStream output, Indenter indenter) { Iterator it = children.iterator(); while (it.hasNext()) { ! ((CombinerElement)(it.next())).encode(output, indenter); } Index: Policy.java =================================================================== RCS file: /cvsroot/sunxacml/sunxacml/com/sun/xacml/Policy.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** Policy.java 17 Mar 2004 18:03:37 -0000 1.6 --- Policy.java 7 Jan 2005 23:46:32 -0000 1.7 *************** *** 3,7 **** * @(#)Policy.java * ! * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without --- 3,7 ---- * @(#)Policy.java * ! * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without *************** *** 37,42 **** --- 37,47 ---- package com.sun.xacml; + import com.sun.xacml.combine.CombinerParameter; + import com.sun.xacml.combine.RuleCombinerElement; import com.sun.xacml.combine.RuleCombiningAlgorithm; + import com.sun.xacml.cond.VariableDefinition; + import com.sun.xacml.cond.VariableManager; + import com.sun.xacml.ctx.Result; *************** *** 47,50 **** --- 52,58 ---- import java.util.ArrayList; + import java.util.Collections; + import java.util.HashMap; + import java.util.HashSet; import java.util.Iterator; import java.util.List; *************** *** 67,70 **** --- 75,81 ---- { + // the set of variable definitions in this policy + private Set definitions; + /** * Creates a new <code>Policy</code> with only the required elements. *************** *** 76,85 **** */ public Policy(URI id, RuleCombiningAlgorithm combiningAlg, Target target) { ! this(id, combiningAlg, null, target, null, null, null); } /** * Creates a new <code>Policy</code> with only the required elements ! * plus some rules. * * @param id the policy identifier --- 87,96 ---- */ public Policy(URI id, RuleCombiningAlgorithm combiningAlg, Target target) { ! this(id, null, combiningAlg, null, target, null, null, null); } /** * Creates a new <code>Policy</code> with only the required elements ! * plus rules. * * @param id the policy identifier *************** *** 95,110 **** public Policy(URI id, RuleCombiningAlgorithm combiningAlg, Target target, List rules) { ! this(id, combiningAlg, null, target, null, rules, null); } /** * Creates a new <code>Policy</code> with the required elements plus ! * some rules and policy defaults. * * @param id the policy identifier * @param combiningAlg the <code>CombiningAlgorithm</code> used on the * rules in this set * @param target the <code>Target</code> for this policy - * @param defaultVersion the XPath version to use * @param rules a list of <code>Rule</code> objects * --- 106,123 ---- public Policy(URI id, RuleCombiningAlgorithm combiningAlg, Target target, List rules) { ! this(id, null, combiningAlg, null, target, null, rules, null); } /** * Creates a new <code>Policy</code> with the required elements plus ! * rules and a String description. * * @param id the policy identifier + * @param version the policy version or null for the default (this is + * always null for pre-2.0 policies) * @param combiningAlg the <code>CombiningAlgorithm</code> used on the * rules in this set + * @param description a <code>String</code> describing the policy * @param target the <code>Target</code> for this policy * @param rules a list of <code>Rule</code> objects * *************** *** 113,130 **** * <code>Rule</code> */ ! public Policy(URI id, RuleCombiningAlgorithm combiningAlg, Target target, ! String defaultVersion, List rules) { ! this(id, combiningAlg, null, target, defaultVersion, rules, null); } /** * Creates a new <code>Policy</code> with the required elements plus ! * some rules and a String description. * * @param id the policy identifier * @param combiningAlg the <code>CombiningAlgorithm</code> used on the * rules in this set * @param description a <code>String</code> describing the policy * @param target the <code>Target</code> for this policy * @param rules a list of <code>Rule</code> objects * --- 126,147 ---- * <code>Rule</code> */ ! public Policy(URI id, String version, RuleCombiningAlgorithm combiningAlg, ! String description, Target target, List rules) { ! this(id, version, combiningAlg, description, target, null, rules, ! null); } /** * Creates a new <code>Policy</code> with the required elements plus ! * rules, a String description and policy defaults. * * @param id the policy identifier + * @param version the policy version or null for the default (this is + * always null for pre-2.0 policies) * @param combiningAlg the <code>CombiningAlgorithm</code> used on the * rules in this set * @param description a <code>String</code> describing the policy * @param target the <code>Target</code> for this policy + * @param defaultVersion the XPath version to use * @param rules a list of <code>Rule</code> objects * *************** *** 133,146 **** * <code>Rule</code> */ ! public Policy(URI id, RuleCombiningAlgorithm combiningAlg, ! String description, Target target, List rules) { ! this(id, combiningAlg, description, target, null, rules, null); } /** * Creates a new <code>Policy</code> with the required elements plus ! * some rules, a String description and policy defaults. * * @param id the policy identifier * @param combiningAlg the <code>CombiningAlgorithm</code> used on the * rules in this set --- 150,167 ---- * <code>Rule</code> */ ! public Policy(URI id, String version, RuleCombiningAlgorithm combiningAlg, ! String description, Target target, String defaultVersion, ! List rules) { ! this(id, version, combiningAlg, description, target, defaultVersion, ! rules, null); } /** * Creates a new <code>Policy</code> with the required elements plus ! * rules, a String description, policy defaults, and obligations. * * @param id the policy identifier + * @param version the policy version or null for the default (this is + * always null for pre-2.0 policies) * @param combiningAlg the <code>CombiningAlgorithm</code> used on the * rules in this set *************** *** 149,152 **** --- 170,174 ---- * @param defaultVersion the XPath version to use * @param rules a list of <code>Rule</code> objects + * @param obligations a set of <code>Obligations</code> objects * * @throws IllegalArgumentException if the <code>List</code> of rules *************** *** 154,169 **** * <code>Rule</code> */ ! public Policy(URI id, RuleCombiningAlgorithm combiningAlg, String description, Target target, String defaultVersion, ! List rules) { ! this(id, combiningAlg, description, target, defaultVersion, rules, ! null); } /** * Creates a new <code>Policy</code> with the required elements plus ! * some rules, a String description, policy defaults, and obligations. * * @param id the policy identifier * @param combiningAlg the <code>CombiningAlgorithm</code> used on the * rules in this set --- 176,194 ---- * <code>Rule</code> */ ! public Policy(URI id, String version, RuleCombiningAlgorithm combiningAlg, String description, Target target, String defaultVersion, ! List rules, Set obligations) { ! this(id, version, combiningAlg, description, target, defaultVersion, ! rules, obligations, null); } /** * Creates a new <code>Policy</code> with the required elements plus ! * rules, a String description, policy defaults, obligations, and ! * variable definitions. * * @param id the policy identifier + * @param version the policy version or null for the default (this is + * always null for pre-2.0 policies) * @param combiningAlg the <code>CombiningAlgorithm</code> used on the * rules in this set *************** *** 173,176 **** --- 198,204 ---- * @param rules a list of <code>Rule</code> objects * @param obligations a set of <code>Obligations</code> objects + * @param definitions a set of <code>VariableDefinition</code> objects + * that must provide all definitions referenced by + * all <code>VariableReference</code>s in the policy * * @throws IllegalArgumentException if the <code>List</code> of rules *************** *** 178,189 **** * <code>Rule</code> */ ! public Policy(URI id, RuleCombiningAlgorithm combiningAlg, String description, Target target, String defaultVersion, ! List rules, Set obligations) { ! super(id, combiningAlg, description, target, defaultVersion, ! obligations); // check that the list contains only rules if (rules != null) { Iterator it = rules.iterator(); while (it.hasNext()) { --- 206,220 ---- * <code>Rule</code> */ ! public Policy(URI id, String version, RuleCombiningAlgorithm combiningAlg, String description, Target target, String defaultVersion, ! List rules, Set obligations, Set definitions) { ! super(id, version, combiningAlg, description, target, defaultVersion, ! obligations, null); ! ! List list = null; // check that the list contains only rules if (rules != null) { + list = new ArrayList(); Iterator it = rules.iterator(); while (it.hasNext()) { *************** *** 191,200 **** if (! (o instanceof Rule)) throw new IllegalArgumentException("non-Rule in rules"); ! } } ! setChildren(rules); } /** * Creates a new Policy based on the given root node. This is --- 222,301 ---- if (! (o instanceof Rule)) throw new IllegalArgumentException("non-Rule in rules"); ! list.add(new RuleCombinerElement((Rule)o)); ! } } ! setChildren(list); ! ! // save the definitions ! if (definitions == null) ! this.definitions = Collections.EMPTY_SET; ! else ! this.definitions = Collections. ! unmodifiableSet(new HashSet(definitions)); } + + + /** + * Creates a new <code>Policy</code> with the required and optional + * elements. If you need to provide combining algorithm parameters, you + * need to use this constructor. Note that unlike the other constructors + * in this class, the rules list is actually a list of + * <code>CombinerElement</code>s used to match a rule with any + * combiner parameters it may have. + * + * @param id the policy identifier + * @param version the policy version or null for the default (this is + * always null for pre-2.0 policies) + * @param combiningAlg the <code>CombiningAlgorithm</code> used on the + * rules in this set + * @param description a <code>String</code> describing the policy or + * null if there is no description + * @param target the <code>Target</code> for this policy + * @param defaultVersion the XPath version to use or null if there is + * no default version + * @param ruleElements a list of <code>RuleCombinerElement</code> objects + * or null if there are no rules + * @param obligations a set of <code>Obligations</code> objects or null + * if there are no obligations + * @param definitions a set of <code>VariableDefinition</code> objects + * that must provide all definitions referenced by + * all <code>VariableReference</code>s in the policy + * @param parameters the <code>List</code> of + * <code>CombinerParameter</code>s provided for general + * use by the combining algorithm + * + * @throws IllegalArgumentException if the <code>List</code> of rules + * contains an object that is not a + * <code>RuleCombinerElement</code> + */ + public Policy(URI id, String version, RuleCombiningAlgorithm combiningAlg, + String description, Target target, String defaultVersion, + List ruleElements, Set obligations, Set definitions, + List parameters) { + super(id, version, combiningAlg, description, target, defaultVersion, + obligations, parameters); + + // check that the list contains only RuleCombinerElements + if (ruleElements != null) { + Iterator it = ruleElements.iterator(); + while (it.hasNext()) { + Object o = it.next(); + if (! (o instanceof RuleCombinerElement)) + throw new IllegalArgumentException("non-Rule in rules"); + } + } + + setChildren(ruleElements); + + // save the definitions + if (definitions == null) + this.definitions = Collections.EMPTY_SET; + else + this.definitions = Collections. + unmodifiableSet(new HashSet(definitions)); + } + /** * Creates a new Policy based on the given root node. This is *************** *** 207,220 **** List rules = new ArrayList(); String xpathVersion = getDefaultVersion(); NodeList children = root.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); ! if (child.getNodeName().equals("Rule")) ! rules.add(Rule.getInstance(child, xpathVersion)); } ! setChildren(rules); } --- 308,413 ---- List rules = new ArrayList(); + HashMap parameters = new HashMap(); String xpathVersion = getDefaultVersion(); + HashMap variableIds = new HashMap(); + // first off, go through and look for any definitions to get their + // identifiers up front, since before we parse any references we'll + // need to know what definitions we support NodeList children = root.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); ! if (child.getNodeName().equals("VariableDefinition")) { ! String id = child.getAttributes(). ! getNamedItem("VariableId").getNodeValue(); ! ! // it's an error to have more than one definition with the ! // same identifier ! if (variableIds.containsKey(id)) ! throw new ParsingException("multiple definitions for " + ! "variable " + id); ! ! variableIds.put(id, child); ! } } ! // now create a manager with the defined variable identifiers ! VariableManager manager = new VariableManager(variableIds, ! xpathVersion); ! definitions = new HashSet(); ! ! // next, collect the Policy-specific elements ! for (int i = 0; i < children.getLength(); i++) { ! Node child = children.item(i); ! String name = child.getNodeName(); ! ! if (name.equals("Rule")) { ! rules.add(Rule.getInstance(child, xpathVersion, manager)); ! } else if (name.equals("RuleCombinerParameters")) { ! String ref = child.getAttributes().getNamedItem("RuleIdRef"). ! getNodeValue(); ! ! // if we found the parameter before than add it the end of ! // the previous paramters, otherwise create a new entry ! if (parameters.containsKey(ref)) { ! List list = (List)(parameters.get(ref)); ! parseParameters(list, child); ! } else { ! List list = new ArrayList(); ! parseParameters(list, child); ! parameters.put(ref, list); ! } ! } else if (name.equals("VariableDefinition")) { ! String id = child.getAttributes(). ! getNamedItem("VariableId").getNodeValue(); ! ! // parsing definitions is a little strange, since they can ! // contain references to definitions we haven't yet parsed ! // or circular references, but we still want to verify the ! // references and the types...so, for each definition, we ! // ask the manager though getDefinition, which takes care ! // of loading any forward references, handles loops, etc. ! // It also handles caching definitions, so we don't end ! // up parsing the same definitions multiple times ! definitions.add(manager.getDefinition(id)); ! } ! } ! ! definitions = Collections.unmodifiableSet(definitions); ! ! // now make sure that we can match up any parameters we may have ! // found to a cooresponding Rule... ! List elements = new ArrayList(); ! Iterator it = rules.iterator(); ! ! while (it.hasNext()) { ! Rule rule = (Rule)(it.next()); ! String id = rule.getId().toString(); ! List list = (List)(parameters.remove(id)); ! ! elements.add(new RuleCombinerElement(rule, list)); ! } ! ! // ...and that there aren't extra parameters ! if (! parameters.isEmpty()) ! throw new ParsingException("Unmatched parameters in Rule"); ! ! // finally, set the list of Rules ! setChildren(elements); ! } ! ! /** ! * Helper method that parses out a collection of combiner parameters. ! */ ! private void parseParameters(List parameters, Node root) ! throws ParsingException ! { ! NodeList nodes = root.getChildNodes(); ! ! for (int i = 0; i < nodes.getLength(); i++) { ! Node node = nodes.item(i); ! if (node.getNodeName().equals("CombinerParameter")) ! parameters.add(CombinerParameter.getInstance(node)); ! } } *************** *** 239,242 **** --- 432,444 ---- /** + * Returns the variable definitions in this Policy. + * + * @return a <code>Set</code> of <code>VariableDefinition</code>s + */ + public Set getVariableDefinitions() { + return definitions; + } + + /** * Encodes this <code>Policy</code> into its XML representation and writes * this encoding to the given <code>OutputStream</code> with no *************** *** 279,282 **** --- 481,490 ---- "</XPathVersion></PolicyDefaults>"); + getTarget().encode(output, indenter); + + Iterator it = definitions.iterator(); + while (it.hasNext()) + ((VariableDefinition)(it.next())).encode(output, indenter); + encodeCommonElements(output, indenter); |