All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sap.cloud.security.ams.dcn.engine.EvaluationNode Maven / Gradle / Ivy

Go to download

Client Library for integrating Jakarta EE applications with SAP Authorization Management Service (AMS)

The newest version!
/************************************************************************
 * © 2019-2024 SAP SE or an SAP affiliate company. All rights reserved. *
 ************************************************************************/
package com.sap.cloud.security.ams.dcn.engine;

import java.util.Optional;

/**
 * Base class for all nodes in the evaluation tree (see {@link Engine}).
 *
 * 

Inner nodes represent logical and value operators (e.g. AND, OR, IN) and hold references to * sub nodes representing their operands. Except for a special node used for policy selection (see * {@link EffectivePoliciesNode}), all leaf nodes are either representing a concrete value (of * boolean, number, string or array type) or an unresolved attribute (e.g. $app.foo). */ public abstract class EvaluationNode { /** * Returns an empty optional unless this node represents a concrete value. * * @see ValueNode#value() */ public Optional value() { return Optional.empty(); } /** * Same as {@link #simplify()} by default but nodes representing operators are expected to * override this method and apply it recursively on its sub nodes first. * * @return simplified node equivalent to the subtree rooted at this node */ public EvaluationNode deepSimplify() { return simplify(); } /** * Returns a simplified node equivalent to this node. By default, this method returns the node * itself. * * @return simplified node equivalent to this node */ public EvaluationNode simplify() { return this; } /** * Returns a key used to identify nodes that can be merged with each other. Merging is triggered * by {@link AllOfNode#simplify()} and {@link AnyOfNode#simplify()}. By default, this method * returns an empty optional, meaning that the node cannot be merged with any other node. * * @return optional key for merging * @see BinaryOperatorNode#mergeKey() */ public Optional mergeKey() { return Optional.empty(); } /** * Nodes supporting merging of nodes which are sub nodes of the same {@link AllOfNode} need to * override this method along with {@link #mergeKey()}. By default, this method throws an * exception and will not be called as {@link #mergeKey()} returns an empty optional by default. * * @param other node to merge with * @return merged node * @see BinaryOperatorNode#andMerge(EvaluationNode) * @see AbstractEvaluationNodeFactory#inNode(EvaluationNode, EvaluationNode) */ public EvaluationNode andMerge(EvaluationNode other) { throw new IllegalStateException("Cannot merge " + this + " with " + other + " using AND"); } /** * Nodes supporting merging of nodes which are sub nodes of the same {@link AnyOfNode} need to * override this method along with {@link #mergeKey()}. By default, this method throws an * exception and will not be called as {@link #mergeKey()} returns an empty optional by default. * * @param other node to merge with * @return merged node * @see BinaryOperatorNode#orMerge(EvaluationNode) * @see AbstractEvaluationNodeFactory#inNode(EvaluationNode, EvaluationNode) */ public EvaluationNode orMerge(EvaluationNode other) { throw new IllegalStateException("Cannot merge " + this + " with " + other + " using OR"); } /** * Evaluates the subtree rooted at this node with respect to the attribute values provided by the * given {@link ValueAccessor}. The result is either a concrete value node or a new evaluation * subtree which is equivalent to this node with respect to the given attribute values. * * @param valueAccessor accessor for attribute values * @return evaluation subtree or a concrete value node */ public abstract EvaluationNode evaluate(ValueAccessor valueAccessor); /** * Converts the subtree rooted at this node to a condition object as required by the {@link * com.sap.cloud.security.ams.dcl.client.pdp.PolicyDecisionPoint}. * * @return condition object */ public abstract Object toCondition(); // TODO: find a better place for this method static String regexFromLikePattern(String pattern, Character escapeChar) { StringBuilder regex = new StringBuilder(); boolean escaped = false; for (int i = 0; i < pattern.length(); i++) { char c = pattern.charAt(i); if (escapeChar != null && escapeChar.equals(c)) { if (escaped) { regex.append(escapeChar); escaped = false; } else { escaped = true; } continue; } switch (c) { case '%': if (escaped) { regex.append("%"); escaped = false; } else { regex.append(".*"); } break; case '_': if (escaped) { regex.append("_"); escaped = false; } else { regex.append("."); } break; default: // cf. https://docs.oracle.com/javase/tutorial/essential/regex/literals.html String regexMetacharacters = "[](){}^$.|*+?\\"; if (regexMetacharacters.indexOf(c) != -1) { regex.append("\\"); } regex.append(c); escaped = false; break; } } return regex.toString(); } }