use of org.ow2.authzforce.core.pdp.api.expression.VariableReference in project core by authzforce.
the class PolicyEvaluators method getInstanceGeneric.
/**
* Generic creation of PolicySet evaluator
*
* @param policySetRefChainWithArgIffRefTarget null/empty if {@code policyElement} is the root policySet; else it is the chain of top-level (as opposed to nested inline) PolicySets linked by PolicySetIdReferences from the root
* PolicySet up to (and including) the top-level (PolicySetIdReference-targeted) PolicySet that encloses or is {@code policyElement}
*/
private static <TLPEE extends TopLevelPolicyElementEvaluator, COMBINED_EVALUATOR extends PolicyEvaluator> TLPEE getInstanceGeneric(final PolicySetElementEvaluatorFactory<TLPEE, COMBINED_EVALUATOR> policyEvaluatorFactory, final PolicySet policyElement, final Deque<String> policySetRefChainWithArgIffRefTarget) throws IllegalArgumentException {
assert policyEvaluatorFactory != null && policyElement != null;
// final Set<PrimaryPolicyMetadata> enclosedPolicies = HashCollections.newUpdatableSet();
final String policyId = policyElement.getPolicySetId();
final BooleanEvaluator targetEvaluator = TargetEvaluators.getInstance(policyElement.getTarget(), policyEvaluatorFactory.expressionFactory, policyEvaluatorFactory.defaultXPathCompiler);
/*
* Elements defined in xs:choice of PolicySetType in XACML schema (Policy(Set)/Policy(Set)IdReference/CombinerParameters/Policy(Set)CombinerParameters
*/
final List<Serializable> jaxbPolicySetChoiceElements = policyElement.getPolicySetsAndPoliciesAndPolicySetIdReferences();
/*
* Prepare the list of evaluators combined by the combining algorithm in this PolicySet, i.e. Policy(Set)/Policy(Set)IdReference evaluators. combinedEvaluators.size() <=
* jaxbPolicySetChoiceElements.size() since combinedEvaluators does not include *CombinerParameter evaluators
*/
final List<COMBINED_EVALUATOR> combinedEvaluators = new ArrayList<>(jaxbPolicySetChoiceElements.size());
/*
* Why isn't there any VariableDefinition in XACML PolicySet like in Policy? If there were, we would keep a copy of variable IDs defined in this policy, to remove them from the global manager
* at the end of parsing this PolicySet. They should not be visible outside the scope of this.
* <p>
* final Set<String> variableIds = HashCollections.newUpdatableSet(jaxbPolicySetChoiceElements.size());
*/
/*
* Map to get child Policies by their ID so that we can resolve Policies associated with PolicyCombinerParameters Size cannot get bigger than jaxbPolicySetChoiceElements.size()
*/
final Map<String, COMBINED_EVALUATOR> childPolicyEvaluatorsByPolicyId = HashCollections.newUpdatableMap(jaxbPolicySetChoiceElements.size());
/*
* Map to get child PolicySets by their ID so that we can resolve PolicySets associated with PolicySetCombinerParameters Size cannot get bigger than jaxbPolicySetChoiceElements.size()
*/
final Map<String, COMBINED_EVALUATOR> childPolicySetEvaluatorsByPolicySetId = HashCollections.newUpdatableMap(jaxbPolicySetChoiceElements.size());
/*
* *CombinerParameters (combining algorithm parameters), size <= jaxbPolicySetChoiceElements.size()
*/
final List<CombiningAlgParameter<? extends COMBINED_EVALUATOR>> combiningAlgParameters = new ArrayList<>(jaxbPolicySetChoiceElements.size());
int childIndex = 0;
for (final Serializable policyChildElt : jaxbPolicySetChoiceElements) {
if (policyChildElt instanceof PolicyCombinerParameters) {
final String combinedPolicyId = ((PolicyCombinerParameters) policyChildElt).getPolicyIdRef();
final COMBINED_EVALUATOR childPolicyEvaluator = childPolicyEvaluatorsByPolicyId.get(combinedPolicyId);
if (childPolicyEvaluator == null) {
throw new IllegalArgumentException(policyEvaluatorFactory.policyMetadata + ": invalid PolicyCombinerParameters: referencing undefined child Policy #" + combinedPolicyId + " (no such policy defined before this element)");
}
final BaseCombiningAlgParameter<COMBINED_EVALUATOR> combiningAlgParameter;
try {
combiningAlgParameter = new BaseCombiningAlgParameter<>(childPolicyEvaluator, ((CombinerParametersType) policyChildElt).getCombinerParameters(), policyEvaluatorFactory.expressionFactory, policyEvaluatorFactory.defaultXPathCompiler);
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException(policyEvaluatorFactory.policyMetadata + ": invalid child #" + childIndex + " (PolicyCombinerParameters)", e);
}
combiningAlgParameters.add(combiningAlgParameter);
} else if (policyChildElt instanceof PolicySetCombinerParameters) {
final String combinedPolicySetId = ((PolicySetCombinerParameters) policyChildElt).getPolicySetIdRef();
final COMBINED_EVALUATOR combinedPolicySetEvaluator = childPolicySetEvaluatorsByPolicySetId.get(combinedPolicySetId);
if (combinedPolicySetEvaluator == null) {
throw new IllegalArgumentException(policyEvaluatorFactory.policyMetadata + ": invalid PolicySetCombinerParameters: referencing undefined child PolicySet #" + combinedPolicySetId + " (no such policySet defined before this element)");
}
final BaseCombiningAlgParameter<COMBINED_EVALUATOR> combiningAlgParameter;
try {
combiningAlgParameter = new BaseCombiningAlgParameter<>(combinedPolicySetEvaluator, ((CombinerParametersType) policyChildElt).getCombinerParameters(), policyEvaluatorFactory.expressionFactory, policyEvaluatorFactory.defaultXPathCompiler);
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException(policyEvaluatorFactory.policyMetadata + ": invalid child #" + childIndex + " (PolicySetCombinerParameters)", e);
}
combiningAlgParameters.add(combiningAlgParameter);
} else if (policyChildElt instanceof JAXBElement) {
final JAXBElement<?> jaxbPolicyChildElt = (JAXBElement<?>) policyChildElt;
final String eltNameLocalPart = jaxbPolicyChildElt.getName().getLocalPart();
if (eltNameLocalPart.equals(XacmlNodeName.POLICY_ID_REFERENCE.value())) {
final IdReferenceType policyChildIdRef = (IdReferenceType) jaxbPolicyChildElt.getValue();
final COMBINED_EVALUATOR childEvaluator = policyEvaluatorFactory.getChildPolicyRefEvaluator(childIndex, TopLevelPolicyElementType.POLICY, policyChildIdRef, null);
combinedEvaluators.add(childEvaluator);
final COMBINED_EVALUATOR duplicate = childPolicySetEvaluatorsByPolicySetId.putIfAbsent(childEvaluator.getPolicyId(), childEvaluator);
if (duplicate != null) {
throw new IllegalArgumentException("Duplicate PolicyIdReference's id = " + childEvaluator.getPolicyId());
}
} else if (eltNameLocalPart.equals(XacmlNodeName.POLICYSET_ID_REFERENCE.value())) {
final IdReferenceType policyChildIdRef = (IdReferenceType) jaxbPolicyChildElt.getValue();
final String policyChildId = policyChildIdRef.getValue();
/*
* Add this new reference to policyChildIdRef to the policyRef chain arg of getChildPolicyRefEvaluator(...). If policySetRefChainWithArgIffRefTarget is null/empty, policyElement is
* the root policy (no ancestor in the chain), therefore it should be added before policyChildIdRef, as the antecedent; Else non-empty policySetRefChainWithArgIffRefTarget's last
* item is either policyElement (iff it is a policy ref's target) or the top-level (as opposed to nested inline) PolicySet that encloses policyElement, in which either case we just
* add policyChildIdRef to the chain.
*/
final Deque<String> newPolicySetRefChainWithArgIffRefTarget = policySetRefChainWithArgIffRefTarget == null || policySetRefChainWithArgIffRefTarget.isEmpty() ? new ArrayDeque<>(Arrays.asList(policyId, policyChildId)) : policyEvaluatorFactory.joinPolicySetRefChains(policySetRefChainWithArgIffRefTarget, Collections.singletonList(policyChildId));
final COMBINED_EVALUATOR childEvaluator = policyEvaluatorFactory.getChildPolicyRefEvaluator(childIndex, TopLevelPolicyElementType.POLICY_SET, policyChildIdRef, newPolicySetRefChainWithArgIffRefTarget);
combinedEvaluators.add(childEvaluator);
final COMBINED_EVALUATOR duplicate = childPolicySetEvaluatorsByPolicySetId.put(policyChildId, childEvaluator);
if (duplicate != null) {
throw new IllegalArgumentException("Duplicate PolicySetIdReference's id = " + policyChildId);
}
} else if (eltNameLocalPart.equals(XacmlNodeName.COMBINER_PARAMETERS.value())) {
/*
* CombinerParameters that is not Policy(Set)CombinerParameters already tested before
*/
final BaseCombiningAlgParameter<COMBINED_EVALUATOR> combiningAlgParameter;
try {
combiningAlgParameter = new BaseCombiningAlgParameter<>(null, ((CombinerParametersType) jaxbPolicyChildElt.getValue()).getCombinerParameters(), policyEvaluatorFactory.expressionFactory, policyEvaluatorFactory.defaultXPathCompiler);
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException(policyEvaluatorFactory.policyMetadata + ": invalid child #" + childIndex + " (CombinerParameters)", e);
}
combiningAlgParameters.add(combiningAlgParameter);
}
} else if (policyChildElt instanceof PolicySet) {
final PolicySet childPolicy = (PolicySet) policyChildElt;
/*
* XACML spec §5.1: "ensure that no two policies visible to the PDP have the same identifier"
*/
final String childPolicyId = childPolicy.getPolicySetId();
/*
* Create/Update the policySet ref chain if necessary. If policySetRefChainWithArgIffRefTarget is null/empty, this means policyElement is the root policyset (no antecedent), and we
* create a chain with its ID, to know the antecedent of the next encountered policyset ref (which may be found deep under multiple levels of nested PolicySets).; else
* policySetRefChainWithArgIffRefTarget's last item is either policyElement (iff it is a policy ref's target) or the top-level (as opposed to nested inline) PolicySet that encloses
* policyElement, in which either case we already have the info we need in the chain so keep it as is.
*/
final Deque<String> newPolicySetRefChain = policySetRefChainWithArgIffRefTarget == null || policySetRefChainWithArgIffRefTarget.isEmpty() ? new ArrayDeque<>(Collections.singletonList(policyId)) : policySetRefChainWithArgIffRefTarget;
final COMBINED_EVALUATOR childEvaluator = policyEvaluatorFactory.getChildPolicySetEvaluator(childIndex, childPolicy, newPolicySetRefChain);
combinedEvaluators.add(childEvaluator);
final COMBINED_EVALUATOR duplicate = childPolicySetEvaluatorsByPolicySetId.putIfAbsent(childPolicyId, childEvaluator);
if (duplicate != null) {
throw new IllegalArgumentException("Duplicate PolicySetId = " + childPolicyId);
}
} else if (policyChildElt instanceof Policy) {
final Policy childPolicy = (Policy) policyChildElt;
/*
* XACML spec §5.1: "ensure that no two policies visible to the PDP have the same identifier"
*/
final String childPolicyId = childPolicy.getPolicyId();
final COMBINED_EVALUATOR childEvaluator = policyEvaluatorFactory.getChildPolicyEvaluator(childIndex, childPolicy);
combinedEvaluators.add(childEvaluator);
final COMBINED_EVALUATOR duplicate = childPolicyEvaluatorsByPolicyId.putIfAbsent(childPolicyId, childEvaluator);
if (duplicate != null) {
throw new IllegalArgumentException("Duplicate PolicyId = " + childPolicyId);
}
}
/*
* Why isn't there any VariableDefinition in XACML PolicySet defined by OASIS XACML 3.0 spec, like in Policy? If there were, the following code would be used (same as in PolicyEvaluator
* class).
*/
// else if (policySetChildElt instanceof VariableDefinition)
// {
// final VariableDefinition varDef = (VariableDefinition)
// policyChildElt;
// final Deque<String> varDefLongestVarRefChain = new
// ArrayDeque<>();
// final VariableReference<?> var;
// try
// {
// var = expressionFactory.addVariable(varDef, defaultXPathCompiler,
// varDefLongestVarRefChain);
// } catch (IllegalArgumentException e)
// {
// throw new IllegalArgumentException(policyFriendlyId + ": invalid
// child #" + childIndex + " (VariableDefinition)", e);
// }
//
// if (var != null)
// {
// /*
// * Conflicts can occur between variables defined in this policy
// but also with others already in a wider scope, i.e. defined in
// * parent/ancestor policy
// */
// throw new IllegalArgumentException(policyFriendlyId + ":
// Duplicable VariableDefinition for VariableId=" +
// var.getVariableId());
// }
//
// localVariableIds.add(varDef.getVariableId());
// // check whether the longest VariableReference chain in the
// VariableDefinition is longer than what we've got so far
// final int sizeOfVarDefLongestVarRefChain =
// varDefLongestVarRefChain.size();
// if(sizeOfVarDefLongestVarRefChain >
// sizeOfPolicyLongestVarRefChain) {
// sizeOfPolicyLongestVarRefChain = sizeOfVarDefLongestVarRefChain;
// }
// }
childIndex++;
}
/*
* Why isn't there any VariableDefinition in XACML PolicySet like in Policy? If there were, the final following code would be used: We are done parsing expressions in this policy, including
* VariableReferences, it's time to remove variables scoped to this policy from the variable manager
*/
// for (final String varId : variableIds)
// {
// expFactory.remove(varId);
// }
final ObligationExpressions obligationExps = policyElement.getObligationExpressions();
final AdviceExpressions adviceExps = policyElement.getAdviceExpressions();
return policyEvaluatorFactory.getInstance(policyEvaluatorFactory.policyMetadata, targetEvaluator, ImmutableList.of(), policyElement.getPolicyCombiningAlgId(), ImmutableList.copyOf(combinedEvaluators), ImmutableList.copyOf(combiningAlgParameters), obligationExps == null ? null : obligationExps.getObligationExpressions(), adviceExps == null ? null : adviceExps.getAdviceExpressions());
}
use of org.ow2.authzforce.core.pdp.api.expression.VariableReference in project core by authzforce.
the class PolicyEvaluators method getInstance.
/**
* Creates Policy handler from XACML Policy element
*
* @param policyElement Policy (XACML)
* @param parentDefaultXPathCompiler XPath compiler corresponding to parent PolicyDefaults/XPathVersion; undefined if this Policy has no parent Policy (root), or none defined in parent, or XPath disabled by PDP configuration
* @param namespacePrefixToUriMap namespace prefix-URI mappings from the original XACML Policy (XML) document, to be used for namespace-aware XPath evaluation; empty iff XPath support disabled or: {@code parentDefaultXPathCompiler.isPresent()} and they can be retrieved already from {@code parentDefaultXPathCompiler.get().getDeclaredNamespacePrefixToUriMap()}
* @param expressionFactory Expression factory/parser
* @param combiningAlgRegistry rule/policy combining algorithm registry
* @return instance
* @throws IllegalArgumentException if any argument is invalid
*/
public static StaticTopLevelPolicyElementEvaluator getInstance(final Policy policyElement, final ExpressionFactory expressionFactory, final CombiningAlgRegistry combiningAlgRegistry, final Optional<XPathCompilerProxy> parentDefaultXPathCompiler, final Map<String, String> namespacePrefixToUriMap) throws IllegalArgumentException {
if (policyElement == null) {
throw NULL_XACML_POLICY_ARG_EXCEPTION;
}
if (expressionFactory == null) {
throw NULL_EXPRESSION_FACTORY_EXCEPTION;
}
if (combiningAlgRegistry == null) {
throw NULL_XACML_COMBINING_ALG_ARG_EXCEPTION;
}
final String policyId = policyElement.getPolicyId();
final PolicyVersion policyVersion = new PolicyVersion(policyElement.getVersion());
final PrimaryPolicyMetadata policyMetadata = new BasePrimaryPolicyMetadata(TopLevelPolicyElementType.POLICY, policyId, policyVersion);
final BooleanEvaluator targetEvaluator = TargetEvaluators.getInstance(policyElement.getTarget(), expressionFactory, parentDefaultXPathCompiler);
/*
* Elements defined in xs:choice of XACML schema type PolicyType: Rules/(Rule)CombinerParameters/VariableDefinitions
*/
final List<Serializable> policyChoiceElements = policyElement.getCombinerParametersAndRuleCombinerParametersAndVariableDefinitions();
/*
* There are at most as many combining alg parameters as policyChoiceElements.size().
*/
final List<CombiningAlgParameter<? extends RuleEvaluator>> combiningAlgParameters = new ArrayList<>(policyChoiceElements.size());
/*
* Keep a copy of locally-defined variables defined in this policy, to remove them from the global manager at the end of parsing this policy. They should not be visible outside the scope of
* this policy. There are at most as many VariableDefinitions as policyChoiceElements.size().
*/
final List<VariableReference<?>> localVariables = new ArrayList<>(policyChoiceElements.size());
final DefaultsType policyDefaults = policyElement.getPolicyDefaults();
Optional<XPathCompilerProxy> childXpathCompiler;
/*
* Leave childXpathCompiler undefined if XPath support disabled globally.
*
* Else (XPath support enabled globally, but may be disabled locally for this specific Policy if XPathVersion undefined in it and any enclosing PolicySet)...
* Reminder: According to the XACML standard, the Policy(Set)Defaults/XPathVersion must be specified (non-null) in the current Policy(Set) or any of its enclosing/ancestor PolicySet for XPath expressions to be allowed (therefore a need for a XPathCompiler), e.g. in AttributeSelectors, XPath functions, etc.
*/
if (expressionFactory.isXPathEnabled()) {
/*
If both policyDefaults and parentDefaultXPathCompiler undefined, it means no Policy(Set)Defaults/XPathVersion defined (in current Policy and any enclosing PolicySet), i.e. XPath support is disabled for this Policy, so leave childXpathCompiler undefined like parentDefaultXPathCompiler.
We may reuse parentDefaultXPathCompiler if:
- parentDefaultXPathCompiler is defined
- AND policyDefaults/XPathVersion is undefined OR the XPath version matches the policyDefaults/XPathVersion
- AND namespacePrefixToUriMap is empty (i.e. only the ones from parentDefaultXPathCompiler apply)
*/
if (policyDefaults == null) {
if (parentDefaultXPathCompiler.isEmpty() || namespacePrefixToUriMap.isEmpty()) {
childXpathCompiler = parentDefaultXPathCompiler;
} else {
// parentDefaultXPathCompiler defined AND namespacePrefixToUriMap not empty -> new XPathCompiler to handle these new namespacePrefixToUriMap map
childXpathCompiler = Optional.of(new ImmutableXPathCompiler(parentDefaultXPathCompiler.get().getXPathVersion(), namespacePrefixToUriMap, List.of()));
}
} else {
// policyDefaults defined
final String xpathVersionUri = policyDefaults.getXPathVersion();
assert xpathVersionUri != null : "PolicyDefaults(non-null)/XPathVersion = null, which violates the XACML schema! Fix: enforce XACML schema validation.";
try {
final XPathVersion xPathVersion = XPathVersion.fromURI(xpathVersionUri);
if (parentDefaultXPathCompiler.isEmpty()) {
childXpathCompiler = Optional.of(new ImmutableXPathCompiler(xPathVersion, namespacePrefixToUriMap, List.of()));
} else // parentDefaultXPathCompiler defined, re-use it only if XPath version matches policyDefaults and namespacePrefixToUriMap empty
if (parentDefaultXPathCompiler.get().getXPathVersion().equals(xPathVersion) && namespacePrefixToUriMap.isEmpty()) {
childXpathCompiler = parentDefaultXPathCompiler;
} else {
childXpathCompiler = Optional.of(new ImmutableXPathCompiler(xPathVersion, namespacePrefixToUriMap, List.of()));
}
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException(policyMetadata + ": Invalid PolicySetDefaults/XPathVersion or XML namespace prefix/URI undefined", e);
}
}
} else {
// XPath support disabled globally
childXpathCompiler = Optional.empty();
}
/*
childXpathCompiler is empty iff XPath support disabled globally (!expressionFactory.isXPathEnabled()) OR (policyDefaults ==null AND parentDefaultXPathCompiler.isEmpty()), in other words iff XPath support disabled for this Policy
*/
/*
If XPath support enabled, we can reuse the same XPathCompiler as long as there is no new VariableDefinition
*/
boolean isNewChildXpathCompilerRequired = false;
/*
* We keep a record of the size of the longest chain of VariableReference in this policy, and update it when a VariableDefinition occurs
*/
int sizeOfPolicyLongestVarRefChain = 0;
/*
* Map to get rules by their ID so that we can resolve rules associated with RuleCombinerParameters, and detect duplicate RuleId. We want to preserve insertion order, to get map.values() in
* order of declaration, so that ordered-* algorithms have rules in order. There are at most as many Rules as policyChoiceElements.size().
*/
final Map<String, RuleEvaluator> ruleEvaluatorsByRuleIdInOrderOfDeclaration = new LinkedHashMap<>(policyChoiceElements.size());
int childIndex = 0;
for (final Serializable policyChildElt : policyChoiceElements) {
/*
If and only if XPath enabled for this Policy (childXpathCompiler.isPresent()), XPath compiler needed for each child, can we reuse the same one as last time (it was used to create a child element evaluator) ?
*/
if (childXpathCompiler.isPresent() && isNewChildXpathCompilerRequired) {
/*
New Variables defined since last XPath compiler created -> we need to use a new one to handle the new XACML Variables as XPath variables
*/
childXpathCompiler = Optional.of(new ImmutableXPathCompiler(childXpathCompiler.get().getXPathVersion(), namespacePrefixToUriMap, localVariables));
isNewChildXpathCompilerRequired = false;
}
if (policyChildElt instanceof RuleCombinerParameters) {
final String combinedRuleId = ((RuleCombinerParameters) policyChildElt).getRuleIdRef();
final RuleEvaluator ruleEvaluator = ruleEvaluatorsByRuleIdInOrderOfDeclaration.get(combinedRuleId);
if (ruleEvaluator == null) {
throw new IllegalArgumentException(policyMetadata + ": invalid RuleCombinerParameters: referencing undefined child Rule #" + combinedRuleId + " (no such rule defined before this element)");
}
final BaseCombiningAlgParameter<RuleEvaluator> combiningAlgParameter;
try {
combiningAlgParameter = new BaseCombiningAlgParameter<>(ruleEvaluator, ((CombinerParametersType) policyChildElt).getCombinerParameters(), expressionFactory, childXpathCompiler);
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException(policyMetadata + ": invalid child #" + childIndex + " (RuleCombinerParameters)", e);
}
combiningAlgParameters.add(combiningAlgParameter);
} else if (policyChildElt instanceof CombinerParametersType) {
/*
* CombinerParameters that is not RuleCombinerParameters already tested before
*/
final BaseCombiningAlgParameter<RuleEvaluator> combiningAlgParameter;
try {
combiningAlgParameter = new BaseCombiningAlgParameter<>(null, ((CombinerParametersType) policyChildElt).getCombinerParameters(), expressionFactory, childXpathCompiler);
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException(policyMetadata + ": invalid child #" + childIndex + " (CombinerParameters)", e);
}
combiningAlgParameters.add(combiningAlgParameter);
} else if (policyChildElt instanceof VariableDefinition) {
final VariableDefinition varDef = (VariableDefinition) policyChildElt;
final Deque<String> varDefLongestVarRefChain = new ArrayDeque<>();
final VariableReference<?> var;
try {
var = expressionFactory.addVariable(varDef, varDefLongestVarRefChain, childXpathCompiler);
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException(policyMetadata + ": invalid child #" + childIndex + " (VariableDefinition)", e);
}
if (var != null) {
/*
* Conflicts can occur between variables defined in this policy but also with others already in a wider scope, i.e. defined in parent/ancestor policy
*/
throw new IllegalArgumentException(policyMetadata + ": Duplicable VariableDefinition for VariableId = " + var.getVariableId());
}
localVariables.add(expressionFactory.getVariableExpression(varDef.getVariableId()));
/*
New Variables defined since last XPath compiler created -> we need to use a new one to handle the new XACML Variables as XPath variables in the subsequent child elements
*/
isNewChildXpathCompilerRequired = true;
/*
* check whether the longest VariableReference chain in the VariableDefinition is longer than what we've got so far
*/
final int sizeOfVarDefLongestVarRefChain = varDefLongestVarRefChain.size();
if (sizeOfVarDefLongestVarRefChain > sizeOfPolicyLongestVarRefChain) {
sizeOfPolicyLongestVarRefChain = sizeOfVarDefLongestVarRefChain;
}
} else if (policyChildElt instanceof Rule) {
final RuleEvaluator ruleEvaluator;
try {
ruleEvaluator = new RuleEvaluator((Rule) policyChildElt, expressionFactory, childXpathCompiler);
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException(policyMetadata + ": Error parsing child #" + childIndex + " (Rule)", e);
}
final RuleEvaluator conflictingRuleEvaluator = ruleEvaluatorsByRuleIdInOrderOfDeclaration.putIfAbsent(ruleEvaluator.getRuleId(), ruleEvaluator);
if (conflictingRuleEvaluator != null) {
/*
* Conflict: 2 Rule elements with same RuleId -> violates uniqueness of RuleId within a Policy (XACML spec)
*/
throw new IllegalArgumentException(policyMetadata + ": Duplicate Rule with RuleId = " + conflictingRuleEvaluator.getRuleId());
}
}
childIndex++;
}
final ObligationExpressions obligationExps = policyElement.getObligationExpressions();
final AdviceExpressions adviceExps = policyElement.getAdviceExpressions();
final StaticTopLevelPolicyElementEvaluator policyEvaluator = new StaticBaseTopLevelPolicyElementEvaluator<>(RuleEvaluator.class, policyMetadata, Optional.empty(), targetEvaluator, ImmutableList.copyOf(localVariables), policyElement.getRuleCombiningAlgId(), ImmutableList.copyOf(ruleEvaluatorsByRuleIdInOrderOfDeclaration.values()), ImmutableList.copyOf(combiningAlgParameters), obligationExps == null ? null : obligationExps.getObligationExpressions(), adviceExps == null ? null : adviceExps.getAdviceExpressions(), expressionFactory, combiningAlgRegistry, childXpathCompiler);
/*
* We are done parsing expressions in this policy, including VariableReferences, it's time to remove variables scoped to this policy from the variable manager
*/
localVariables.forEach(var -> expressionFactory.removeVariable(var.getVariableId()));
return policyEvaluator;
}
use of org.ow2.authzforce.core.pdp.api.expression.VariableReference in project core-pdp-api by authzforce.
the class XPathValue method evaluate.
/**
* Convenient method to get the XML nodes ("node-set") matching the XPath expression from the Content node of the XACML Attributes element with category <i>XPathCategory</i> in this
* {@code context}. <i>XPathCategory</i> is extracted from the attribute of the same name in {@code otherXmlAttributes} argument passed to {@link #XPathValue(String, Map, XPathCompilerProxy)} when
* creating this instance. To be used by XPath-based functions defined in section A.3.15 of XACML 3.0 Core specification.
*
* @param context
* current evaluation context
* @return node-set
* @throws org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException
* error evaluating the XPath expression
*/
public XdmValue evaluate(final EvaluationContext context) throws IndeterminateEvaluationException {
if (context == null) {
throw this.missingContextException;
}
final XdmNode contentNode = context.getAttributesContent(this.xpathCategory);
if (contentNode == null) {
throw this.missingAttributesContentException;
}
/*
* An XPathExecutable is immutable, and therefore thread-safe. It is simpler to load a new XPathSelector each time the expression is to be evaluated. However, the XPathSelector is serially
* reusable within a single thread. See Saxon Javadoc.
*/
final XPathSelector xpathSelector = xPathEvaluator.load();
try {
for (final VariableReference<?> xpathVar : xpathVariables) {
final Value val = context.getVariableValue(xpathVar.getVariableId(), xpathVar.getReturnType());
xpathSelector.setVariable(xpathVar.getXPathVariableName(), val.getXdmValue());
}
xpathSelector.setContextItem(contentNode);
return xpathSelector.evaluate();
} catch (final SaxonApiException e) {
throw new IndeterminateEvaluationException(this.xpathEvalExceptionStatus, e);
}
}
Aggregations