You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openaz.apache.org by pd...@apache.org on 2015/04/13 17:38:32 UTC
[32/51] [partial] incubator-openaz git commit: Initial seed of merged
of AT&T and JP Morgan code
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.java
new file mode 100755
index 0000000..e61e59f
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.java
@@ -0,0 +1,132 @@
+/*
+ * AT&T - PROPRIETARY
+ * THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ * ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ * Copyright (c) 2013 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.Bag;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+/**
+ * FunctionDefinitionBagIsIn implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to
+ * implement the XACML 'type'-is-in predicates as functions taking two arguments, the first of <code>type</code> and the second of type <code>Bag</code>,
+ * and returning a <code>Boolean</code> for whether the first argument is contained in the second.
+ *
+ * In the first implementation of XACML we had separate files for each XACML Function.
+ * This release combines multiple Functions in fewer files to minimize code duplication.
+ * This file supports the following XACML codes:
+ * string-is-in
+ * boolean-is-in
+ * integer-is-in
+ * double-is-in
+ * time-is-in
+ * date-is-in
+ * dateTime-is-in
+ * anyURI-is-in
+ * hexBinary-is-in
+ * base64Binary-is-in
+ * dayTimeDuration-is-in (version 1 and3)
+ * yearMonthDuration-is-in (version 1 and 3)
+ * x500Name-is-in
+ * rfc822Name-is-in
+ * ipAddress-is-in
+ * dnsName-is-in
+ *
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ * @param <I> the java class for the data type of the elements in the Input argument Bag
+ *
+ * The Output for these functions is always a Boolean.
+ */
+public class FunctionDefinitionBagIsIn<I> extends FunctionDefinitionBase<Boolean, I> {
+
+
+ /**
+ * Constructor - need dataType input because of java Generic type-erasure during compilation.
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ */
+ public FunctionDefinitionBagIsIn(Identifier idIn, DataType<I> dataTypeArgsIn) {
+ super(idIn, DataTypes.DT_BOOLEAN, dataTypeArgsIn, false);
+
+ }
+
+ /**
+ * Evaluates this <code>FunctionDefinition</code> on the given <code>List</code> of{@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}s.
+ *
+ * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} to use in the evaluation
+ * @param arguments the <code>List</code> of <code>FunctionArgument</code>s for the evaluation
+ * @return an {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} with the results of the call
+ */
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+
+ if (arguments == null || arguments.size() != 2) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 2 arguments, got " +
+ ((arguments == null) ? "null" : arguments.size()) ));
+ }
+
+ // get the thing to look for in the bag
+ FunctionArgument elementArgument = arguments.get(0);
+
+ ConvertedArgument<I> convertedTargetArgument = new ConvertedArgument<I>(elementArgument, this.getDataTypeArgs(), false);
+ if ( ! convertedTargetArgument.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedTargetArgument.getStatus()));
+ }
+
+ // Special case: Most methods want the value contained in the AttributeValue object inside the FunctionArgument.
+ // This one wants the AttributeValue itself.
+ // We use the ConvertedArgument constructor to validate that the argument is ok, then use the AttributeValue
+ // from the FunctionArgument.
+ AttributeValue<?> attributeValueElement = elementArgument.getValue();
+
+ // now get the bag
+ FunctionArgument bagArgument = arguments.get(1);
+ ConvertedArgument<Bag> convertedBagArgument = new ConvertedArgument<Bag>(bagArgument, null, true);
+
+ if ( ! convertedBagArgument.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedBagArgument.getStatus()));
+ }
+
+ Bag bag = convertedBagArgument.getBag();
+
+ Iterator<AttributeValue<?>> iterBagContents = bag.getAttributeValues();
+ while (iterBagContents.hasNext()) {
+ AttributeValue<?> attributeValueBagContents = iterBagContents.next();
+
+ /*
+ * Should we be checking the type of the bag contents and returning an error if the bag contents are not of the
+ * right type? The spec does not say this, so we just use the AttributeValue.equals() method for now.
+ */
+ if (attributeValueElement.equals(attributeValueBagContents)) {
+ return ER_TRUE;
+ }
+ }
+
+ return ER_FALSE;
+ }
+
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.java
new file mode 100755
index 0000000..03e1210
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.java
@@ -0,0 +1,117 @@
+/*
+ * AT&T - PROPRIETARY
+ * THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ * ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ * Copyright (c) 2013 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import java.util.List;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.Bag;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+/**
+ * FunctionDefinitionBagOneAndOnly implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to
+ * implement the XACML 'type'-one-and-only predicates as functions taking one <code>Bag</code> argument and returning the single element in that bag of the 'type'.
+ *
+ * In the first implementation of XACML we had separate files for each XACML Function.
+ * This release combines multiple Functions in fewer files to minimize code duplication.
+ * This file supports the following XACML codes:
+ * string-one-and-only
+ * boolean-one-and-only
+ * integer-one-and-only
+ * double-one-and-only
+ * time-one-and-only
+ * date-one-and-only
+ * dateTime-one-and-only
+ * anyURI-one-and-only
+ * hexBinary-one-and-only
+ * base64Binary-one-and-only
+ * dayTimeDuration-one-and-only (version 1 and3)
+ * yearMonthDuration-one-and-only (version 1 and 3)
+ * x500Name-one-and-only
+ * rfc822Name-one-and-only
+ * ipAddress-one-and-only
+ * dnsName-one-and-only
+ *
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ * @param <I> the java class for the data type of the elements in the bag handed to this as the Input argument,
+ * which is also the type of the return value
+ *
+ */
+public class FunctionDefinitionBagOneAndOnly<I> extends FunctionDefinitionBase<I,I> {
+
+
+ /**
+ * Constructor - need dataType input because of java Generic type-erasure during compilation.
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ */
+ public FunctionDefinitionBagOneAndOnly(Identifier idIn, DataType<I> dataTypeArgsIn) {
+ super(idIn, dataTypeArgsIn, dataTypeArgsIn, false);
+ }
+
+ /**
+ * Evaluates this <code>FunctionDefinition</code> on the given <code>List</code> of{@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}s.
+ *
+ * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} to use in the evaluation
+ * @param arguments the <code>List</code> of <code>FunctionArgument</code>s for the evaluation
+ * @return an {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} with the results of the call
+ */
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+
+ if (arguments == null || arguments.size() != 1) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + " Expected 1 argument, got " +
+ ((arguments == null) ? "null" : arguments.size()) ));
+ }
+
+ FunctionArgument argument = arguments.get(0);
+ ConvertedArgument<Bag> convertedArgument = new ConvertedArgument<Bag>(argument, null, true);
+
+ if ( ! convertedArgument.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedArgument.getStatus()));
+ }
+
+ Bag bag = convertedArgument.getBag();
+
+ if (bag.size() != 1) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() +
+ " Expected 1 but Bag has " + bag.size() + " elements"));
+ }
+
+ // get the single value from the bag
+ AttributeValue<?> attributeValueOneAndOnly = bag.getAttributeValues().next();
+ assert(attributeValueOneAndOnly != null);
+
+ // make sure it has the right type
+ //
+ if (!this.getDataTypeId().equals(attributeValueOneAndOnly.getDataTypeId())) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() +
+ " Element in bag of wrong type. Expected " +
+ this.getShortDataTypeId(this.getDataTypeId()) + " got " + this.getShortDataTypeId(attributeValueOneAndOnly.getDataTypeId())));
+ }
+ return ExpressionResult.newSingle(attributeValueOneAndOnly);
+ }
+
+
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.java
new file mode 100755
index 0000000..af75491
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.java
@@ -0,0 +1,110 @@
+/*
+ * AT&T - PROPRIETARY
+ * THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ * ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ * Copyright (c) 2013 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import java.math.BigInteger;
+import java.util.List;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML;
+import com.att.research.xacml.std.StdAttributeValue;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.Bag;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+/**
+ * FunctionDefinitionBagSize implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to
+ * implement the XACML 'type'-bag-size predicates as functions taking one <code>Bag</code> argument and returning an <code>Integer</code>
+ * representing the number of elements in the bag.
+ *
+ * In the first implementation of XACML we had separate files for each XACML Function.
+ * This release combines multiple Functions in fewer files to minimize code duplication.
+ * This file supports the following XACML codes:
+ * string-bag-size
+ * boolean-bag-size
+ * integer-bag-size
+ * double-bag-size
+ * time-bag-size
+ * date-bag-size
+ * dateTime-bag-size
+ * anyURI-bag-size
+ * hexBinary-bag-size
+ * base64Binary-bag-size
+ * dayTimeDuration-bag-size (version 1 and3)
+ * yearMonthDuration-bag-size (version 1 and 3)
+ * x500Name-bag-size
+ * rfc822Name-bag-size
+ * ipAddress-bag-size
+ * dnsName-bag-size
+ *
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ * @param <I> the java class for the data type of the function Input arguments
+ */
+public class FunctionDefinitionBagSize<I> extends FunctionDefinitionBase<BigInteger, I> {
+
+
+ /**
+ * Constructor - need dataType input because of java Generic type-erasure during compilation.
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ */
+ public FunctionDefinitionBagSize(Identifier idIn, DataType<I> dataTypeArgsIn) {
+ super(idIn, DataTypes.DT_INTEGER, dataTypeArgsIn, false);
+ }
+
+ /**
+ * Evaluates this <code>FunctionDefinition</code> on the given <code>List</code> of{@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}s.
+ *
+ * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} to use in the evaluation
+ * @param arguments the <code>List</code> of <code>FunctionArgument</code>s for the evaluation
+ * @return an {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} with the results of the call
+ */
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+
+ if (arguments == null || arguments.size() != 1) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 1 argument, got " +
+ ((arguments == null) ? "null" : arguments.size()) ));
+ }
+
+ FunctionArgument argument = arguments.get(0);
+ ConvertedArgument<Bag> convertedArgument = new ConvertedArgument<Bag>(argument, null, true);
+
+ if ( ! convertedArgument.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedArgument.getStatus()));
+ }
+
+ Bag bag = convertedArgument.getBag();
+
+ if (bag == null) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Bag is null" ));
+
+ }
+
+
+ // type is correct, so create a wrapper and return it
+ AttributeValue<BigInteger> resultAttributeValue = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, BigInteger.valueOf(bag.size()));
+ return ExpressionResult.newSingle(resultAttributeValue);
+ }
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.java
new file mode 100755
index 0000000..390e9b2
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.java
@@ -0,0 +1,165 @@
+/*
+ * AT&T - PROPRIETARY
+ * THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ * ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ * Copyright (c) 2013 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.datatypes.DataTypeBoolean;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
+
+
+/**
+ * /**
+ * FunctionDefinitionBase provides a common base for {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition}s.
+ * The child classes derived from this are of two types:
+ * <UL>
+ * <LI> Functions returning a single simple value of a type defined in {@link com.att.research.xacml.std.datatypes.DataTypes}.
+ * These functions will all derive from {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionSimple}.
+ * <LI> Functions returning a single bag with elements of a single type.
+ * <UL>
+ * <P>
+ * This base class contains the following components:
+ * <UL>
+ * <LI> The Identity for this function.
+ * <LI> The DataType of the data returned from this function.
+ * For Bags this means the DataType of the elements in the bag, or null if that is ambiguous.
+ * <LI> Commonly-used values.
+ * </UL>
+ *
+ * @author glenngriffin
+ *
+ * @param <O> the java class for the Output data type returned by the <code>FunctionDefinition</code>
+ * @param <I> the java class for the Input data type expected in the arguments to the <code>FunctionDefinition</code>.
+ * Some functions have non-homogeneous arguments but may still have a main 'type'.
+ */
+public abstract class FunctionDefinitionBase<O,I> implements FunctionDefinition {
+
+ // The XACML identifier string for this particular function
+ private Identifier id;
+
+ // each function derived from this returns a single non-bag data value of the following type, or a Bag containing elements of this type
+ private DataType<O> dataTypeReturn;
+
+ // All functions have input arguments and expect them to be of a given type.
+ // In some instances the argument gets multiple values of different types, but when the function has a 'type' associated with it's name
+ // specific ones of the input must be of this type.
+ // When an argument Input to the function is a Bag, the elements in that bag will be of this type.
+ // This corresponds most closely to the 'type' in the function name (as in 'type'-bag or 'type'-equals).
+ private DataType<I> dataTypeArgs;
+
+ // true = the return value from this function is a bag; false = return value is a single-value DataType object
+ private boolean returnsBag;
+
+ /*
+ * For functions that return a Boolean result we create a single instance of the True/False return values that they can share
+ */
+ protected static final ExpressionResult ER_TRUE = ExpressionResult.newSingle(DataTypeBoolean.AV_TRUE);
+ protected static final ExpressionResult ER_FALSE = ExpressionResult.newSingle(DataTypeBoolean.AV_FALSE);
+
+ /**
+ * Creates a new <code>FunctionDefinitionBase</code> with the {@link com.att.research.xacml.api.Identifier} <code>idIn</code> as
+ * the function id.
+ *
+ * @param idIn the <code>Identifier</code> for this <code>FunctionDefinitionBase</code>
+ */
+ protected FunctionDefinitionBase(Identifier idIn, DataType<O> returnDataTypeIn, DataType<I> argumentDataTypeIn, boolean returnsBagIn) {
+ this.id = idIn;
+ this.dataTypeReturn = returnDataTypeIn;
+ this.dataTypeArgs = argumentDataTypeIn;
+ this.returnsBag = returnsBagIn;
+ }
+
+ /**
+ * Returns a shortened version of the Id for this function, primarilly for use with error messages to prevent them from becoming too long.
+ * This is a simple convenience method to reduce code bloat.
+ *
+ * @return
+ */
+ public String getShortFunctionId() {
+ return this.getId().getUri().toString().substring(this.getId().getUri().toString().indexOf("function:"));
+ }
+
+ /**
+ * Returns a shortened version of the given DataType Id, primarily for use with error messages to prevent them from becoming too long.
+ * This is a simple convenience method to reduce code bloat.
+ *
+ * @param identifier expected to have '#' in it, and if no '#' should have ":data-type:"
+ * @return
+ */
+ public String getShortDataTypeId(Identifier identifier) {
+ String idString = identifier.stringValue();
+ int index = idString.indexOf("#");
+ if (index < 0) {
+ index = idString.indexOf(":data-type:");
+ if (index < 0) {
+ return idString;
+ } else {
+ return idString.substring(index + 11);
+ }
+ } else {
+ return idString.substring(index+1);
+ }
+ }
+
+ /**
+ * Return a new Status that includes the name of this function in front of the original status' message.
+ * This is a convenience method to reduce code bloat.
+ *
+ * @param originalStatu
+ * @return
+ */
+ public Status getFunctionStatus(Status originalStatus) {
+ return new StdStatus(originalStatus.getStatusCode(), getShortFunctionId() + " " + originalStatus.getStatusMessage());
+ }
+
+
+ //
+ // Getters for the internal variables
+ //
+
+ @Override
+ public Identifier getId() {
+ return this.id;
+ }
+
+ @Override
+ public Identifier getDataTypeId() {
+ if (this.dataTypeReturn == null) {
+ return null;
+ } else {
+ return this.dataTypeReturn.getId();
+ }
+ }
+
+ public DataType<O> getDataType() {
+ return this.dataTypeReturn;
+ }
+
+ /**
+ * Return the Identifier for the Input Argument(s) DataType.
+ *
+ * @return
+ */
+ public DataType<I> getDataTypeArgs() {
+ return this.dataTypeArgs;
+ }
+
+ @Override
+ public boolean returnsBag() {
+ return returnsBag;
+ }
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.java
new file mode 100755
index 0000000..a6af460
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.java
@@ -0,0 +1,136 @@
+/*
+ * AT&T - PROPRIETARY
+ * THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ * ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ * Copyright (c) 2013 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+/**
+ * FunctionDefinitionComparison implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to
+ * implement the XACML comparison predicates as functions taking two arguments of the same type
+ * and returning a <code>Boolean</code>.
+ *
+ * In the first implementation of XACML we had separate files for each XACML Function.
+ * This release combines multiple Functions in fewer files to minimize code duplication.
+ * This file supports the following XACML codes:
+ * integer-greater-than
+ * integer-greater-than-or-equal
+ * integer-less-than
+ * integer-less-than-or-equal
+ * double-greater-than
+ * double-greater-than-or-equal
+ * double-less-than
+ * double-less-than-or-equal
+ *
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ * @param <I> the java class for the data type of the function Input arguments
+ */
+public class FunctionDefinitionComparison<I extends Comparable<I>> extends FunctionDefinitionHomogeneousSimple<Boolean, I> {
+
+ /**
+ * List of comparison operations.
+ *
+ * @author glenngriffin
+ *
+ */
+ public enum OPERATION {GREATER_THAN, GREATER_THAN_EQUAL, LESS_THAN, LESS_THAN_EQUAL };
+
+ // the operation for this instance of the class
+ private OPERATION operation;
+
+
+ /**
+ * Constructor - need dataType input because of java Generic type-erasure during compilation.
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ */
+ public FunctionDefinitionComparison(Identifier idIn, DataType<I> dataTypeArgsIn, OPERATION opIn) {
+ super(idIn, DataTypes.DT_BOOLEAN, dataTypeArgsIn, 2);
+ operation = opIn;
+ }
+
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+
+ List<I> convertedArguments = new ArrayList<I>();
+ Status status = this.validateArguments(arguments, convertedArguments);
+
+ /*
+ * If the function arguments are not correct, just return an error status immediately
+ */
+ if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) {
+ return ExpressionResult.newError(getFunctionStatus(status));
+ }
+
+ int compareResult;
+ try {
+ compareResult = ((I)convertedArguments.get(0)).compareTo((I)convertedArguments.get(1));
+ } catch (Exception e) {
+ String message = e.getMessage();
+ if (e.getCause() != null) {
+ message = e.getCause().getMessage();
+ }
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));
+ }
+
+ switch (operation) {
+ case GREATER_THAN:
+ if (compareResult > 0) {
+ return ER_TRUE;
+ } else {
+ return ER_FALSE;
+ }
+
+ case GREATER_THAN_EQUAL:
+ if (compareResult > -1) {
+ return ER_TRUE;
+ } else {
+ return ER_FALSE;
+ }
+
+ case LESS_THAN:
+ if (compareResult < 0) {
+ return ER_TRUE;
+ } else {
+ return ER_FALSE;
+ }
+
+ case LESS_THAN_EQUAL:
+ if (compareResult < 1) {
+ return ER_TRUE;
+ } else {
+ return ER_FALSE;
+ }
+ }
+
+ // switch on enum should handle everything - should never get here
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " ENUM did not cover case of " + operation));
+
+ }
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.java
new file mode 100755
index 0000000..5530065
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.java
@@ -0,0 +1,125 @@
+/*
+ * AT&T - PROPRIETARY
+ * THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ * ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ * Copyright (c) 2013 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.std.functions;
+
+
+import java.util.List;
+
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.IDateTime;
+import com.att.research.xacml.std.datatypes.ISO8601Duration;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+/**
+ * FunctionDefinitionDateTimeArithmetic implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to
+ * implement the XACML Date and Time Arithmetic predicates.
+ *
+ * In the first implementation of XACML we had separate files for each XACML Function.
+ * This release combines multiple Functions in fewer files to minimize code duplication.
+ * This file supports the following XACML codes:
+ * dateTime-add-dayTimeDuration
+ * dateTime-add-yearMonthDuration
+ * dateTime-subtract-dayTimeDuration
+ * dateTime-subtract-yearMonthDuration
+ * date-add-yearMonthDuration
+ * date-subtract-yearMonthDuration
+ *
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ * @param <I> the java class for the data type of the function Input arguments;
+ * SPECIAL CASE: this applies ONLY to the 2nd argument.
+ * @param <O> the java class for the data type of the function Output;
+ * SPECIAL CASE: this ALSO applies to the type of the 1st Input argument.
+ */
+public class FunctionDefinitionDateTimeArithmetic<O extends IDateTime<O>, I extends ISO8601Duration> extends FunctionDefinitionBase<O, I> {
+
+ /**
+ * List of Date and Time Arithmetic operations.
+ *
+ * @author glenngriffin
+ *
+ */
+ public enum OPERATION {ADD, SUBTRACT};
+
+ // operation to be used in this instance of the class
+ private final OPERATION operation;
+
+
+
+ /**
+ * Constructor - need dataTypeArgs input because of java Generic type-erasure during compilation.
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ */
+ public FunctionDefinitionDateTimeArithmetic(Identifier idIn, DataType<O> dataTypeIn, DataType<I> dataTypeArgsIn, OPERATION op) {
+ super(idIn, dataTypeIn, dataTypeArgsIn, false);
+ this.operation = op;
+ }
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+ if (arguments == null || arguments.size() != 2) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Expected 2 arguments, got " +
+ ((arguments == null) ? "null" : arguments.size()) ));
+ }
+
+ // first arg has same type as function output
+ FunctionArgument functionArgument = arguments.get(0);
+ ConvertedArgument<O> convertedArgument0 = new ConvertedArgument<O>(functionArgument, this.getDataType(), false);
+ if ( ! convertedArgument0.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedArgument0.getStatus()));
+ }
+ O idateOrig = convertedArgument0.getValue();
+
+ // second argument is of input type
+ functionArgument = arguments.get(1);
+ ConvertedArgument<I> convertedArgument1 = new ConvertedArgument<I>(functionArgument, this.getDataTypeArgs(), false);
+ if ( ! convertedArgument1.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedArgument1.getStatus()));
+ }
+ // get the Duration object from the argument which includes all fields, even if the incoming argument does not include them all
+ ISO8601Duration duration = convertedArgument1.getValue();
+
+ // add/subtract the duration to the input argument
+ //
+ O idateResult = null;
+ switch(this.operation) {
+ case ADD:
+ idateResult = idateOrig.add(duration);
+ break;
+ case SUBTRACT:
+ idateResult = idateOrig.sub(duration);
+ break;
+ }
+ ExpressionResult expressionResult = null;
+ try {
+ expressionResult = ExpressionResult.newSingle(this.getDataType().createAttributeValue(idateResult));
+ } catch (DataTypeException e) {
+ String message = e.getMessage();
+ if (e.getCause() != null) {
+ message = e.getCause().getMessage();
+ }
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));
+ }
+ return expressionResult;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.java
new file mode 100755
index 0000000..af5c1e6
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.java
@@ -0,0 +1,88 @@
+/*
+ * AT&T - PROPRIETARY
+ * THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ * ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ * Copyright (c) 2013 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+/**
+ * FunctionDefinitionEquality extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to
+ * implement the XACML Equality predicates as functions taking two arguments of the same data type and returning a <code>Boolean</code>.
+ *
+ * In the first implementation of XACML we had separate files for each XACML Function.
+ * This release combines multiple Functions in fewer files to minimize code duplication.
+ * This file supports the following XACML codes:
+ * string-equal
+ * boolean-equal
+ * integer-equal
+ * double-equal
+ * date-equal
+ * time-equal
+ * dateTime-equal
+ * dayTimeDuration-equal
+ * yearMonthDuration-equal
+ * anyURI-equal
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ *
+ * @param <I> the java class for the data type of the function Input arguments
+ */
+public class FunctionDefinitionEquality<I> extends FunctionDefinitionHomogeneousSimple<Boolean, I> {
+
+ /**
+ * Determines if the two <code>T</code> values are equal using the java <code>equals</code> method. Derived classes
+ * may override this if the <code>equals</code> method is not sufficient.
+ *
+ * @param v1 the first object to compare
+ * @param v2 the second object to compare
+ * @return true if the two objects are the same, else false
+ */
+ protected boolean isEqual(I v1, I v2) {
+ return v1.equals(v2);
+ }
+
+ public FunctionDefinitionEquality(Identifier idIn, DataType<I> dataTypeArgsIn) {
+ super(idIn, DataTypes.DT_BOOLEAN, dataTypeArgsIn, 2);
+ }
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+ List<I> convertedArguments = new ArrayList<I>();
+ Status status = this.validateArguments(arguments, convertedArguments);
+
+ /*
+ * If the function arguments are not correct, just return an error status immediately
+ */
+ if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) {
+ return ExpressionResult.newError(getFunctionStatus(status));
+ }
+
+ /*
+ * Now just perform the equality operation.
+ */
+ if (this.isEqual(convertedArguments.get(0), convertedArguments.get(1))) {
+ return ER_TRUE;
+ } else {
+ return ER_FALSE;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.java
new file mode 100755
index 0000000..515cbd5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.java
@@ -0,0 +1,523 @@
+/*
+ * AT&T - PROPRIETARY
+ * THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ * ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ * Copyright (c) 2013 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.Bag;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
+import com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory;
+
+/**
+ * FunctionDefinitionSet implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to
+ * implement the XACML Set predicates as functions taking two arguments of <code>Bag</code> the same primitive type
+ * and returning either a <code>Boolean</code> or a <code>Bag</code> of the same primitive type.
+ * <P>
+ * The ipAddress, dnsName and xPathExpression do not have set functions defined for them in section 10.2.8 of the Release 3 XACML spec.
+ *
+ * In the first implementation of XACML we had separate files for each XACML Function.
+ * This release combines multiple Functions in fewer files to minimize code duplication.
+ * This file supports the following XACML codes:
+ * string-bag
+ * boolean-bag
+ * integer-bag
+ * double-bag
+ * time-bag
+ * date-bag
+ * dateTime-bag
+ * anyURI-bag
+ * hexBinary-bag
+ * base64Binary-bag
+ * dayTimeDuration-bag (version 1 and3)
+ * yearMonthDuration-bag (version 1 and 3)
+ * x500Name-bag
+ * rfc822Name-bag
+ *
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ * @param <I> the java class for the data type of the function Input arguments
+ * @param <O> the java class for the data type of the function Output
+ */
+public class FunctionDefinitionHigherOrderBag<O,I> extends FunctionDefinitionBase<O, I> {
+
+ /**
+ * List of comparison operations.
+ *
+ * @author glenngriffin
+ *
+ */
+ public enum OPERATION {ANY_OF, ALL_OF, ANY_OF_ANY, ALL_OF_ANY, ANY_OF_ALL, ALL_OF_ALL, MAP };
+
+ // the operation for this instance of the class
+ private OPERATION operation;
+
+
+ /**
+ * Constructor - need dataType input because of java Generic type-erasure during compilation.
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ */
+ public FunctionDefinitionHigherOrderBag(Identifier idIn, DataType<O> dataTypeIn, DataType<I> dataTypeArgsIn, OPERATION opIn) {
+ super(idIn, dataTypeIn, dataTypeArgsIn, ((opIn == OPERATION.MAP) ? true : false) );
+ operation = opIn;
+ }
+
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+
+ // simple argument check
+ if (arguments == null || arguments.size() < 2) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Expected at least 2 arguments, got " +
+ ((arguments == null) ? "null" : arguments.size()) ));
+ }
+
+ // three functions have some things known about the arguments
+ if (operation == OPERATION.ALL_OF_ANY || operation == OPERATION.ANY_OF_ALL || operation == OPERATION.ALL_OF_ALL) {
+ if (arguments.size() != 3) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Expected 3 arguments, got " + arguments.size()) );
+ }
+ // the 2nd & 3rd arguments must both be bags
+ if ( arguments.get(1) == null || ! arguments.get(1).isBag() ) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " 2nd argument must be bag, got '" + ((arguments.get(1) == null) ? "null" : this.getShortDataTypeId(arguments.get(1).getValue().getDataTypeId())) + "'" ));
+ }
+ if (arguments.get(2) == null || ! arguments.get(2).isBag() ) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " 3rd argument must be bag, got '" + ((arguments.get(2) == null) ? "null" : this.getShortDataTypeId(arguments.get(2).getValue().getDataTypeId())) + "'" ));
+ }
+ }
+
+ // first argument is supposed to be a Function ID passed to us as an AnyURI
+ FunctionArgument functionIdArgument = arguments.get(0);
+ if (functionIdArgument == null || functionIdArgument.getValue() == null) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Predicate Function (first argument) was null"));
+ }
+ if ( ! functionIdArgument.getValue().getDataTypeId().equals(DataTypes.DT_ANYURI.getId())) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " First argument expected URI, got " + functionIdArgument.getValue().getDataTypeId() ) );
+ }
+ Identifier functionId = new IdentifierImpl((URI) functionIdArgument.getValue().getValue());
+
+ // look up the actual function definition based on that ID
+ StdFunctionDefinitionFactory fdf = new StdFunctionDefinitionFactory();
+
+ FunctionDefinition predicate = fdf.getFunctionDefinition(functionId);
+
+ if (predicate == null) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " First argument was not URI of a function, got '" + functionId + "'") );
+ }
+ // in all cases except MAP, the predicate must return True/False
+ if (operation != OPERATION.MAP) {
+ if ( ! predicate.getDataTypeId().equals(DataTypes.DT_BOOLEAN.getId())) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Predicate Function must return boolean, but '" + predicate.getId() + "' returns '" + this.getShortDataTypeId(predicate.getDataTypeId()) ));
+ }
+ }
+
+
+
+ // The remaining arguments may be either bags or primitive types.
+ // We do not know what the primitive types will be, and do not concern ourselves about that here
+ // (the predicate function we just got and will call later will complain if they do not match its expectations).
+ // The predicate function will want things as FunctionAttributes, so we do not need to unwrap anything.
+ boolean bagSeen = false;
+ for (int i = 1; i < arguments.size(); i++) {
+ FunctionArgument argument = arguments.get(i);
+ if (argument == null) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Got null argument at index " + i) );
+ }
+ // force evaluation and check status
+ if ( ! argument.getStatus().isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(argument.getStatus()));
+ }
+
+ // for bags, remember that we saw one; for non-bag primitives, check that the primitive value is not null
+ if (argument.isBag()) {
+ bagSeen = true;
+ } else {
+ if (argument.getValue() == null || argument.getValue().getValue() == null) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Got null attribute at index " + i) );
+ }
+ }
+ }
+
+ // all functions require at least one bag
+ if ( ! bagSeen && operation != OPERATION.ANY_OF_ANY) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Did not get any Bag argument; must have at least 1") );
+ }
+
+
+ // arguments are ready for use
+
+ // list of arguments for passing to the predicate
+ List<FunctionArgument> predicateArguments = new ArrayList<FunctionArgument>();
+
+ // for functions that take a single bag, which index is that bag at
+ int indexOfBagInOriginalArgs = -1;
+
+ // bag iterator
+ Iterator<AttributeValue<?>> bagIterator1;
+ Iterator<AttributeValue<?>> bagIterator2;
+
+
+
+
+ switch (operation) {
+
+ case ANY_OF:
+ // Copy the primitive arguments to the list for passing to the predicate,
+ // putting a place-holder in for the value from the (single) bag
+ for (int i = 1; i < arguments.size(); i++) {
+ predicateArguments.add(arguments.get(i));
+ if (arguments.get(i).isBag()) {
+ if (indexOfBagInOriginalArgs == -1) {
+ indexOfBagInOriginalArgs = i ;
+ } else {
+ // bag already found - we should have only one
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) );
+ }
+ }
+ }
+
+ // get each primitive value in turn
+ bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues();
+ while (bagIterator1.hasNext()) {
+ // all of the predicate arguments have been created except that the one from the bag needs to replace the place-holder in the list
+ predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next()));
+ ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments);
+ if ( ! res.isOk()) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Predicate error: " + res.getStatus().getStatusMessage()) );
+ }
+ if ( (Boolean)(res.getValue().getValue()) == true) {
+ return ER_TRUE;
+ }
+ }
+
+ return ER_FALSE;
+
+
+
+ case ALL_OF:
+ // Copy the primitive arguments to the list for passing to the predicate,
+ // putting a place-holder in for the value from the (single) bag
+ for (int i = 1; i < arguments.size(); i++) {
+ predicateArguments.add(arguments.get(i));
+ if (arguments.get(i).isBag()) {
+ if (indexOfBagInOriginalArgs == -1) {
+ indexOfBagInOriginalArgs = i ;
+ } else {
+ // bag already found - we should have only one
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) );
+ }
+ }
+ }
+
+ // get each primitive value in turn
+ bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues();
+ while (bagIterator1.hasNext()) {
+ // all of the predicate arguments have been created except that the one from the bag needs to replace the place-holder in the list
+ predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next()));
+ ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments);
+ if ( ! res.isOk()) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Predicate error: " + res.getStatus().getStatusMessage()) );
+ }
+ if ( (Boolean)(res.getValue().getValue()) == false) {
+ return ER_FALSE;
+ }
+ }
+ return ER_TRUE;
+
+
+ case ANY_OF_ANY:
+ // empty bags can give odd error messages, so check here and return something that makes more sense
+ for (int i = 1; i < arguments.size(); i++) {
+ if (arguments.get(i).isBag() && arguments.get(i).getBag().size() == 0) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Bag is empty at index " + i ));
+ }
+ }
+ // This is different from all the other Higher-order bag functions because it can take an unbounded number of arguments any/all of which may be bags.
+ // (The others take either an unbounded number of args of which exactly 1 is a bag, or they take exactly 2 bags)
+ // To handle the possibility of multiple bags without knowing a priori how many there might be,
+ // we first create all possible lists of arguments to be passed to the predicate.
+ // This is done using a depth-first search of the total argument space.
+ List<List<FunctionArgument>> listOfPredicateLists = new ArrayList<List<FunctionArgument>>();
+
+ /*
+ * Start the recursive append process
+ */
+ appendCrossProduct(new ArrayList<FunctionArgument>(), arguments.subList(1, arguments.size()), 0, listOfPredicateLists);
+
+ // we now have all possible argument lists for the predicate to work on, so do the ANY operation now
+ for (List<FunctionArgument> predicateArgumentList : listOfPredicateLists) {
+ // all of the predicate arguments have been created except that the one from the bag needs to replace the place-holder in the list
+ ExpressionResult res = predicate.evaluate(evaluationContext, predicateArgumentList);
+ if ( ! res.isOk()) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Predicate error: " + res.getStatus().getStatusMessage()) );
+ }
+ if ( (Boolean)(res.getValue().getValue()) == true) {
+ return ER_TRUE;
+ }
+ }
+
+ // if we get here then none of the combinations gave a TRUE result
+ return ER_FALSE;
+
+
+
+ case ALL_OF_ANY:
+//TODO - it might be more efficient to extract all the attributes from the first bag and convert them to FunctionArguments just once, then use that list each time
+
+ // get the element from the 2nd bag that we want to check all elements from the 1st bag against
+ bagIterator2 = arguments.get(2).getBag().getAttributeValues();
+ while (bagIterator2.hasNext()) {
+ FunctionArgument predicateArgument2 = new FunctionArgumentAttributeValue(bagIterator2.next());
+ boolean allMatch = true;
+
+ // now look at every value of the first bag operating with the selected value from the 2nd
+ bagIterator1 = arguments.get(1).getBag().getAttributeValues();
+ while (bagIterator1.hasNext()) {
+
+ predicateArguments.clear();
+ predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator1.next()));
+ predicateArguments.add(predicateArgument2);
+
+ ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments);
+ if ( ! res.isOk()) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Predicate error: " + res.getStatus().getStatusMessage()) );
+ }
+ if ( (Boolean)(res.getValue().getValue()) == false) {
+ allMatch = false;
+ break;
+ }
+ }
+ if (allMatch) {
+ // wee found one value in bag2 that works (is TRUE) for all values in bag1
+ return ER_TRUE;
+ }
+ // this value from bag2 did not work, so get the next one
+ }
+
+ // no value in bag2 worked for all values of bag1
+ return ER_FALSE;
+
+
+
+ case ANY_OF_ALL:
+//TODO - it might be more efficient to extract all the attributes from the 2nd bag and convert them to FunctionArguments just once, then use that list each time
+
+ // get the element from the 1st bag that we want to check all elements from the 1st bag against
+ bagIterator1 = arguments.get(1).getBag().getAttributeValues();
+ while (bagIterator1.hasNext()) {
+ FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next());
+ boolean allMatch = true;
+
+ // now look at every value of the 2nd bag operating with the selected value from the first
+ bagIterator2 = arguments.get(2).getBag().getAttributeValues();
+ while (bagIterator2.hasNext()) {
+ predicateArguments.clear();
+ predicateArguments.add(predicateArgument1);
+ predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next()));
+
+ ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments);
+ if ( ! res.isOk()) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Predicate error: " + res.getStatus().getStatusMessage()) );
+ }
+ if ( (Boolean)(res.getValue().getValue()) == false) {
+ allMatch = false;
+ break;
+ }
+ }
+ if (allMatch) {
+ // wee found one value in bag1 that works (is TRUE) for all values in bag2
+ return ER_TRUE;
+ }
+ // this value from bag1 did not work, so get the next one
+ }
+
+ // no value in bag1 worked for all values of bag2
+ return ER_FALSE;
+
+
+
+ case ALL_OF_ALL:
+//TODO - it might be more efficient to extract all the attributes from the 2nd bag and convert them to FunctionArguments just once, then use that list each time
+
+ // get the element from the 1st bag that we want to check all elements from the 1st bag against
+ bagIterator1 = arguments.get(1).getBag().getAttributeValues();
+ while (bagIterator1.hasNext()) {
+ FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next());
+
+ // now look at every value of the 2nd bag operating with the selected value from the first
+ bagIterator2 = arguments.get(2).getBag().getAttributeValues();
+ while (bagIterator2.hasNext()) {
+ predicateArguments.clear();
+ predicateArguments.add(predicateArgument1);
+ predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next()));
+
+ ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments);
+ if ( ! res.isOk()) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Predicate error: " + res.getStatus().getStatusMessage()) );
+ }
+
+ if ( (Boolean)(res.getValue().getValue()) == false) {
+ return ER_FALSE;
+ }
+ }
+ // this value did not fail, so try the next
+ }
+
+ // everything in bag1 worked (was true) for everything in bag 2
+ return ER_TRUE;
+
+
+
+ case MAP:
+ // Copy the primitive arguments to the list for passing to the predicate,
+ // putting a place-holder in for the value from the (single) bag
+ for (int i = 1; i < arguments.size(); i++) {
+ predicateArguments.add(arguments.get(i));
+ if (arguments.get(i).isBag()) {
+ if (indexOfBagInOriginalArgs == -1) {
+ indexOfBagInOriginalArgs = i ;
+ } else {
+ // bag already found - we should have only one
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) );
+ }
+ }
+ }
+
+ Bag outputBag = new Bag();
+
+ // get each primitive value in turn
+ bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues();
+ while (bagIterator1.hasNext()) {
+ // all of the predicate arguments have been created except that the one from the bag needs to replace the place-holder in the list
+ predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next()));
+ ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments);
+ if ( ! res.isOk()) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Predicate error: " + res.getStatus().getStatusMessage()) );
+ }
+ if (res.isBag()) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Cannot put bag inside bag; predicate was '" + predicate.getId() + "'"));
+ }
+ outputBag.add(res.getValue());
+ }
+
+
+ return ExpressionResult.newBag(outputBag);
+
+ }
+
+ // all cases should have been covered by above - should never get here
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Could not evaluate Higher-Order Bag function " + operation));
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+ /**
+ * Performs the depth-first walk to generate argument lists. Needed by any-of-any because of the variable number of bags it might get.
+ *
+ * This code was salvaged from the R2 version of the product and adjusted to fit the new way of doing business.
+ *
+ * @param argListInProgress the current argument list being generated in this pass
+ * @param valueList the list of expression result values
+ * @param nPosition the position within the expression result values to use to append to the base argument list
+ * @param listArgLists the <code>List</code> where final argument lists are appended
+ */
+ private static void appendCrossProduct(List<FunctionArgument> argListInProgress, List<FunctionArgument> valueList, int nPosition, List<List<FunctionArgument>> listArgLists) {
+ /*
+ * Have we hit a leaf?
+ */
+ if (nPosition >= valueList.size()) {
+ List<FunctionArgument> copy = new ArrayList<FunctionArgument>();
+ copy.addAll(argListInProgress);
+ listArgLists.add(copy);
+ return;
+ }
+
+ /*
+ * Check to see if the value at the current position is a primitive or a bag
+ */
+ FunctionArgument FunctionArgument = valueList.get(nPosition);
+ if (FunctionArgument.isBag() && FunctionArgument.getBag().getAttributeValues() != null && FunctionArgument.getBag().size() > 0) {
+ Iterator<AttributeValue<?>> iterBagValues = FunctionArgument.getBag().getAttributeValues();
+ while (iterBagValues.hasNext()) {
+ AttributeValue<?> attributeValue = iterBagValues.next();
+ FunctionArgument functionArgument = new FunctionArgumentAttributeValue(attributeValue);
+ argListInProgress.add(functionArgument);
+ appendCrossProduct(argListInProgress, valueList, nPosition+1, listArgLists);
+ argListInProgress.remove(argListInProgress.size()-1);
+ }
+ } else {
+ /*
+ * This is a simple value, so we can just append to the argListInProgress and continue the recursion
+ */
+ argListInProgress.add(FunctionArgument);
+ appendCrossProduct(argListInProgress, valueList, nPosition+1, listArgLists);
+ argListInProgress.remove(argListInProgress.size()-1);
+ }
+ }
+
+
+
+
+
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.java
new file mode 100755
index 0000000..a41ccbe
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.java
@@ -0,0 +1,142 @@
+/*
+ * AT&T - PROPRIETARY
+ * THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ * ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ * Copyright (c) 2013 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import java.util.List;
+
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+/**
+ * FunctionDefinitionHomogeneousSimple extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionSimple}
+ * with utility methods for ensuring the types of the arguments passed in the <code>evaluate</code> method matches the parameterized
+ * type, and the number of arguments is correct.
+ * When evaluated the resulting arguments must be simple data types, not bags.
+ *
+ * The various functions have the following needs with respect to their arguments:
+ * <UL>
+ * <LI>
+ * The argument list size is pre-defined and all arguments can be evaluated at once before the function is called.
+ * <LI>
+ * The argument list size is pre-defined but the arguments must be evaluated one at a time by the function.
+ * <LI>
+ * The argument list size is not pre-defined.
+ * </UL>
+ * To support those needs this class includes methods for checking the list size and evaluating a single argument as well as
+ * combining those operations in a single method to make it simpler for the calling function.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ *
+ * @param <O> the java class for the value of the Output return result from the <code>FunctionDefinition</code>
+ * @param <I> the java class for the value of the Input {@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}s in the <code>evaluate</code> method
+ */
+public abstract class FunctionDefinitionHomogeneousSimple<O,I> extends FunctionDefinitionBase<O,I> {
+
+
+ // null means that number of arguments is variable
+ private Integer numArgs;
+
+ /**
+ * Constructor
+ *
+ * @param idIn
+ * @param dataTypeReturnIn
+ * @param dataTypeArgsIn
+ * @param nArgs
+ */
+ public FunctionDefinitionHomogeneousSimple(Identifier idIn, DataType<O> dataTypeReturnIn, DataType<I> dataTypeArgsIn, Integer nArgs) {
+ super(idIn, dataTypeReturnIn, dataTypeArgsIn, false);
+ this.numArgs = nArgs;
+ }
+
+
+ /**
+ * Gets the number of arguments expected to this <code>FunctionDefinition</code>.
+ * For functions without a pre-defined number of arguments this is not used.
+ *
+ * @return the number of arguments expected to this <code>FunctionDefinition</code>.
+ */
+ public Integer getNumArgs() {
+ return this.numArgs;
+ }
+
+
+ /**
+ * Validates the given <code>List</code> of <code>FunctionArgument</code>s has the correct count and <code>DataType</code> and evaluates expressions.
+ * This combines both the argument list length check and the evaluation of all arguments on that list.
+ *
+ * @param listFunctionArguments the <code>List</code> of <code>FunctionArgument</code>s to validate
+ * @return a {@link com.att.research.xacml.api.Status} indication with an error if the arguments are not valid
+ */
+ public Status validateArguments(List<FunctionArgument> listFunctionArguments, List<I> convertedValues) {
+ /*
+ * See if we have to validate the number of arguments
+ */
+ Status listLengthStatus = validateArgumentListLength(listFunctionArguments);
+ if ( ! listLengthStatus.isOk()) {
+ return listLengthStatus;
+ }
+
+
+ /*
+ * Now validate the types of the arguments
+ */
+ for (int i = 0; i < listFunctionArguments.size(); i++) {
+ FunctionArgument functionArgument = listFunctionArguments.get(i);
+ ConvertedArgument<I> argument = new ConvertedArgument<I>(functionArgument, getDataTypeArgs(), false);
+ if ( ! argument.isOk()) {
+ // when a Status is returned that indicates an error, tell caller which arg had problem
+ Status decoratedStatus = new StdStatus(argument.getStatus().getStatusCode(), argument.getStatus().getStatusMessage() + " at arg index " + i );
+ return decoratedStatus;
+ }
+ if (convertedValues != null) {
+ convertedValues.add(argument.getValue());
+ }
+ }
+
+ /*
+ * Everything passed the data type test, so we are good to go
+ */
+ return StdStatus.STATUS_OK;
+ }
+
+
+ /**
+ * Validates the given <code>List</code> of <code>FunctionArgument</code>s has the correct count.
+ *
+ * @param listFunctionArguments the <code>List</code> of <code>FunctionArgument</code>s to validate
+ * @return a {@link com.att.research.xacml.api.Status} indication with an error if the arguments are not valid
+ */
+ public Status validateArgumentListLength(List<FunctionArgument> listFunctionArguments) {
+ /*
+ * See if we have to validate the number of arguments
+ */
+ if ((listFunctionArguments == null && this.numArgs > 0 ) ||
+ (listFunctionArguments != null && this.numArgs != listFunctionArguments.size()) ) {
+ return new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Expected " + this.numArgs + " arguments, got " +
+ ((listFunctionArguments == null) ? 0 : listFunctionArguments.size()) );
+ }
+
+ /*
+ * Everything passed the data type test, so we are good to go
+ */
+ return StdStatus.STATUS_OK;
+ }
+
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.java
new file mode 100755
index 0000000..a99456b
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.java
@@ -0,0 +1,219 @@
+/*
+ * AT&T - PROPRIETARY
+ * THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ * ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ * Copyright (c) 2013 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import java.util.List;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+/**
+ * FunctionDefinitionLogical extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to
+ * implement the XACML Logic predicates as functions taking zero, one, or multiple arguments of type <code>Boolean</code> and returning a <code>Boolean</code>.
+ *
+ * In the first implementation of XACML we had separate files for each XACML Function.
+ * This release combines multiple Functions in fewer files to minimize code duplication.
+ * This file supports the following XACML codes:
+ * or
+ * and
+ * n-of
+ * not
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ */
+public class FunctionDefinitionLogical extends FunctionDefinitionHomogeneousSimple<Boolean,Boolean> {
+
+ /**
+ * List of Logical Operations types
+ *
+ * @author glenngriffin
+ *
+ */
+ public enum OPERATION {OR, AND, N_OF, NOT}
+
+ // the operation that this instance is being asked to do
+ private final OPERATION operation;
+
+
+ public FunctionDefinitionLogical(Identifier idIn, OPERATION op) {
+ super(idIn, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, null);
+ operation = op;
+ }
+
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+
+ switch (operation) {
+ case OR:
+ if (arguments == null || arguments.size() == 0) {
+ return ER_FALSE;
+ }
+ try {
+ // evaluate the arguments one at a time and abort on the first true
+ for (int i = 0; i < arguments.size(); i++) {
+ ConvertedArgument<Boolean> argument = new ConvertedArgument<Boolean>(arguments.get(i), this.getDataTypeArgs(), false);
+ if ( ! argument.isOk()) {
+ // return a decorated message
+ return ExpressionResult.newError(getFunctionStatus(argument.getStatus()));
+ }
+ if (argument.getValue() == true) {
+ return ER_TRUE;
+ }
+ }
+ } catch (Exception e) {
+ String message = e.getMessage();
+ if (e.getCause() != null) {
+ message = e.getCause().getMessage();
+ }
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));
+ }
+ return ER_FALSE;
+
+
+ case AND:
+ if (arguments == null || arguments.size() == 0) {
+ return ER_TRUE;
+ }
+ try {
+ // evaluate the arguments one at a time and abort on the first false
+ for (int i = 0; i < arguments.size(); i++) {
+ ConvertedArgument<Boolean> argument = new ConvertedArgument<Boolean>(arguments.get(i), this.getDataTypeArgs(), false);
+ if ( ! argument.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(argument.getStatus()));
+ }
+ if (argument.getValue() == false) {
+ return ER_FALSE;
+ }
+ }
+
+ } catch (Exception e) {
+ String message = e.getMessage();
+ if (e.getCause() != null) {
+ message = e.getCause().getMessage();
+ }
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));
+ }
+ return ER_TRUE;
+
+
+ case N_OF:
+ Integer argumentCountNeeded;
+ int trueArgumentsSeen = 0;
+ if (arguments == null || arguments.size() == 0) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 1 argument, got 0"));
+ }
+ try {
+ //
+ // Special case:
+ // The first argument in the list (an Integer) is not homogeneous with the rest of the arguments (Booleans).
+ // While this is technically not a FunctionDefinitionHomogeneousSimple type of object, we derive from that class anyway
+ // so that we can take advantage of the validateArgument() method in that class.
+ // Unfortunately we cannot re-use that same code (because of generics - it gets messy) for the Integer argument.
+ // The following code essentially does the same job as validateArgument() on the first argument in the list.
+ //
+
+ // first arg is the number of remaining arguments that must be TRUE
+ if (arguments.get(0) == null) {
+ return ER_TRUE;
+ }
+ if ( ! arguments.get(0).getStatus().isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(arguments.get(0).getStatus()));
+ }
+ if (arguments.get(0).isBag()) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected a simple value, saw a bag"));
+ }
+ AttributeValue<?> attributeValue = arguments.get(0).getValue();
+ if (attributeValue == null) {
+ // assume this is the same as "first argument is 0"
+ return ER_TRUE;
+ }
+
+ argumentCountNeeded = DataTypes.DT_INTEGER.convert(attributeValue.getValue()).intValue();
+ if (argumentCountNeeded == 0) {
+ return ER_TRUE;
+ }
+ if (arguments.size() - 1 < argumentCountNeeded) {
+ // return a non-OK status to signal indeterminate
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Expected " + argumentCountNeeded + " arguments but only " +
+ (arguments.size() - 1) + " arguments in list after the count"));
+ }
+ for (int i = 1; i < arguments.size(); i++) {
+ ConvertedArgument<Boolean> argument = new ConvertedArgument<Boolean>(arguments.get(i), this.getDataTypeArgs(), false);
+ if ( ! argument.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(argument.getStatus()));
+ }
+ if ((argument.getValue()) == true) {
+ trueArgumentsSeen++;
+ if (trueArgumentsSeen >= argumentCountNeeded) {
+ return ER_TRUE;
+ }
+ }
+ // if we cannot reach the goal, stop now.
+ // remaining entries to be looked at = list size - i - 1, which is the most additional TRUEs that we could get.
+ if ( (arguments.size() - i - 1) + trueArgumentsSeen < argumentCountNeeded) {
+ // do not evaluate remaining entries
+ return ER_FALSE;
+ }
+ }
+ // did not reach our goal
+ return ER_FALSE;
+
+ } catch (Exception e) {
+ String message = e.getMessage();
+ if (e.getCause() != null) {
+ message = e.getCause().getMessage();
+ }
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));
+ }
+
+
+ case NOT:
+ if (arguments == null || arguments.size() != 1) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 1 argument, got " +
+ ((arguments == null) ? "null" : arguments.size()) ) );
+ }
+ try {
+ ConvertedArgument<Boolean> argument = new ConvertedArgument<Boolean>(arguments.get(0), this.getDataTypeArgs(), false);
+ if ( ! argument.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(argument.getStatus()));
+ }
+ if (argument.getValue() == true) {
+ return ER_FALSE;
+ } else {
+ return ER_TRUE;
+ }
+ } catch (Exception e) {
+ String message = e.getMessage();
+ if (e.getCause() != null) {
+ message = e.getCause().getMessage();
+ }
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));
+ }
+ }
+
+ // all cases should have been covered by above - should never get here
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Could not evaluate Logical function " + operation));
+
+ }
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.java
new file mode 100755
index 0000000..ce5ec07
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.java
@@ -0,0 +1,90 @@
+/*
+ * AT&T - PROPRIETARY
+ * THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ * ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ * Copyright (c) 2013 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.api.XACML;
+import com.att.research.xacml.std.StdAttributeValue;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+/**
+ * FunctionDefinitionNumberTypeConversion extends {@link FunctionDefinitionHomogeneousSimple} to
+ * implement the XACML predicates foc converting <code>Double</code> to <code>Integer</code> and vice versa.
+ *
+ * In the first implementation of XACML we had separate files for each XACML Function.
+ * This release combines multiple Functions in fewer files to minimize code duplication.
+ * This file supports the following XACML codes:
+ * double-to-integer
+ * integer-to-double
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ * @param <O> the java class for the data type of the function Output
+ * @param <I> the java class for the data type of the function Input argument
+ */
+public class FunctionDefinitionNumberTypeConversion<O extends Number, I extends Number> extends FunctionDefinitionHomogeneousSimple<O, I> {
+
+
+ public FunctionDefinitionNumberTypeConversion(Identifier idIn, DataType<O> outputType, DataType<I> argType) {
+ super(idIn, outputType, argType, 1);
+
+ }
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+ List<I> convertedArguments = new ArrayList<I>();
+ Status status = this.validateArguments(arguments, convertedArguments);
+
+ /*
+ * If the function arguments are not correct, just return an error status immediately
+ */
+ if (!status.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) {
+ return ExpressionResult.newError(getFunctionStatus(status));
+ }
+
+ /*
+ * Numeric operations cannot be operated on generically in java, so we have to check the types and handle separately.
+ * Whichever type the argument is, convert it to the other
+ */
+ ExpressionResult expressionResult;
+ try {
+ if (convertedArguments.get(0).getClass() == BigInteger.class) {
+ AttributeValue<Double> doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE,
+ new Double( ((BigInteger)convertedArguments.get(0)).toString() ) );
+ expressionResult = ExpressionResult.newSingle(doubleResult);
+ } else {
+ AttributeValue<BigInteger> integerResult = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, BigInteger.valueOf(((Double)convertedArguments.get(0)).intValue()) );
+ expressionResult = ExpressionResult.newSingle(integerResult);
+ }
+ } catch (Exception e) {
+ String message = e.getMessage();
+ if (e.getCause() != null) {
+ message = e.getCause().getMessage();
+ }
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));
+ }
+
+ return expressionResult;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.java
new file mode 100755
index 0000000..5015204
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.java
@@ -0,0 +1,141 @@
+/*
+ * AT&T - PROPRIETARY
+ * THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ * ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ * Copyright (c) 2013 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import java.util.List;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacml.std.datatypes.RFC822Name;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+/**
+ * FunctionDefinitionRFC822NameMatch extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to
+ * implement the XACML RFC822Name match predicate as functions taking one <code>String</code> and one <code>RFC822Name</code> arguments
+ * and returning a single <code>Boolean</code> value.
+ *
+ * In the first implementation of XACML we had separate files for each XACML Function.
+ * This release combines multiple Functions in fewer files to minimize code duplication.
+ * This file supports the following XACML codes:
+ * rfc822Name-match
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ */
+public class FunctionDefinitionRFC822NameMatch extends FunctionDefinitionBase<Boolean, RFC822Name> {
+
+
+ /**
+ * Constructor
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ * @param op
+ */
+ public FunctionDefinitionRFC822NameMatch(Identifier idIn) {
+ super(idIn, DataTypes.DT_BOOLEAN, DataTypes.DT_RFC822NAME, false);
+ }
+
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+
+ if (arguments == null || arguments.size() != 2) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() + " Expected 2 arguments, got " +
+ ((arguments == null) ? "null" : arguments.size()) ));
+ }
+
+ // get the string to search for
+ ConvertedArgument<String> stringArgument = new ConvertedArgument<String>(arguments.get(0), DataTypes.DT_STRING, false);
+ if ( ! stringArgument.isOk()) {
+ Status decoratedStatus = new StdStatus(stringArgument.getStatus().getStatusCode(), stringArgument.getStatus().getStatusMessage() + " at arg index 0" );
+ return ExpressionResult.newError(getFunctionStatus(decoratedStatus));
+ }
+ String searchTermString = stringArgument.getValue();
+
+ // get the RFC822Name to match with
+ ConvertedArgument<RFC822Name> rfc822Argument = new ConvertedArgument<RFC822Name>(arguments.get(1), DataTypes.DT_RFC822NAME, false);
+ if ( ! rfc822Argument.isOk()) {
+ Status decoratedStatus = new StdStatus(rfc822Argument.getStatus().getStatusCode(), rfc822Argument.getStatus().getStatusMessage() + " at arg index 1" );
+ return ExpressionResult.newError(getFunctionStatus(decoratedStatus));
+ }
+
+ RFC822Name rfc822Name = rfc822Argument.getValue();
+
+
+ /*
+ * Now perform the match.
+ */
+
+ /*
+ * According to the spec the string must be one of the following 3 things:
+ * - a name with an '@' in it = a full name that must exactly match the whole RFC name (domain part is ignore case)
+ * - a domain name (without an '@' and not starting with a '.') = must match whole RFC domain name (ignore case)
+ * - a partial domain name (without an '@') starting with a '.' = the last part of the RFC domain name (ignore case)
+ */
+
+ String[] searchTerms = searchTermString.split("@");
+
+ if (searchTerms.length > 2) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() +
+ " String contained more than 1 '@' in '" + searchTermString + "'" ));
+ }
+
+ if (searchTerms.length == 2 || searchTermString.endsWith("@")) {
+ // this is an exact match
+ if (searchTerms[0] == null || searchTerms[0].length() == 0) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() +
+ " String missing local part in '" + searchTermString + "'" ));
+ }
+ if (searchTerms.length < 2 || searchTerms[1] == null || searchTerms[1].length() == 0) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, getShortFunctionId() +
+ " String missing domain part in '" + searchTermString + "'" ));
+ }
+
+ // args are ok, so check both against RFC name
+ if (searchTerms[0].equals(rfc822Name.getLocalName()) &&
+ searchTerms[1].toLowerCase().equals(rfc822Name.getCanonicalDomainName())) {
+ return ER_TRUE;
+ } else {
+ return ER_FALSE;
+ }
+ }
+
+ // we have only a domain name, which may be whole or partial
+
+ // make it match the canonical version
+ searchTerms[0] = searchTerms[0].toLowerCase();
+
+ if (searchTerms[0].charAt(0) == '.') {
+ // name is partial - must match the end
+ if (rfc822Name.getCanonicalDomainName().endsWith(searchTerms[0])) {
+ return ER_TRUE;
+ } else {
+ return ER_FALSE;
+ }
+ } else {
+ // name is whole domain - must match exactly
+ if (rfc822Name.getCanonicalDomainName().equals(searchTerms[0])) {
+ return ER_TRUE;
+ } else {
+ return ER_FALSE;
+ }
+ }
+
+ }
+
+}