Initial seed of merged of AT&T and JP Morgan code
diff --git a/openaz-pep/pom.xml b/openaz-pep/pom.xml
new file mode 100755
index 0000000..bcf6443
--- /dev/null
+++ b/openaz-pep/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>openaz</artifactId>
+ <groupId>org.openliberty.openaz</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>openaz-pep</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>openaz-xacml</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>openaz-xacml-pdp</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Action.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Action.java
new file mode 100755
index 0000000..cd7975d
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Action.java
@@ -0,0 +1,62 @@
+package org.openliberty.openaz.pepapi;
+
+import com.att.research.xacml.api.XACML3;
+
+;
+
+/**
+ * Container class that maps attributes to predefined XACML Action category.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public class Action extends CategoryContainer {
+
+ public static final String ACTION_ID_KEY = "ACTION_ID_KEY";
+
+ private String actionIdValue;
+
+ private Action() {
+ super(XACML3.ID_ATTRIBUTE_CATEGORY_ACTION);
+ }
+
+ /**
+ * Creates a new Action instance
+ *
+ * @return
+ */
+ public static Action newInstance() {
+ return new Action();
+ }
+
+ /**
+ * Create a new Action instance containing a single default attribute with the given value
+ *
+ * @param actionIdValue
+ * @return
+ */
+ public static Action newInstance(String actionIdValue) {
+ Action a = new Action();
+ a.actionIdValue = actionIdValue;
+ a.addAttribute(ACTION_ID_KEY, actionIdValue);
+ return a;
+ }
+
+ /**
+ * Get the value for default attribute.
+ *
+ * @return
+ */
+ public String getActionIdValue() {
+ return actionIdValue;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("action-id value: " + actionIdValue);
+ builder.append("\n");
+ builder.append(super.toString());
+ return builder.toString();
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ActionResourcePair.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ActionResourcePair.java
new file mode 100755
index 0000000..4d9cc8c
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ActionResourcePair.java
@@ -0,0 +1,92 @@
+package org.openliberty.openaz.pepapi;
+
+
+/**
+ * A convenient abstraction for an action - resource pair.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public final class ActionResourcePair {
+
+ private final Object action;
+
+ private final Object resource;
+
+ /**
+ * Creates a new action - resource pair
+ *
+ * @param action an Object representing the action being performed.
+ * @param resource an Object representing the resource on which the action is being performed.
+ */
+ public ActionResourcePair(Object action, Object resource){
+ this.resource = resource;
+ this.action = action;
+ }
+
+ /**
+ * Returns the resource associated with this action - resource pair
+ *
+ * @return an Object representing the resource.
+ */
+ public Object getResource() {
+ return resource;
+ }
+
+ /**
+ * Returns the action associated with this action - resource pair.
+ *
+ * @return an Object representing the action.
+ */
+ public Object getAction() {
+ return action;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((action == null) ? 0 : action.hashCode());
+ result = prime * result
+ + ((resource == null) ? 0 : resource.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ ActionResourcePair other = (ActionResourcePair) obj;
+ if (action == null) {
+ if (other.action != null)
+ return false;
+ } else if (!action.equals(other.action)) {
+ return false;
+ }
+
+ if (resource == null) {
+ if (other.resource != null) {
+ return false;
+ }
+ } else if (!resource.equals(other.resource)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("\nAction: " + action.toString());
+ builder.append("\nResource: " + resource.toString());
+ return builder.toString();
+ }
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Advice.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Advice.java
new file mode 100755
index 0000000..46682d0
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Advice.java
@@ -0,0 +1,21 @@
+package org.openliberty.openaz.pepapi;
+
+import java.util.Map;
+
+/**
+ *
+ */
+public interface Advice {
+
+ /**
+ *
+ * @return
+ */
+ public String getId();
+
+ /**
+ *
+ */
+ public Map<String, Object[]> getAttributeMap();
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Attribute.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Attribute.java
new file mode 100755
index 0000000..c6c84bb
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Attribute.java
@@ -0,0 +1,30 @@
+package org.openliberty.openaz.pepapi;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * Represents an Attribute match criterion, where an attribute with the given Id can take any of the values provided.
+ * If no value is available, then value matching is ignored.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+@Target({})
+@Retention(RetentionPolicy.CLASS)
+public @interface Attribute {
+
+ /**
+ *
+ * @return
+ */
+ String id();
+
+ /**
+ *
+ * @return
+ */
+ String[] anyValue() default {};
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/CategoryContainer.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/CategoryContainer.java
new file mode 100755
index 0000000..010bc6f
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/CategoryContainer.java
@@ -0,0 +1,140 @@
+package org.openliberty.openaz.pepapi;
+
+import com.att.research.xacml.api.Identifier;
+
+import java.net.URI;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Abstraction for an attribute container of a specific XACML category.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public class CategoryContainer {
+
+ private final Map<String, Object[]> attributeMap;
+
+ private final Identifier categoryIdentifier;
+
+ CategoryContainer(Identifier categoryIdentifier) {
+ this.categoryIdentifier = categoryIdentifier;
+ this.attributeMap = new HashMap<String, Object[]>();
+ }
+
+ private final void addToMap(String id, Object[] values) {
+ if (values != null && values.length > 0) {
+ attributeMap.put(id, values);
+ }else {
+ throw new IllegalArgumentException("Values cannot be null");
+ }
+ }
+
+ public Identifier getCategoryIdentifier() {
+ return this.categoryIdentifier;
+ }
+
+ /**
+ * Returns all the contained attributes as a Map of key - value pairs.
+ *
+ * @return
+ */
+ public Map<String, Object[]> getAttributeMap() {
+ return Collections.unmodifiableMap(attributeMap);
+ }
+
+ /**
+ * Add a new attribute with the given id and one or more String values
+ *
+ * @param id
+ * @param values
+ * @throws IllegalArgumentException, if values are null;
+ */
+ public void addAttribute(String id, String... values) {
+ addToMap(id, values);
+ }
+
+ /**
+ * Add a new attribute with the given id and one or more Long values
+ *
+ * @param id
+ * @param values
+ * @throws IllegalArgumentException, if values are null;
+ */
+ public void addAttribute(String id, Long... values) {
+ addToMap(id, values);
+ }
+
+ /**
+ * Add a new attribute with the given id and one or more Integer values
+ *
+ * @param id
+ * @param values
+ * @throws IllegalArgumentException, if values are null;
+ */
+ public void addAttribute(String id, Integer... values) {
+ addToMap(id, values);
+ }
+
+ /**
+ * Add a new attribute with the given id and one or more Double values
+ *
+ * @param id
+ * @param values
+ * @throws IllegalArgumentException, if values are null;
+ */
+ public void addAttribute(String id, Double... values) {
+ addToMap(id, values);
+ }
+
+ /**
+ * Add a new attribute with the given id and one or more Boolean values
+ *
+ * @param id
+ * @param values
+ * @throws IllegalArgumentException, if values are null;
+ */
+ public void addAttribute(String id, Boolean... values) {
+ addToMap(id, values);
+ }
+
+ /**
+ * Add a new attribute with the given id and one or more <code>java.util.Date</code> values
+ *
+ * @param id
+ * @param values
+ * @throws IllegalArgumentException, if values are null;
+ */
+ public void addAttribute(String id, Date... values) {
+ addToMap(id, values);
+ }
+
+ /**
+ * Add a new attribute with the given id and one or more URI values
+ *
+ * @param id
+ * @param values
+ * @throws IllegalArgumentException, if values are null;
+ */
+ public void addAttribute(String id, URI... values) {
+ addToMap(id, values);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ for(Entry<String, Object[]> e: attributeMap.entrySet()) {
+ builder.append("Attribute Id: " + e.getKey());
+ builder.append(", Attribute Values: ");
+ for(Object o: e.getValue()) {
+ builder.append(o.toString() + ", ");
+ }
+ builder.append("\n");
+ }
+ return builder.toString();
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Environment.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Environment.java
new file mode 100755
index 0000000..42f8c64
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Environment.java
@@ -0,0 +1,27 @@
+package org.openliberty.openaz.pepapi;
+
+import com.att.research.xacml.api.XACML3;
+
+/**
+ *
+ * Container class that maps attributes to predefined XACML Environment category.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public final class Environment extends CategoryContainer {
+
+ private Environment() {
+ super(XACML3.ID_ATTRIBUTE_CATEGORY_ENVIRONMENT);
+ }
+
+ /**
+ * Creates a new Environment instance
+ *
+ * @return
+ */
+ public static Environment newInstance() {
+ return new Environment();
+ }
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/InvalidAnnotationException.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/InvalidAnnotationException.java
new file mode 100755
index 0000000..39a220b
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/InvalidAnnotationException.java
@@ -0,0 +1,29 @@
+package org.openliberty.openaz.pepapi;
+
+/**
+ * RuntimeException thrown when a registered handler class does not contain one of the
+ * required annotations - <code>@MatchAnyObligation</code>, <code>@MatchAllObligationAttributes</code>.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+@SuppressWarnings("serial")
+public class InvalidAnnotationException extends RuntimeException {
+
+ public InvalidAnnotationException() {
+ super();
+ }
+
+ public InvalidAnnotationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidAnnotationException(String message) {
+ super(message);
+ }
+
+ public InvalidAnnotationException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MapperRegistry.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MapperRegistry.java
new file mode 100755
index 0000000..41ea381
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MapperRegistry.java
@@ -0,0 +1,35 @@
+package org.openliberty.openaz.pepapi;
+
+
+/**
+ * Container that holds <code>ObjectMapper</code> instances registered with the framework.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public interface MapperRegistry {
+
+ /**
+ * Registers the provided ObjectMapper instance
+ *
+ * @param mapper
+ */
+ public void registerMapper(ObjectMapper mapper);
+
+ /**
+ * Registers the provided ObjectMapper instances
+ *
+ * @param mappers
+ */
+ public void registerMappers(Iterable<? extends ObjectMapper> mappers);
+
+ /**
+ * Returns the ObjectMapper instance registered for the given Class.
+ *
+ * @param clazz
+ * @return an ObjectMapper instance
+ * @throws org.openliberty.openaz.pepapi.PepException if no ObjectMapper could be found for class clazz;
+ */
+ public ObjectMapper getMapper(Class<?> clazz);
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.java
new file mode 100755
index 0000000..19f2859
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.java
@@ -0,0 +1,25 @@
+package org.openliberty.openaz.pepapi;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Represents a union of Obligation Attribute match criterion.
+ * All attribute criterion supplied will be conjunctively matched by the framework.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MatchAllObligationAttributes {
+
+ /**
+ *
+ * @return
+ */
+ Attribute[] value();
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAnyObligation.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAnyObligation.java
new file mode 100755
index 0000000..502c3fd
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAnyObligation.java
@@ -0,0 +1,25 @@
+package org.openliberty.openaz.pepapi;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Represents an Obligation criteria that matches any of the supplied Obligation ids.
+ * If no ids are provided, then any Obligation will be matched(catch-all).
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MatchAnyObligation {
+
+ /**
+ *
+ * @return
+ */
+ String[] value() default {};
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Matchable.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Matchable.java
new file mode 100755
index 0000000..554523f
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Matchable.java
@@ -0,0 +1,19 @@
+package org.openliberty.openaz.pepapi;
+
+/**
+ * Interface that abstracts an object that can be matched. Concrete implementations provide a match() function.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ * @param <T>
+ */
+public interface Matchable<T> {
+
+ /**
+ * Returns a boolean result after matching the given Object
+ *
+ * @param t
+ * @return a <code>boolean</code> value
+ */
+ public boolean match(T t);
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObjectMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObjectMapper.java
new file mode 100755
index 0000000..0af85d9
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObjectMapper.java
@@ -0,0 +1,47 @@
+package org.openliberty.openaz.pepapi;
+
+
+
+/**
+ * Converts a Java Class (typically an application Domain Object) into request attributes of some Category.
+ * Applications are expected to provide only a single ObjectMapper instance per Domain Type.
+ *
+ * Typically, there is a one-to-one relationship between the Domain Type and Attribute Category. The interface, however, takes
+ * a general approach allowing a Domain Type to be mapped to multiple categories.
+ *
+ * The conversion for the most part involves obtaining a <code>CategoryAttributes</code> instance for a specific category from the
+ * request context and then mapping Object properties as name-value pairs using one of the overloaded <code>setAttribute</code>
+ * methods.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public interface ObjectMapper {
+
+ /**
+ * Returns a Class that represents the mapped domain type.
+ *
+ * @return a Class object
+ */
+ public Class<?> getMappedClass();
+
+ /**
+ * Maps Object properties to attributes
+ *
+ * @param o - an instance of the domain object to be mapped
+ * @param pepRequest - the current Request Context
+ */
+ public void map(Object o, PepRequest pepRequest);
+
+ /**
+ *
+ * @param mapperRegistry
+ */
+ public void setMapperRegistry(MapperRegistry mapperRegistry);
+
+ /**
+ *
+ * @param pepConfig
+ */
+ public void setPepConfig(PepConfig pepConfig);
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Obligation.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Obligation.java
new file mode 100755
index 0000000..76f3656
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Obligation.java
@@ -0,0 +1,44 @@
+package org.openliberty.openaz.pepapi;
+
+import java.util.Map;
+
+/**
+ * The Obligation interface provides access to an Obligation
+ * object implementation that contains a set of zero or more
+ * Attributes.
+ * <p>
+ * The Obligation has an id: {@link #getId()}
+ * <p>
+ * Each attribute has an id, as well, which are used as the key Strings
+ * of the Maps returned by method:
+ * <ul>
+ * <li>{@link #getAttributeMap()}</li>
+ * </ul>
+ * Each key String has an associated value, which can be an
+ * an array of Objects.
+ * <p>
+ *
+ * @author Josh Bregman, Rich Levinson, Prateek Mishra
+ *
+ */
+public interface Obligation {
+
+ /**
+ * Return the Id for this Obligation.
+ *
+ * @return a string containing the Id of this Obligation
+ */
+ public String getId();
+
+ /**
+ * Returns a Map of Obligation Attribute name,object-value-array pairs,
+ * indexed by name, where name is the AttributeId and the value
+ * is an array of one or more Object values of the "attribute"
+ * (where an array with length > 1 indicates a multi-valued attribute).
+ * <p>
+ * @return a Map of String (AttributeId name), Object array
+ * (Attribute values) pairs
+ */
+ public Map<String, Object[]> getAttributeMap();
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandler.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandler.java
new file mode 100755
index 0000000..13cd008
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandler.java
@@ -0,0 +1,11 @@
+package org.openliberty.openaz.pepapi;
+
+
+/**
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public interface ObligationHandler extends Matchable<Obligation>, ObligationStoreAware {
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.java
new file mode 100755
index 0000000..a76733f
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.java
@@ -0,0 +1,20 @@
+package org.openliberty.openaz.pepapi;
+
+
+import java.util.Map;
+
+/**
+ * Abstraction for a Obligation Handler registration mechanism. Subclasses provide specific implementations.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ */
+public interface ObligationHandlerRegistry {
+
+ /**
+ * Returns a Map of <code>Matchable</code> implementations keyed by handler Class.
+ *
+ * @return
+ */
+ public Map<Class<?>, Matchable<Obligation>> getRegisteredHandlerMap();
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationRouter.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationRouter.java
new file mode 100755
index 0000000..1d3b368
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationRouter.java
@@ -0,0 +1,18 @@
+package org.openliberty.openaz.pepapi;
+
+import java.util.Map;
+
+/**
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public interface ObligationRouter {
+
+ /**
+ *
+ * @param obligationMap
+ */
+ public void routeObligations(Map<String, Obligation> obligationMap);
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStore.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStore.java
new file mode 100755
index 0000000..9b65f95
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStore.java
@@ -0,0 +1,27 @@
+package org.openliberty.openaz.pepapi;
+
+import java.util.Set;
+
+/**
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public interface ObligationStore {
+
+ /**
+ *
+ * @param oHandlerClass
+ * @return
+ */
+ public Set<Obligation> getHandlerObligations(Class<?> oHandlerClass);
+
+ /**
+ *
+ * @param oHandlerClass
+ * @param obligationId
+ * @return
+ */
+ public Obligation getHandlerObligationById(Class<?> oHandlerClass, String obligationId);
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStoreAware.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStoreAware.java
new file mode 100755
index 0000000..99a65a2
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStoreAware.java
@@ -0,0 +1,17 @@
+package org.openliberty.openaz.pepapi;
+
+
+/**
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public interface ObligationStoreAware {
+
+ /**
+ *
+ * @param oStore
+ */
+ public void setObligationStore(ObligationStore oStore);
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgent.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgent.java
new file mode 100755
index 0000000..20b95fb
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgent.java
@@ -0,0 +1,89 @@
+package org.openliberty.openaz.pepapi;
+
+import java.util.List;
+
+/**
+ *
+ * Serves as the main entry point into the PepAPI framework. It coordinates authorization request creation, execution and
+ * response assemblage. Applications typically work with a single instance of PepAgent which is thread-safe.
+ *
+ * The <code>decide()</code> method, which provides the most general mechanism for authorization, accepts a collection of application Domain Objects,
+ * each with it's own <code>ObjectMapper</code> defined. The client application thus passes these Domain Objects directly, <code>decide()</code> uses
+ * reflection to determine their type, and then finds a type-specific mapper.
+ *
+ * This mechanism relies on application defined library of Object Mappers, one for each Domain Object that the client
+ * program expects to use in an authorization call.
+ *
+ * It is important to note that Java Primitives/Wrappers and other standard types(except Collections) are not supported out of the box.
+ * This is primarily because there is no sensible default mapping between a Java Standard Type and a XACML category and hence
+ * it's impossible for the framework to make a mapping decision at runtime. However, client applications may enforce their own rules as
+ * they see fit by providing Custom ObjectMapper(s) for these types.
+ *
+ * <code>simpleDecide()</code> method addresses the simplest of use cases where attributes involved are simple userId, actionId and resourceId Strings.
+ *
+ * <code>bulkDecide()</code> provides an abstraction for a MultiRequest, where in client applications may provide collection of Domain Object
+ * bindings/associations each of which map to individual requests. The method separates out Domain Object associations with multiple cardinality
+ * from the ones shared across requests.
+ *
+ * Thus, in a <code>bulkDecide()</code> call applications provide two sets of arguments:
+ * - a List of Domain Object bindings, each of which map to an individual request.
+ * - a collection of common Domain Objects shared across all requests.
+ *
+ * Specific AzService implementations(PDP Providers) may implement bulkDecide() as a XACML MultiRequest (Note: XACML Multi Decision Profile is optional)
+ * or as individual requests executed iteratively.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public interface PepAgent {
+
+
+ /**
+ * Returns a authorization decision for the given subjectId, actionId,
+ * resourceId Strings.
+ *
+ * @param subjectId
+ * @param actionId
+ * @param resourceId
+ * @return
+ * @throws PepException
+ * - if an appropriate ObjectMapper cannot be found.
+ * - if the underlying AzService instance/PDP throws an exception
+ * - if the PepAgent is configured to throw PepExceptions for "Indeterminate" or "Not Applicable" decisions.
+ * @throws IllegalArgumentException if any of the arguments are null
+ */
+ public PepResponse simpleDecide(String subjectId, String actionId, String resourceId);
+
+ /**
+ * Returns an authorization decision for the given collection of Domain Objects each with it's own
+ * ObjectMapper instance. Java Primitives/Wrappers or other Standard types (except Collections) are not supported
+ * out of the box. However, client applications may enforce their own rules as they see fit by providing Custom ObjectMapper(s)
+ * for these types.
+ *
+ * @param objects
+ * @return
+ * @throws PepException
+ * - if an appropriate ObjectMapper cannot be found.
+ * - if the underlying AzService instance/PDP throws an exception
+ * - if the PepAgent is configured to throw PepException for "Indeterminate" or "Not Applicable" decisions.
+ * @throws IllegalArgumentException if any of the arguments are null
+ */
+ public PepResponse decide(Object... objects);
+
+ /**
+ * Returns a PepResponse instance representing a collection of decisions, each of which corresponds to
+ * an association. Each association represents a specific instance of Domain Object binding. A typical example for an association
+ * would be an Action-Resource pair.
+ *
+ * @param associations a list of Domain Object bindings, each of which maps to a individual Request.
+ * @param objects a collection of common Domain Objects shared across all Requests.
+ * @return
+ * @throws PepException
+ * - if an appropriate ObjectMapper cannot be found.
+ * - if the underlying AzService instance/PDP throws an exception
+ * - if the PepAgent is configured to throw PepExceptions for "Indeterminate" or "Not Applicable" decisions.
+ * @throws IllegalArgumentException if any of the arguments are null
+ */
+ public List<PepResponse> bulkDecide(List<?> associations, Object... objects);
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgentFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgentFactory.java
new file mode 100755
index 0000000..3cb7601
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgentFactory.java
@@ -0,0 +1,16 @@
+package org.openliberty.openaz.pepapi;
+
+/**
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public interface PepAgentFactory {
+
+ /**
+ * Returns a PepAgent instance
+ *
+ * @return
+ */
+ public PepAgent getPepAgent();
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepConfig.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepConfig.java
new file mode 100755
index 0000000..897c2f1
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepConfig.java
@@ -0,0 +1,51 @@
+package org.openliberty.openaz.pepapi;
+
+import java.util.List;
+
+/**
+ * @authors Ajith Nair, David Laurance, Darshak Kothari
+ */
+public interface PepConfig {
+
+ /**
+ *
+ * @return
+ */
+ public String getIssuer();
+
+ /**
+ *
+ * @return
+ */
+ public String getDefaultSubjectId();
+
+ /**
+ *
+ * @return
+ */
+ public String getDefaultResourceId();
+
+ /**
+ *
+ * @return
+ */
+ public String getDefaultActionId();
+
+ /**
+ *
+ * @return
+ */
+ public PepResponseBehavior getIndeterminateBehavior();
+
+ /**
+ *
+ * @return
+ */
+ public PepResponseBehavior getNotApplicableBehavior();
+
+ /**
+ *
+ * @return
+ */
+ public List<String> getMapperClassNames();
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepException.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepException.java
new file mode 100755
index 0000000..6f141d6
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepException.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright 2009-2011 Oracle, Inc.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Authors:
+ * 1.1 (2011): Rich Levinson, Prateek Mishra (Oracle)
+ * 1.0 (2009): Josh Bregman, Rich Levinson, Prateek Mishra (Oracle)
+ * Contributor:
+ * Rich Levinson (Oracle)
+ */
+package org.openliberty.openaz.pepapi;
+
+/**
+ * The PepException is used to provide additional
+ * information to callers of the PepApi when
+ * exception conditions occur.
+ * <p>
+ * PepApi 1.1: now extends RuntimeException in order
+ * that users do not require try/catch blocks
+ * when using PepApi 1.1.
+ * <p>
+ * @author Josh Bregman, Rich Levinson, Prateek Mishra
+ */
+public class PepException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Create a PepException containing a Throwable that
+ * specifies the cause of this PepException.
+ * @param cause
+ */
+ public PepException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Create a PepException containing the message provided
+ * and a Throwable containing further information as to
+ * the cause of the PepException.
+ * @param message
+ * @param cause
+ */
+ public PepException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Create a PepException containing the message provided.
+ * @param message
+ */
+ public PepException(String message) {
+ super(message);
+ }
+
+ public PepException() {super();}
+}
+
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequest.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequest.java
new file mode 100755
index 0000000..fe7391c
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequest.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright 2009-2011 Oracle, Inc.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Authors:
+ * (2014): Ajith Nair, David Laurance
+ * 1.1 (2011): Rich Levinson, Prateek Mishra (Oracle)
+ * 1.0 (2009): Josh Bregman, Rich Levinson, Prateek Mishra (Oracle)
+ * Contributor:
+ * Rich Levinson (Oracle)
+ */
+package org.openliberty.openaz.pepapi;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Request;
+
+/**
+ *
+ * @author Josh Bregman, Rich Levinson, Prateek Mishra
+ *
+ */
+public interface PepRequest {
+
+ /**
+ * Returns a PepRequestAttributes instance that represents the attribute category identified
+ * by the categoryIdentfier parameter.
+ *
+ * @param categoryIdentifier an identifier for a category
+ */
+ public PepRequestAttributes getPepRequestAttributes(Identifier categoryIdentifier);
+
+ /**
+ *
+ * @return
+ */
+ public Request getWrappedRequest();
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestAttributes.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestAttributes.java
new file mode 100755
index 0000000..b011e9b
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestAttributes.java
@@ -0,0 +1,128 @@
+package org.openliberty.openaz.pepapi;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.RequestAttributes;
+
+import java.net.URI;
+import java.util.Date;
+
+/**
+ * Convenient wrapper around a RequestAttributes{@link com.att.research.xacml.api.RequestAttributes} instance,
+ * representing a collection of request attributes that belong to a particular category.
+ *
+ */
+public interface PepRequestAttributes {
+
+ /**
+ * Returns an Indentifier representing the attribute category that the PepRequestAttributes encapsulates
+ *
+ * @return Identifier
+ */
+ public Identifier getCategory();
+
+ /**
+ * Returns an id representing the xml:id
+ *
+ * @return Identifier
+ */
+ public String getId();
+
+ /**
+ * Creates and adds an attribute with the name as the AttributeId,
+ * Date array elements as AttributeValue(s) into the underlying attribute collection.
+ * The attribute will NOT be returned by the PDP in the response after request evaluation.
+ *
+ * @param name
+ * a string with a name to be used as AttributeId
+ * @param values
+ * a Date array to be used as AttributeValue(s)
+ * @throws IllegalArgumentException if the array is null
+ */
+ public void addAttribute(String name, Date... values);
+
+ /**
+ * Creates and adds an attribute with the name as the AttributeId,
+ * String array elements as AttributeValue(s) into the underlying attribute collection.
+ * The attribute will NOT be returned by the PDP in the response after request evaluation.
+ *
+ * @param name
+ * a string with a name to be used as AttributeId
+ * @param values
+ * a String array to be used as AttributeValue(s)
+ * @throws IllegalArgumentException if the array is null
+ */
+ public void addAttribute(String name, String... values);
+
+ /**
+ * Creates and adds an attribute with the name as the AttributeId,
+ * Integer array elements as AttributeValue(s) into the underlying attribute collection.
+ * The attribute will NOT be returned by the PDP in the response after request evaluation.
+ *
+ * @param name
+ * a string with a name to be used as AttributeId
+ * @param values
+ * an Integer array to be used as AttributeValue(s)
+ * @throws IllegalArgumentException if the array is null
+ */
+ public void addAttribute(String name, Integer... values);
+
+ /**
+ * Creates and adds an attribute with the name as the AttributeId,
+ * Boolean array elements as AttributeValue(s) into the underlying attribute collection.
+ * The attribute will NOT be returned by the PDP in the response after request evaluation.
+ *
+ * @param name
+ * a string with a name to be used as AttributeId
+ * @param values
+ * a Boolean array to be used as AttributeValue(s)
+ * @throws IllegalArgumentException if the array is null
+ */
+ public void addAttribute(String name, Boolean... values);
+
+
+ /**
+ * Creates and adds an attribute with the name as the AttributeId,
+ * Long array elements as AttributeValue(s) into the underlying attribute collection.
+ * The attribute will NOT be returned by the PDP in the response after request evaluation.
+ *
+ * @param name
+ * a string with a name to be used as AttributeId
+ * @param values
+ * a Long array to be used as AttributeValue(s)
+ * @throws IllegalArgumentException if the array is null
+ */
+ public void addAttribute(String name, Long... values);
+
+ /**
+ * Creates and adds an attribute with the name as the AttributeId,
+ * Double array elements as AttributeValue(s) into the underlying attribute collection.
+ * The attribute will NOT be returned by the PDP in the response after request evaluation.
+ *
+ * @param name
+ * a string with a name to be used as AttributeId
+ * @param values
+ * a Double array to be used as AttributeValue(s)
+ * @throws IllegalArgumentException if the array is null
+ */
+ public void addAttribute(String name, Double... values);
+
+ /**
+ * Creates and adds an attribute with the name as the AttributeId,
+ * URI array elements as AttributeValue(s) into the underlying attribute collection.
+ * The attribute will NOT be returned by the PDP in the response after request evaluation.
+ *
+ * @param name
+ * a string AttributeId of the attribute being set
+ * @param values
+ * a URI array to be used as AttributeValue(s
+ * @throws IllegalArgumentException if the array is null
+ */
+ public void addAttribute(String name, URI... values);
+
+ /**
+ *
+ * @return
+ */
+ public RequestAttributes getWrappedRequestAttributes();
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestFactory.java
new file mode 100755
index 0000000..5b9a2ee
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestFactory.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright 2009-2011 Oracle, Inc.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Authors:
+ * 1.1 (2011): Rich Levinson, Prateek Mishra (Oracle)
+ * 1.0 (2009): Josh Bregman, Rich Levinson, Prateek Mishra (Oracle)
+ * Contributor:
+ * Rich Levinson (Oracle)
+ */
+package org.openliberty.openaz.pepapi;
+
+import java.util.List;
+
+/**
+ *
+ * @author Josh Bregman, Rich Levinson, Prateek Mishra
+ *
+ */
+public interface PepRequestFactory {
+
+ /**
+ *
+ * @return
+ * @throws org.openliberty.openaz.pepapi.PepException, if no ObjectMappers found.
+ * @throws IllegalArgumentException,, if any argument is null.
+ */
+ public PepRequest newPepRequest(Object[] objects);
+
+ /**
+ *
+ * @param associations
+ * @param objects
+ * @return
+ * @throws org.openliberty.openaz.pepapi.PepException, if ObjectMappers are not found.
+ * @throws IllegalArgumentException,, if the arguments are null.
+ */
+ public PepRequest newBulkPepRequest(List<?> associations, Object[] objects);
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponse.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponse.java
new file mode 100755
index 0000000..b27ea6b
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponse.java
@@ -0,0 +1,72 @@
+package org.openliberty.openaz.pepapi;
+
+import com.att.research.xacml.api.Attribute;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Result;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * @author Josh Bregman, Rich Levinson, Prateek Mishra
+ */
+public interface PepResponse {
+
+ /**
+ * Returns the decision associated with the current result.
+ * @return true if the user was granted access to the resource,
+ * otherwise false
+ * @throws PepException if the {@link PepResponseBehavior}
+ * configured in the {@link PepResponseFactory}
+ * indicates that for the response should be thrown
+ */
+ public boolean allowed() throws PepException;
+
+ /**
+ * Return the set of {@link org.openliberty.openaz.pepapi.Obligation}s associated with the
+ * current result indexed by ObligationId.
+ * @return a Map of ObligationId, Obligation pairs
+ * @throws PepException
+ * @see org.openliberty.openaz.pepapi.Obligation#getId()
+ */
+ public Map<String, Obligation> getObligations() throws PepException;
+
+ /**
+ * Return the set of {@link org.openliberty.openaz.pepapi.Advice}s associated with the
+ * current result indexed by adviceId.
+ * @return a Map of adviceId, Advice pairs
+ * @throws PepException
+ * @see org.openliberty.openaz.pepapi.Advice#getId()
+ */
+ public Map<String, Advice> getAdvices() throws PepException;
+
+ /**
+ * Return the object association that is tied to the current
+ * result. The association is the same object that was
+ * used to create the PepRequest and may be used to
+ * correlate the PepResponse results with the association
+ * pairs that were used to create the PepRequest.
+ * @return an object that was used as the action-resource in the PepRequest
+ * @throws PepException
+ */
+ public Object getAssociation() throws PepException;
+
+ /**
+ *
+ * @return
+ */
+ public Collection<Attribute> getAttributes();
+
+ /**
+ *
+ * @return
+ */
+ public Map<Identifier, Collection<Attribute>> getAttributesByCategory();
+
+ /**
+ *
+ * @return
+ */
+ public Result getWrappedResult();
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseBehavior.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseBehavior.java
new file mode 100755
index 0000000..ad1c70d
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseBehavior.java
@@ -0,0 +1,22 @@
+package org.openliberty.openaz.pepapi;
+
+/**
+ * This enum provides the options that can be set using the
+ * {@link org.openliberty.openaz.pepapi.PepResponseFactory} to determine the behavior when
+ * {@link org.openliberty.openaz.pepapi.PepResponse#allowed()} is called AND the
+ * decision is either Indeterminate or NotApplicable.
+ *
+ * @author Josh Bregman, Rich Levinson, Prateek Mishra
+ *
+ */
+public enum PepResponseBehavior {
+
+ /** The behavior is to allow (Permit) access by returning true when the condition for which this behavior is assigned occurs */
+ RETURN_YES,
+
+ /** The behavior is to disallow (Deny) access by returning false when the condition for which this behavior is assigned occurs */
+ RETURN_NO,
+
+ /** The behavior is to disallow (Deny) access by throwing a PepException when the condition for which this behavior is assigned occurs */
+ THROW_EXCEPTION
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseFactory.java
new file mode 100755
index 0000000..82b92c7
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseFactory.java
@@ -0,0 +1,51 @@
+package org.openliberty.openaz.pepapi;
+
+import com.att.research.xacml.api.Result;
+
+/**
+ * Factory for creating and configuring <code>PepResponse</code>.
+ * <br>
+ * This class creates {@link org.openliberty.openaz.pepapi.PepResponse} objects and configures
+ * the behavior of how the <code>PepResponse</code> interprets the
+ * results from the AzService or any other PDP that is supported
+ * by an implementation of PepApi (org.openliberty.openaz.azapi.pep.*).
+ * <br>
+ * The {@link PepResponseBehavior} that is invoked when
+ * {@link org.openliberty.openaz.pepapi.PepResponse#allowed()} is called and the associated status code
+ * has been returned by the PDP and is being handled by the PepResponse
+ * provider impl, can be configured to be one of:
+ * <ul>
+ * <li>
+ * {@link org.openliberty.openaz.pepapi.PepResponse#allowed()} returns true (PERMIT: {@link PepResponseBehavior#RETURN_YES}),
+ * <li>
+ * {@link org.openliberty.openaz.pepapi.PepResponse#allowed()} returns false (DENY: {@link PepResponseBehavior#RETURN_NO}),
+ * <li>
+ * or{@link org.openliberty.openaz.pepapi.PepResponse#allowed()} throws an exception (DENY: {@link PepResponseBehavior#THROW_EXCEPTION}).
+ * </ul>
+ * <p>
+ * In general, a Permit returns true, and a Deny returns false,
+ * but there are also other types of returns, including
+ * NotApplicable and Indeterminate. The configuration is to
+ * specify for each of the 4 xacml-defined conditions, what
+ * the behavior will be. i.e. for each of the "special"
+ * conditions there is a choice to return either true (Permit),
+ * false (Deny), or throw an Exception.
+ * <p>
+ * In addition, PDP-specific status codes can be specified, such
+ * that when the impl detects one of the configured status codes
+ * has been returned, then the {@link PepResponseBehavior} configured
+ * for that status code will be returned.
+ * <p>
+ * Finally, a default {@link PepResponseBehavior} may be configured
+ * for any status code that has not been explicitly configured
+ * or does not have its own default provided by the impl. The
+ * default if the statusCode default has not been configured is
+ * {@link PepResponseBehavior#THROW_EXCEPTION}.
+ * <p>
+ * @author Josh Bregman, Rich Levinson, Prateek Mishra
+ */
+public interface PepResponseFactory {
+
+ public PepResponse newPepResponse(Result result);
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseType.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseType.java
new file mode 100755
index 0000000..09b6203
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseType.java
@@ -0,0 +1,25 @@
+package org.openliberty.openaz.pepapi;
+
+/**
+ *
+ * @author Josh Bregman, Rich Levinson, Prateek Mishra
+ */
+public enum PepResponseType {
+ /** The PepResponse returned for this query type will contain
+ * only the list of resource action associations that are
+ * allowed.
+ */
+ ONLY_ALLOWED_RESULTS,
+ /**
+ * The PepResponse returned for this query type will contain
+ * only the list of resource action associations that are
+ * denied.
+ */
+ ONLY_DENIED_RESULTS,
+ /** The PepResponse returned for this query type will contain
+ * the complete list of results for each resource action association
+ * that was requested, including allowed, denied, notapplicable,
+ * and indeterminate.
+ */
+ ALL_RESULTS;
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PostDecisionHandler.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PostDecisionHandler.java
new file mode 100755
index 0000000..851f3a1
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PostDecisionHandler.java
@@ -0,0 +1,24 @@
+package org.openliberty.openaz.pepapi;
+
+/**
+ * An interface that may be implemented to process the
+ * PepResponse that is returned from the main decide()
+ * call before the final results are returned to the user.
+ *
+ * @author Josh Bregman, Rich Levinson, Prateek Mishra
+ *
+ */
+public interface PostDecisionHandler {
+
+ /**
+ * This method is used to apply post-decision custom
+ * processing to the {@link org.openliberty.openaz.pepapi.PepResponse} after it has
+ * been returned.
+ *
+ * @param request
+ * @throws org.openliberty.openaz.pepapi.PepException
+ */
+ public void postDecide(PepRequest request, PepResponse response)
+ throws PepException;
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PreDecisionHandler.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PreDecisionHandler.java
new file mode 100755
index 0000000..472c9e8
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PreDecisionHandler.java
@@ -0,0 +1,23 @@
+package org.openliberty.openaz.pepapi;
+
+/**
+ * An interface that can be used for preliminary processing
+ * of a PepRequest before it is actually submitted to the
+ * main decide() method.
+ *
+ * @author Josh Bregman, Rich Levinson, Prateek Mishra
+ *
+ */
+public interface PreDecisionHandler {
+
+ /**
+ * This method is used to apply preliminary custom
+ * processing to the {@link org.openliberty.openaz.pepapi.PepRequest} prior to its
+ * being submitted.
+ *
+ * @param request
+ * @throws org.openliberty.openaz.pepapi.PepException
+ */
+ public void preDecide(PepRequest request)
+ throws PepException;
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Resource.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Resource.java
new file mode 100755
index 0000000..aa878d1
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Resource.java
@@ -0,0 +1,129 @@
+package org.openliberty.openaz.pepapi;
+
+import com.att.research.xacml.api.XACML3;
+
+import java.net.URI;
+import java.util.Date;
+
+/**
+ * Container class that maps attributes to predefined XACML Resource category.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public final class Resource extends CategoryContainer {
+
+ public static final String RESOURCE_ID_KEY = "RESOURCE_ID_KEY";
+
+ private Object resourceIdValue;
+
+ private Resource(){
+ super(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
+ }
+
+ /**
+ * Creates a new Resource instance
+ *
+ * @return
+ */
+ public static Resource newInstance() {
+ return new Resource();
+ }
+
+ /**
+ * Creates a new Resource instance containing a single default attribute with the given String value.
+ *
+ * @param resourceIdValue
+ * @return
+ */
+ public static Resource newInstance(String resourceIdValue) {
+ Resource r = new Resource();
+ r.resourceIdValue = resourceIdValue;
+ r.addAttribute(RESOURCE_ID_KEY, resourceIdValue);
+ return r;
+ }
+
+ /**
+ * Creates a new Resource instance containing a single default attribute with the given URI value.
+ *
+ * @param resourceIdValue
+ * @return
+ */
+ public static Resource newInstance(URI resourceIdValue) {
+ Resource r = new Resource();
+ r.resourceIdValue = resourceIdValue;
+ r.addAttribute(RESOURCE_ID_KEY, resourceIdValue);
+ return r;
+ }
+
+ /**
+ * Creates a new Resource instance containing a single default attribute with the given Long value.
+ *
+ * @param resourceIdValue
+ * @return
+ */
+ public static Resource newInstance(Long resourceIdValue) {
+ Resource r = new Resource();
+ r.resourceIdValue = resourceIdValue;
+ r.addAttribute(RESOURCE_ID_KEY, resourceIdValue);
+ return r;
+ }
+
+ /**
+ * Creates a new Resource instance containing a single default attribute with the given Double value.
+ *
+ * @param resourceIdValue
+ * @return
+ */
+ public static Resource newInstance(Double resourceIdValue) {
+ Resource r = new Resource();
+ r.resourceIdValue = resourceIdValue;
+ r.addAttribute(RESOURCE_ID_KEY, resourceIdValue);
+ return r;
+ }
+
+ /**
+ * Creates a new Resource instance containing a single default attribute with the given Boolean value.
+ *
+ * @param resourceIdValue
+ * @return
+ */
+ public static Resource newInstance(Boolean resourceIdValue) {
+ Resource r = new Resource();
+ r.resourceIdValue = resourceIdValue;
+ r.addAttribute(RESOURCE_ID_KEY, resourceIdValue);
+ return r;
+ }
+
+ /**
+ * Creates a new Resource instance containing a single default attribute with the given <code>java.util.Date</code> value.
+ *
+ * @param resourceIdValue
+ * @return
+ */
+ public static Resource newInstance(Date resourceIdValue) {
+ Resource r = new Resource();
+ r.resourceIdValue = resourceIdValue;
+ r.addAttribute(RESOURCE_ID_KEY, resourceIdValue);
+ return r;
+ }
+
+ /**
+ * Returns the value of the default resourceIdValue attribute
+ *
+ * @return
+ */
+ public Object getResourceIdValue() {
+ return resourceIdValue;
+ }
+
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("resource-id value : " + resourceIdValue);
+ builder.append("\n");
+ builder.append(super.toString());
+ return builder.toString();
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Subject.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Subject.java
new file mode 100755
index 0000000..011be09
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Subject.java
@@ -0,0 +1,60 @@
+package org.openliberty.openaz.pepapi;
+
+import com.att.research.xacml.api.XACML3;
+
+/**
+ * Container class that maps attributes to predefined XACML AccessSubject category.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public class Subject extends CategoryContainer {
+
+ public static final String SUBJECT_ID_KEY = "SUBJECT_ID_KEY";
+
+ private String subjectIdValue;
+
+ private Subject() {
+ super(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT);
+ }
+
+ /**
+ * Creates a new Subject instance
+ *
+ * @return
+ */
+ public static Subject newInstance() {
+ return new Subject();
+ }
+
+ /**
+ * Creates a new Subject instance containing a single default attribute with the given String value.
+ *
+ * @param subjectIdValue
+ * @return
+ */
+ public static Subject newInstance(String subjectIdValue) {
+ Subject s = new Subject();
+ s.subjectIdValue = subjectIdValue;
+ s.addAttribute(SUBJECT_ID_KEY, subjectIdValue);
+ return s;
+ }
+
+ /**
+ * Returns the value of the default subjectIdValue attribute
+ *
+ * @return
+ */
+ public String getSubjectIdValue() {
+ return subjectIdValue;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("subject-id value : " + subjectIdValue);
+ builder.append("\n");
+ builder.append(super.toString());
+ return builder.toString();
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/UnhandleableObligationException.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/UnhandleableObligationException.java
new file mode 100755
index 0000000..7c52cb6
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/UnhandleableObligationException.java
@@ -0,0 +1,27 @@
+package org.openliberty.openaz.pepapi;
+
+/**
+ * Runtime Exception thrown when the framework cannot find a registered handler to deal with the obligation.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+@SuppressWarnings("serial")
+public class UnhandleableObligationException extends RuntimeException {
+
+ public UnhandleableObligationException() {
+ super();
+ }
+
+ public UnhandleableObligationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public UnhandleableObligationException(String message) {
+ super(message);
+ }
+
+ public UnhandleableObligationException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/package.html b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/package.html
new file mode 100755
index 0000000..40d15ff
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/package.html
@@ -0,0 +1,75 @@
+<html>
+<body>
+The goal of this
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/pep/package-summary.html"
+>"PepApi interface package"</a>
+is to provide a set of interfaces that provide a framework
+that will simplify the creation of Policy Enforcement Points (PEPs)
+that use an underlying authorization provider that is accessed through the
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/package-summary.html"
+>"AzApi"</a> package.
+<p>
+To accomplish this goal, the PepApi interface package provides a common
+interface that applications and containers can use to make authorization
+calls to possibly any kind of authorization provider that uses a
+request/response interface.
+<p>
+To keep the common interface both flexible and easy to use, this
+PepApi package makes some simplifying assumptions:
+
+<P>
+<ul>
+ <li>An authorization request context can be one of three varieties:
+ <ul>
+ <li>A single request for authorization of a single action on
+ a single resource
+ <li>A bulk request that consists of multiple single requests.
+ <li>A query request that returns (in minimal or verbose form)
+ the set of decisions on all resources and actions within a "scope"
+ </ul>
+ <li>An authorization request consists of a single subject,
+ a single action, and a single resource, with an optional environment
+ <li>Most applications can represent the subject,action,resource as Strings.
+ <li>Most applications need the Date, Boolean, Double, Integer, String, Time and DateTime types of XACML
+ <li>All attributes have a single issuer
+ <li>Some applications need to represent the subject,action,resource as an object with attributes (i.e a Map)
+ <li>Some frameworks and containers needs to represent the subject,action,resources as native objects, and want to
+ use the same API as their applications.
+ <li>An authorization response is primarily a yes/no decision
+ <li>Applications use obligations, and want to consume the attributes of the obligation as Strings.
+
+</ul>
+</P>
+The pep package is a simple layer on top of the azapi package.
+All of the state is held inside of the classes in the azapi package.
+This was done for both simplicity and to accommodate the creation of PEPs
+that can benefit from the simpler API but may need a little more than the
+above assumptions allow.
+This additional capability is accomplished by being able to retrieve the
+AzApiRequestContext from the PepRequest and being able to retrieve the
+AzApiResponseContext from the PepResponse.
+Since all of the state is in the azapi package, PEPs can just grab a
+handle and continue building the request or processing the response.
+<p>
+Note: the "scope" of the PepApi has been conceptually expanded to
+include non-AzApi authorization providers as well as AzApi-based
+providers. This change has not impacted the PepApi, but it has impacted
+how to most effectively conceptualize the implementations of PepApi.
+<p>
+The primary concept is to consider the
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/package-summary.html"
+>reference impl</a>
+to be an application of a general framework, where this particular
+instance the framework is being applied to an AzApi-packaged authorization
+provider. In fact, the
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/provider/SimpleConcreteSunXacmlService.html"
+>"reference AzApi SunXacml PDP impl"</a>,
+may be considered to be just such an "AzApi-packaged" provider.
+<p>
+There is a tutorial provided with the
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/package-summary.html#package_description"
+>PepApiImpl</a>
+package javadoc page that provides general guidelines for implementing a
+non-AzApi provider to be used by PepApi.
+</body>
+</html>
\ No newline at end of file
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionMapper.java
new file mode 100755
index 0000000..be24376
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionMapper.java
@@ -0,0 +1,22 @@
+package org.openliberty.openaz.pepapi.std;
+
+
+import org.openliberty.openaz.pepapi.Action;
+
+/**
+ * Created by ajith on 12/11/14.
+ */
+public class ActionMapper extends CategoryContainerMapper {
+
+ public ActionMapper() {
+ super(Action.class);
+ }
+
+ @Override
+ protected String resolveAttributeId(String attributeId) {
+ if(attributeId.equals(Action.ACTION_ID_KEY)) {
+ return getPepConfig().getDefaultActionId();
+ }
+ return attributeId;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.java
new file mode 100755
index 0000000..ff97b85
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.java
@@ -0,0 +1,35 @@
+package org.openliberty.openaz.pepapi.std;
+
+
+import org.openliberty.openaz.pepapi.*;
+
+public final class ActionResourcePairMapper implements ObjectMapper {
+
+ private MapperRegistry mapperRegistry;
+
+ private PepConfig pepConfig;
+
+ @Override
+ public Class<?> getMappedClass() {
+ return ActionResourcePair.class;
+ }
+
+ @Override
+ public void map(Object o, PepRequest pepRequest) {
+ ActionResourcePair actionResource = (ActionResourcePair)o;
+ Object action = actionResource.getAction();
+ Object resource = actionResource.getResource();
+ mapperRegistry.getMapper(action.getClass()).map(action, pepRequest);
+ mapperRegistry.getMapper(resource.getClass()).map(resource, pepRequest);
+ }
+
+ @Override
+ public void setMapperRegistry(MapperRegistry mapperRegistry) {
+ this.mapperRegistry = mapperRegistry;
+ }
+
+ @Override
+ public void setPepConfig(PepConfig pepConfig) {
+ this.pepConfig = pepConfig;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ArrayMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ArrayMapper.java
new file mode 100755
index 0000000..b614b15
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ArrayMapper.java
@@ -0,0 +1,46 @@
+package org.openliberty.openaz.pepapi.std;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.*;
+
+
+public final class ArrayMapper implements ObjectMapper {
+
+ private static final Log logger = LogFactory.getLog(ArrayMapper.class);
+
+ private PepConfig pepConfig;
+
+ private MapperRegistry mapperRegistry;
+
+ @Override
+ public Class<Object[]> getMappedClass() {
+ return Object[].class;
+ }
+
+ @Override
+ public void map(Object o, PepRequest pepRequest) {
+ Object[] array = (Object[])o;
+ if(array != null && array.length > 0) {
+ ObjectMapper mapper = mapperRegistry.getMapper(array[0].getClass());
+ if(mapper != null) {
+ for(Object item: array) {
+ mapper.map(item, pepRequest);
+ }
+ }else {
+ logger.error("Can't map an Object of class: " + array[0].getClass().getName());
+ throw new PepException("Can't map an Object of class: " + array[0].getClass().getName());
+ }
+ }
+ }
+
+ @Override
+ public void setMapperRegistry(MapperRegistry mapperRegistry) {
+ this.mapperRegistry = mapperRegistry;
+ }
+
+ @Override
+ public void setPepConfig(PepConfig pepConfig) {
+ this.pepConfig = pepConfig;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.java
new file mode 100755
index 0000000..115368f
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.java
@@ -0,0 +1,95 @@
+package org.openliberty.openaz.pepapi.std;
+
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.*;
+
+import java.net.URI;
+import java.util.Date;
+import java.util.Map;
+import java.util.Map.Entry;
+
+
+public class CategoryContainerMapper implements ObjectMapper {
+
+ private static final Log logger = LogFactory.getLog(CategoryContainerMapper.class);
+
+ private Class<?> mappedClass;
+
+ private MapperRegistry mapperRegistry;
+
+ private PepConfig pepConfig;
+
+ public CategoryContainerMapper(Class<?> mappedClass) {
+ this.mappedClass = mappedClass;
+ }
+
+ @Override
+ public Class<?> getMappedClass() {
+ return this.mappedClass;
+ }
+
+ @Override
+ public void map(Object o, PepRequest pepRequest) {
+ CategoryContainer a = (CategoryContainer)o;
+ PepRequestAttributes pepRequestAttributes = pepRequest.getPepRequestAttributes(a.getCategoryIdentifier());
+ Map<String, Object[]> aMap = a.getAttributeMap();
+ if(aMap != null) {
+ for(Entry<String, Object[]> e: aMap.entrySet()) {
+ String attributeId = resolveAttributeId(e.getKey());
+ Object[] values = e.getValue();
+ if(values != null && values.length > 0) {
+ map(pepRequestAttributes, attributeId, values);
+ } else {
+ logger.error("No value assigned for attribute : " + attributeId);
+ throw new IllegalArgumentException("No or null value for attribute : " + attributeId);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void setMapperRegistry(MapperRegistry mapperRegistry) {
+ this.mapperRegistry = mapperRegistry;
+ }
+
+ @Override
+ public void setPepConfig(PepConfig pepConfig) {
+ this.pepConfig = pepConfig;
+ }
+
+ protected String resolveAttributeId(String attributeId) {
+ return attributeId;
+ }
+
+ private final void map(PepRequestAttributes pepRequestAttributes, String key, Object... values) {
+ Object value = values[0];
+ if (value instanceof String) {
+ pepRequestAttributes.addAttribute(key, (String[]) values);
+ } else if (value instanceof Long) {
+ pepRequestAttributes.addAttribute(key, (Long[]) values);
+ } else if (value instanceof Integer) {
+ pepRequestAttributes.addAttribute(key, (Integer[]) values);
+ } else if (value instanceof Double) {
+ pepRequestAttributes.addAttribute(key, (Double[]) values);
+ } else if (value instanceof Boolean) {
+ pepRequestAttributes.addAttribute(key, (Boolean[]) values);
+ } else if (value instanceof URI) {
+ pepRequestAttributes.addAttribute(key, (URI[]) values);
+ } else if (value instanceof Date) {
+ pepRequestAttributes.addAttribute(key, (Date[]) values);
+ }else {
+ logger.error("Type: " + value.getClass().getName() + " cannot be mapped for attribute: " + key);
+ throw new PepException("Can't map an object of class: " + value.getClass().getName());
+ }
+ }
+
+ protected PepConfig getPepConfig() {
+ return this.pepConfig;
+ }
+
+ protected MapperRegistry getMapperRegistry() {
+ return this.mapperRegistry;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CollectionMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CollectionMapper.java
new file mode 100755
index 0000000..dd6df7b
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CollectionMapper.java
@@ -0,0 +1,46 @@
+package org.openliberty.openaz.pepapi.std;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.*;
+
+import java.util.Collection;
+
+
+public final class CollectionMapper implements ObjectMapper {
+
+ private static final Log logger = LogFactory.getLog(CollectionMapper.class);
+
+ private MapperRegistry mapperRegistry;
+
+ private PepConfig pepConfig;
+
+ @Override
+ public Class<?> getMappedClass() {
+ return Collection.class;
+ }
+
+ @Override
+ public void map(Object o, PepRequest pepRequest) {
+ Collection<?> collection = (Collection<?>)o;
+ for(Object item: collection) {
+ ObjectMapper mapper = mapperRegistry.getMapper(item.getClass());
+ if(mapper != null) {
+ mapper.map(item, pepRequest);
+ }else {
+ logger.error("Can't map an Object of class: " + item.getClass().getName());
+ throw new PepException("Can't map an Object of class: " + item.getClass().getName());
+ }
+ }
+ }
+
+ @Override
+ public void setMapperRegistry(MapperRegistry mapperRegistry) {
+ this.mapperRegistry = mapperRegistry;
+ }
+
+ @Override
+ public void setPepConfig(PepConfig pepConfig) {
+ this.pepConfig = pepConfig;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.java
new file mode 100755
index 0000000..9c11151
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.java
@@ -0,0 +1,13 @@
+package org.openliberty.openaz.pepapi.std;
+
+
+import org.openliberty.openaz.pepapi.Obligation;
+
+public final class MatchAnyCriterion implements ObligationCriterion {
+
+ @Override
+ public boolean match(Obligation obligation) {
+ return true;
+ }
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MultiRequest.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MultiRequest.java
new file mode 100755
index 0000000..f19836e
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MultiRequest.java
@@ -0,0 +1,123 @@
+package org.openliberty.openaz.pepapi.std;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.RequestReference;
+import com.att.research.xacml.std.StdMutableRequest;
+import com.att.research.xacml.std.StdMutableRequestReference;
+import com.att.research.xacml.std.StdRequestAttributesReference;
+import org.openliberty.openaz.pepapi.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ *
+ */
+final class MultiRequest implements PepRequest {
+
+ private static final String REQUEST_ATTR_ID_PREFIX = "attributes";
+
+ private final Map<Identifier, PepRequestAttributes> pepRequestAttributesMapByCategory;
+
+ private final MapperRegistry mapperRegistry;
+
+ private final PepConfig pepConfig;
+
+ private final Object[] sharedRequestObjects;
+
+ private List<?> associations;
+
+ private final AtomicInteger idCounter;
+
+ private final StdMutableRequest wrappedRequest;
+
+ private StdMutableRequestReference currentRequestReference;
+
+ private RequestReference sharedRequestReference;
+
+ static MultiRequest newInstance(PepConfig pepConfig, MapperRegistry mapperRegistry, List<?> associations, Object[] sharedRequestObjects) {
+ MultiRequest m = new MultiRequest(pepConfig, mapperRegistry, associations, sharedRequestObjects);
+ m.mapSharedRequestObjects();
+ m.mapAssociations();
+ return m;
+ }
+
+ private MultiRequest(PepConfig pepConfig, MapperRegistry mapperRegistry, List<?> associations, Object[] sharedRequestObjects) {
+ this.pepRequestAttributesMapByCategory = new HashMap<Identifier, PepRequestAttributes>();
+ this.sharedRequestObjects = sharedRequestObjects;
+ this.associations = associations;
+ this.mapperRegistry = mapperRegistry;
+ this.pepConfig = pepConfig;
+ this.idCounter = new AtomicInteger(1);
+ this.wrappedRequest = new StdMutableRequest();
+ this.currentRequestReference = new StdMutableRequestReference();
+ }
+
+ private void mapSharedRequestObjects() {
+ if(sharedRequestObjects == null) {
+ throw new IllegalArgumentException("One or more arguments are null");
+ }
+ for(Object o: sharedRequestObjects) {
+ if(o == null) {
+ throw new IllegalArgumentException("One or more arguments are null");
+ }
+ ObjectMapper mapper = mapperRegistry.getMapper(o.getClass());
+ if(mapper == null) {
+ throw new IllegalArgumentException("No mappers found for class: " + o.getClass().getName());
+ }
+ mapper.map(o, this);
+ }
+ //Collect
+ sharedRequestReference = currentRequestReference;
+ }
+
+ private void mapAssociations() {
+ if(associations == null) {
+ throw new IllegalArgumentException("One or more arguments are null");
+ }
+ for(Object association: associations) {
+ if(association == null) {
+ throw new IllegalArgumentException("One or more arguments are null");
+ }
+
+ //Prepare
+ pepRequestAttributesMapByCategory.clear();
+ currentRequestReference = new StdMutableRequestReference(sharedRequestReference.getAttributesReferences());
+ wrappedRequest.add(currentRequestReference);
+
+ //Map
+ ObjectMapper mapper = mapperRegistry.getMapper(association.getClass());
+ if(mapper == null) {
+ throw new IllegalArgumentException("No mappers found for class: " + association.getClass().getName());
+ }
+ mapper.map(association, this);
+ }
+ }
+
+ @Override
+ public PepRequestAttributes getPepRequestAttributes(Identifier categoryIdentifier) {
+ PepRequestAttributes pepRequestAttributes = pepRequestAttributesMapByCategory.get(categoryIdentifier);
+ if(pepRequestAttributes == null) {
+ String xmlId = generateRequestAttributesXmlId();
+ StdPepRequestAttributes p = new StdPepRequestAttributes(xmlId, categoryIdentifier);
+ p.setIssuer(pepConfig.getIssuer());
+ pepRequestAttributes = p;
+ pepRequestAttributesMapByCategory.put(categoryIdentifier, pepRequestAttributes);
+ wrappedRequest.add(pepRequestAttributes.getWrappedRequestAttributes());
+ currentRequestReference.add(new StdRequestAttributesReference(xmlId));
+ }
+ return pepRequestAttributes;
+ }
+
+ private String generateRequestAttributesXmlId() {
+ return REQUEST_ATTR_ID_PREFIX + idCounter.getAndIncrement();
+ }
+
+ @Override
+ public Request getWrappedRequest() {
+ return wrappedRequest;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.java
new file mode 100755
index 0000000..23f00cb
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.java
@@ -0,0 +1,87 @@
+package org.openliberty.openaz.pepapi.std;
+
+import org.openliberty.openaz.pepapi.Obligation;
+
+import java.util.*;
+
+public final class ObligationAttributeCriterion implements ObligationCriterion {
+
+ private String id;
+
+ private Set<String> valueSet;
+
+ public ObligationAttributeCriterion(String id) {
+ this.id = id;
+ this.valueSet = new HashSet<String>();
+ }
+
+ ObligationAttributeCriterion(String id, String...values) {
+ this(id);
+ if(values != null && values.length > 0){
+ this.valueSet.addAll(Arrays.asList(values));
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ result = prime * result
+ + ((valueSet == null) ? 0 : valueSet.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ObligationAttributeCriterion other = (ObligationAttributeCriterion) obj;
+ if (id == null) {
+ if (other.id != null)
+ return false;
+ } else if (!id.equals(other.id))
+ return false;
+ if (valueSet == null) {
+ if (other.valueSet != null)
+ return false;
+ } else if (!valueSet.equals(other.valueSet))
+ return false;
+ return true;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public Set<String> getValueSet() {
+ return Collections.unmodifiableSet(valueSet);
+ }
+
+ @Override
+ public boolean match(Obligation obligation) {
+ Map<String, Object[]> obligationAttrMap = obligation.getAttributeMap();
+ if(!obligationAttrMap.containsKey(this.id)) {
+ return false;
+ }
+ //Proceed with value matching, if the AttributeMatch has a defined value set to match.
+ if(!valueSet.isEmpty()) {
+ Object[] attributeValues = obligationAttrMap.get(this.id);
+ boolean valueFound = false;
+ if(attributeValues != null) {
+ for(Object attributeValue: attributeValues) {
+ if(valueSet.contains(attributeValue)) {
+ valueFound = true;
+ break;
+ }
+ }
+ }
+ return valueFound;
+ }
+ return true;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteria.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteria.java
new file mode 100755
index 0000000..8a32271
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteria.java
@@ -0,0 +1,28 @@
+package org.openliberty.openaz.pepapi.std;
+
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.Matchable;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+public final class ObligationCriteria implements Matchable<Obligation> {
+
+ private Set<ObligationCriterion> criteria;
+
+ ObligationCriteria(Collection<ObligationCriterion> criteria){
+ this.criteria = new HashSet<ObligationCriterion>();
+ this.criteria.addAll(criteria);
+ }
+
+ @Override
+ public boolean match(Obligation obligation) {
+ for(ObligationCriterion criterion: criteria){
+ if(!criterion.match(obligation)){
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.java
new file mode 100755
index 0000000..3572bec
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.java
@@ -0,0 +1,37 @@
+package org.openliberty.openaz.pepapi.std;
+
+
+
+import java.util.HashSet;
+import java.util.Set;
+
+
+public final class ObligationCriteriaBuilder {
+
+ private Set<ObligationCriterion> criteria = new HashSet<ObligationCriterion>();
+
+ public ObligationCriteriaBuilder matchAttribute(String attributeId) {
+ criteria.add(new ObligationAttributeCriterion(attributeId));
+ return this;
+ }
+
+ public ObligationCriteriaBuilder matchAttributeWithAnyGivenValue(String attributeId,
+ String... values) {
+ criteria.add(new ObligationAttributeCriterion(attributeId, values));
+ return this;
+ }
+
+ public ObligationCriteriaBuilder matchAnyObligationId(String... obligationIds) {
+ criteria.add(new ObligationIdCriterion(obligationIds));
+ return this;
+ }
+
+ public ObligationCriteriaBuilder matchAnyObligation() {
+ criteria.add(new MatchAnyCriterion());
+ return this;
+ }
+
+ public final ObligationCriteria build() {
+ return new ObligationCriteria(criteria);
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriterion.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriterion.java
new file mode 100755
index 0000000..82d8af1
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriterion.java
@@ -0,0 +1,10 @@
+package org.openliberty.openaz.pepapi.std;
+
+
+import org.openliberty.openaz.pepapi.Obligation;
+
+public interface ObligationCriterion {
+
+ public boolean match(Obligation obligation);
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.java
new file mode 100755
index 0000000..3763b87
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.java
@@ -0,0 +1,25 @@
+package org.openliberty.openaz.pepapi.std;
+
+import org.openliberty.openaz.pepapi.Obligation;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public final class ObligationIdCriterion implements ObligationCriterion {
+
+ private Set<String> obligationIdSet;
+
+ public ObligationIdCriterion(String... obligationIds){
+ this.obligationIdSet = new HashSet<String>();
+ if(obligationIds != null) {
+ this.obligationIdSet.addAll(Arrays.asList(obligationIds));
+ }
+ }
+
+ @Override
+ public boolean match(Obligation obligation) {
+ return this.obligationIdSet.contains(obligation.getId());
+ }
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/PepUtils.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/PepUtils.java
new file mode 100755
index 0000000..983a811
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/PepUtils.java
@@ -0,0 +1,84 @@
+package org.openliberty.openaz.pepapi.std;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.*;
+import java.util.Properties;
+
+/**
+ *
+ */
+public class PepUtils {
+
+ private static final Log logger = LogFactory.getLog(PepUtils.class);
+
+ public static Class<?> loadClass(String className) {
+ ClassLoader currentClassLoader = PepUtils.class.getClassLoader();
+ Class<?> clazz;
+ try {
+ clazz = currentClassLoader.loadClass(className);
+ } catch (ClassNotFoundException e) {
+ ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+ try {
+ clazz = contextClassLoader.loadClass(className);
+ } catch (ClassNotFoundException e1) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+ return clazz;
+ }
+
+
+ public static <T> T instantiateClass(Class<T> clazz) {
+ try {
+ return clazz.newInstance();
+ } catch (InstantiationException e) {
+ throw new IllegalArgumentException(e);
+ } catch (IllegalAccessException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+
+ public static Properties loadProperties(String propertyFile) {
+ Properties properties = new Properties();
+
+ //Try the location as a file first.
+ File file = new File(propertyFile);
+ InputStream in;
+ if(file.exists() && file.canRead()) {
+ if (!file.isAbsolute()) {
+ file = file.getAbsoluteFile();
+ }
+ try {
+ in = new FileInputStream(file);
+ } catch (FileNotFoundException e) {
+ logger.info(propertyFile + " is not a file.");
+ }
+ }
+
+ in = PepUtils.class.getResourceAsStream(propertyFile);
+
+ if(in == null) {
+ logger.error("Invalid classpath of file location: " + propertyFile);
+ throw new IllegalArgumentException("Invalid classpath or file location: " + propertyFile);
+ }
+
+ try {
+ properties.load(in);
+ } catch (IOException e) {
+ logger.error(e);
+ throw new IllegalArgumentException(e);
+ } finally {
+ if(in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ logger.debug("Error closing stream", e);
+ }
+ }
+ }
+ return properties;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ResourceMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ResourceMapper.java
new file mode 100755
index 0000000..113d781
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ResourceMapper.java
@@ -0,0 +1,22 @@
+package org.openliberty.openaz.pepapi.std;
+
+
+import org.openliberty.openaz.pepapi.Resource;
+
+/**
+ * Created by ajith on 12/11/14.
+ */
+public class ResourceMapper extends CategoryContainerMapper {
+
+ public ResourceMapper() {
+ super(Resource.class);
+ }
+
+ @Override
+ protected String resolveAttributeId(String attributeId) {
+ if(attributeId.equals(Resource.RESOURCE_ID_KEY)) {
+ return getPepConfig().getDefaultResourceId();
+ }
+ return attributeId;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdAdvice.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdAdvice.java
new file mode 100755
index 0000000..6649bac
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdAdvice.java
@@ -0,0 +1,47 @@
+package org.openliberty.openaz.pepapi.std;
+
+import com.att.research.xacml.api.AttributeAssignment;
+import org.openliberty.openaz.pepapi.Advice;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+final class StdAdvice implements Advice {
+
+ private com.att.research.xacml.api.Advice wrappedAdvice;
+
+ StdAdvice(com.att.research.xacml.api.Advice advice) {
+ this.wrappedAdvice = advice;
+ }
+
+ /**
+ * Return the Id for this Advice.
+ *
+ * @return a string containing the Id of this Advice
+ */
+ public String getId(){
+ return wrappedAdvice.getId().stringValue();
+ }
+
+ @Override
+ public Map<String, Object[]> getAttributeMap() {
+ Map<String, List<Object>> map = new HashMap<String, List<Object>>();
+ for(AttributeAssignment a: wrappedAdvice.getAttributeAssignments()) {
+ String attributeId = a.getAttributeId().stringValue();
+ List<Object> values = map.get(attributeId);
+ if(values == null) {
+ values = new ArrayList<Object>();
+ map.put(attributeId, values);
+ }
+ values.add(a.getAttributeValue().getValue());
+ }
+ Map<String, Object[]> attributeMap = new HashMap<String, Object[]>();
+ for(Map.Entry<String, List<Object>> e: map.entrySet()) {
+ attributeMap.put(e.getKey(), e.getValue().toArray(new Object[1]));
+ }
+ return attributeMap;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdMapperRegistry.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdMapperRegistry.java
new file mode 100755
index 0000000..1c05ab3
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdMapperRegistry.java
@@ -0,0 +1,99 @@
+package org.openliberty.openaz.pepapi.std;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+public final class StdMapperRegistry implements MapperRegistry {
+
+ private static final Log logger = LogFactory.getLog(StdMapperRegistry.class);
+
+ private final Map<Class<?>, ObjectMapper> map;
+
+ private PepConfig pepConfig;
+
+ private StdMapperRegistry(PepConfig pepConfig) {
+ //Register defaults.
+ this.pepConfig = pepConfig;
+ map = new HashMap<Class<?>, ObjectMapper>();
+ registerMapper(new CollectionMapper());
+ registerMapper(new ArrayMapper());
+ registerMapper(new SubjectMapper());
+ registerMapper(new ActionMapper());
+ registerMapper(new ResourceMapper());
+ registerMapper(new CategoryContainerMapper(Environment.class));
+ registerMapper(new CategoryContainerMapper(CategoryContainer.class));
+ registerMapper(new ActionResourcePairMapper());
+ }
+
+ public static MapperRegistry newInstance(PepConfig pepConfig) {
+ return new StdMapperRegistry(pepConfig);
+ }
+
+ public static MapperRegistry newInstance(PepConfig pepConfig, List<ObjectMapper> mappers) {
+ MapperRegistry mapperRegistry = newInstance(pepConfig);
+ if(mappers != null) {
+ mapperRegistry.registerMappers(mappers);
+ }
+ return mapperRegistry;
+ }
+
+ @Override
+ public void registerMapper(ObjectMapper mapper) {
+ mapper.setPepConfig(pepConfig);
+ mapper.setMapperRegistry(this);
+ map.put(mapper.getMappedClass(), mapper);
+ }
+
+ @Override
+ public void registerMappers(Iterable<? extends ObjectMapper> mappers) {
+ for(ObjectMapper mapper: mappers) {
+ registerMapper(mapper);
+ }
+ }
+
+ @Override
+ public ObjectMapper getMapper(Class<?> clazz) {
+ ObjectMapper mapper = null;
+ Class<?> c = clazz;
+ while(mapper == null && !c.equals(Object.class)) {
+ mapper = getClassMapper(c);
+ c = c.getSuperclass();
+ }
+
+ //Handle Arrays.
+ if(mapper == null) {
+ if(clazz.isArray()) {
+ mapper = getMapper(Object[].class);
+ }
+ }
+
+ if(mapper != null) {
+ logger.debug("Mapper :" + mapper.getClass().getName() + " found for class: " + clazz);
+ return mapper;
+ }else {
+ throw new PepException("No ObjectMapper found for Object of Class: " + clazz);
+ }
+ }
+
+ private ObjectMapper getClassMapper(Class<?> clazz) {
+ ObjectMapper mapper = map.get(clazz);
+ if(mapper == null) {
+ Class<?>[] interfaces = clazz.getInterfaces();
+ if(interfaces != null && interfaces.length > 0) {
+ for(Class<?> inf: interfaces) {
+ mapper = map.get(inf);
+ if(mapper != null) {
+ break;
+ }
+ }
+ }
+ }
+ return mapper;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligation.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligation.java
new file mode 100755
index 0000000..d2fd1ca
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligation.java
@@ -0,0 +1,48 @@
+package org.openliberty.openaz.pepapi.std;
+
+import com.att.research.xacml.api.AttributeAssignment;
+import org.openliberty.openaz.pepapi.Obligation;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+final class StdObligation implements Obligation {
+
+ private com.att.research.xacml.api.Obligation wrappedObligation;
+
+ StdObligation(com.att.research.xacml.api.Obligation obligation) {
+ this.wrappedObligation = obligation;
+ }
+
+ /**
+ * Return the Id for this Obligation.
+ *
+ * @return a string containing the Id of this Obligation
+ */
+ public String getId(){
+ return wrappedObligation.getId().stringValue();
+ }
+
+ @Override
+ public Map<String, Object[]> getAttributeMap() {
+ Map<String, List<Object>> map = new HashMap<String, List<Object>>();
+ for(AttributeAssignment a: wrappedObligation.getAttributeAssignments()) {
+ String attributeId = a.getAttributeId().stringValue();
+ List<Object> values = map.get(attributeId);
+ if(values == null) {
+ values = new ArrayList<Object>();
+ map.put(attributeId, values);
+ }
+ values.add(a.getAttributeValue().getValue());
+ }
+
+ Map<String, Object[]> attributeMap = new HashMap<String, Object[]>();
+ for(Map.Entry<String, List<Object>> e: map.entrySet()) {
+ attributeMap.put(e.getKey(), e.getValue().toArray(new Object[1]));
+ }
+ return attributeMap;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.java
new file mode 100755
index 0000000..488ce5b
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.java
@@ -0,0 +1,106 @@
+package org.openliberty.openaz.pepapi.std;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.ObligationHandler;
+import org.openliberty.openaz.pepapi.ObligationHandlerRegistry;
+import org.openliberty.openaz.pepapi.Attribute;
+import org.openliberty.openaz.pepapi.MatchAllObligationAttributes;
+import org.openliberty.openaz.pepapi.MatchAnyObligation;
+import org.openliberty.openaz.pepapi.Matchable;
+
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An <code>ObligationHandlerRegistry</code> implementation that accept handler classes that are either ObligationHandler instances
+ * or contain any of the following annotations - <code> @MatchAnyObligation, @MatchAllObligationAttributes</code>
+ * that represents Obligation criteria for registration.
+ *
+ * @author Ajith Nair
+ *
+ */
+public class StdObligationHandlerRegistry implements ObligationHandlerRegistry {
+
+ private static final Log logger = LogFactory.getLog(StdObligationHandlerRegistry.class);
+
+ private final Map<Class<?>, Matchable<Obligation>> oHandlerCriteriaMap;
+
+ private StdObligationHandlerRegistry(List<?> oHandlers) {
+ oHandlerCriteriaMap = new HashMap<Class<?>, Matchable<Obligation>>();
+ for (Object oHandler : oHandlers) {
+ Class<?> oHandlerClass = oHandler.getClass();
+ Matchable<Obligation> matchable = null;
+ if(oHandler instanceof ObligationHandler) {
+ matchable = (ObligationHandler)oHandler;
+ }else {
+ matchable = processAnnotation(oHandlerClass);
+ }
+
+ if (matchable != null) {
+ oHandlerCriteriaMap.put(oHandlerClass, matchable);
+ }else {
+ logger.error("Obligation Handler Class: " + oHandlerClass
+ + " is not an instance of ObligationHandler or doesn't contain a valid Annotation");
+ throw new IllegalArgumentException("Obligation Handler Class: " + oHandlerClass
+ + " is not an instance of ObligationHandler or doesn't contain a valid Annotation");
+ }
+ }
+ }
+
+ /**
+ * Process Annotations in the classes provided and translate those into <code>ObligationCriteria</code>.
+ *
+ * @param oHandlerClass
+ * @return an ObligationCriteria instance.
+ */
+ private ObligationCriteria processAnnotation(Class<?> oHandlerClass) {
+ ObligationCriteria criteria = null;
+ for (Annotation a : oHandlerClass.getAnnotations()) {
+ if (a.annotationType().equals(MatchAnyObligation.class)) {
+ String[] obligationIds = ((MatchAnyObligation) a).value();
+ ObligationCriteriaBuilder criteriaBuilder = new ObligationCriteriaBuilder();
+ if (obligationIds != null && obligationIds.length > 0) {
+ criteriaBuilder.matchAnyObligationId(obligationIds);
+ } else {
+ criteriaBuilder.matchAnyObligation();
+ }
+ criteria = criteriaBuilder.build();
+ } else if (a.annotationType().equals(MatchAllObligationAttributes.class)) {
+ ObligationCriteriaBuilder criteriaBuilder = new ObligationCriteriaBuilder();
+ MatchAllObligationAttributes attributeObligationAnnotation =
+ (MatchAllObligationAttributes) a;
+ for (Attribute attribute : attributeObligationAnnotation.value()) {
+ String attributeId = attribute.id();
+ String[] anyValue = attribute.anyValue();
+ if (anyValue != null && anyValue.length > 0) {
+ criteriaBuilder.matchAttributeWithAnyGivenValue(
+ attributeId, anyValue);
+ } else {
+ criteriaBuilder.matchAttribute(attributeId);
+ }
+ }
+ criteria = criteriaBuilder.build();
+ }
+ }
+ return criteria;
+ }
+
+ /**
+ * Returns a new instance of <code>StdObligationHandlerRegistry</code>.
+ *
+ * @param oHandlers
+ * @return
+ */
+ public static ObligationHandlerRegistry newInstance(List<?> oHandlers) {
+ return new StdObligationHandlerRegistry(oHandlers);
+ }
+
+ @Override
+ public Map<Class<?>, Matchable<Obligation>> getRegisteredHandlerMap() {
+ return this.oHandlerCriteriaMap;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationRouter.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationRouter.java
new file mode 100755
index 0000000..6cf3b2c
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationRouter.java
@@ -0,0 +1,87 @@
+package org.openliberty.openaz.pepapi.std;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.ObligationHandlerRegistry;
+import org.openliberty.openaz.pepapi.ObligationRouter;
+import org.openliberty.openaz.pepapi.UnhandleableObligationException;
+import org.openliberty.openaz.pepapi.Matchable;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * Entity that routes obligations at runtime.
+ *
+ * @see org.openliberty.openaz.pepapi.Obligation
+ * @author Ajith Nair
+ */
+public final class StdObligationRouter implements ObligationRouter {
+
+ private static final Log logger = LogFactory.getLog(StdObligationRouter.class);
+
+ private final ObligationHandlerRegistry registrationHandler;
+
+ private final ThreadLocalObligationStore obligationStore;
+
+ StdObligationRouter(ObligationHandlerRegistry registrationHandler,
+ ThreadLocalObligationStore threadLocalOStore) {
+ this.registrationHandler = registrationHandler;
+ this.obligationStore = threadLocalOStore;
+ }
+
+ public static StdObligationRouter newInstance(
+ ObligationHandlerRegistry registrationHandler,
+ ThreadLocalObligationStore threadLocalOStore) {
+ return new StdObligationRouter(registrationHandler,
+ threadLocalOStore);
+ }
+
+ /**
+ * Handles runtime obligations and routes to appropriate policy enforcement points as required.
+ *
+ * @param obligationMap a <code>Map</code> of <code>Obligation</code>s keyed by Obligation ID.
+ * @throws org.openliberty.openaz.pepapi.UnhandleableObligationException if an Obligation cannot be handled/routed.
+ */
+ @Override
+ public void routeObligations(Map<String, Obligation> obligationMap) {
+ //Clear any stale Obligations on the current thread.
+ obligationStore.clear();
+ if(obligationMap != null) {
+ Map<Class<?>, Set<Obligation>> obligationMapByHandlerClass
+ = new HashMap<Class<?>, Set<Obligation>>();
+ for(Entry<String, Obligation> oe: obligationMap.entrySet()) {
+ boolean isObligationHandleable = false;
+ String obligationId = oe.getKey();
+ Obligation obligation = oe.getValue();
+ for(Entry<Class<?>, Matchable<Obligation>> pe :
+ this.registrationHandler.getRegisteredHandlerMap().entrySet()) {
+ Class<?> handlerClass = pe.getKey();
+ Matchable<Obligation> matchable = pe.getValue();
+ if(matchable.match(obligation)) {
+ Set<Obligation> handlerObligationSet = obligationMapByHandlerClass.get(handlerClass);
+ if(handlerObligationSet == null){
+ handlerObligationSet = new HashSet<Obligation>();
+ obligationMapByHandlerClass.put(handlerClass, handlerObligationSet);
+ }
+ handlerObligationSet.add(obligation);
+ isObligationHandleable = true;
+ if(logger.isDebugEnabled()) {
+ logger.debug("Obligation - " + obligationId + " matched by Handler - " + handlerClass);
+ }
+ }
+ }
+ if(!isObligationHandleable) {
+ throw new UnhandleableObligationException(
+ "No ObligationHandlers available for handling Obligation: "
+ + oe.getKey());
+ }
+ }
+ obligationStore.setObligations(obligationMapByHandlerClass);
+ }
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgent.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgent.java
new file mode 100755
index 0000000..519eefb
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgent.java
@@ -0,0 +1,192 @@
+package org.openliberty.openaz.pepapi.std;
+
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.Response;
+import com.att.research.xacml.api.Result;
+import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.api.pdp.PDPEngineFactory;
+import com.att.research.xacml.api.pdp.PDPException;
+import com.att.research.xacml.std.json.JSONRequest;
+import com.att.research.xacml.std.json.JSONResponse;
+import com.att.research.xacml.std.json.JSONStructureException;
+import com.att.research.xacml.util.FactoryException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.*;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+
+final class StdPepAgent implements PepAgent {
+
+ @SuppressWarnings("unused")
+ private static final Log logger = LogFactory.getLog(StdPepAgent.class);
+
+ private Properties xacmlProperties;
+
+ private PepConfig pepConfig;
+
+ private PDPEngine pdpEngine;
+
+ private PDPEngineFactory pdpEngineFactory;
+
+ private List<ObligationStoreAware> obligationHandlers;
+
+ private PepRequestFactory pepRequestFactory;
+
+ private PepResponseFactory pepResponseFactory;
+
+ StdPepAgent() {
+ obligationHandlers = new ArrayList<ObligationStoreAware>();
+ }
+
+ final void initialize() {
+ assert(pdpEngineFactory != null);
+
+ //Instantiate PDPEngine
+ if(pdpEngine == null) {
+ try {
+ pdpEngine = pdpEngineFactory.newEngine(xacmlProperties);
+ } catch (FactoryException e) {
+ throw new PepException(e);
+ }
+ }
+
+ List<ObjectMapper> objectMappers = new ArrayList<ObjectMapper>();
+ for(String mapperClassName: pepConfig.getMapperClassNames()) {
+ Class<? extends ObjectMapper> clazz = (Class<? extends ObjectMapper>)PepUtils.loadClass(mapperClassName);
+ objectMappers.add(PepUtils.instantiateClass(clazz));
+ }
+ MapperRegistry mapperRegistry = StdMapperRegistry.newInstance(pepConfig, objectMappers);
+
+ ObligationRouter oRouter = null;
+ if(!obligationHandlers.isEmpty()) {
+ ObligationHandlerRegistry oHandlerRegistry = StdObligationHandlerRegistry.newInstance(obligationHandlers);
+ ThreadLocalObligationStore oStore = ThreadLocalObligationStore.newInstance();
+ for(ObligationStoreAware oHandler: obligationHandlers) {
+ oHandler.setObligationStore(oStore);
+ }
+ oRouter = StdObligationRouter.newInstance(oHandlerRegistry, oStore);
+ }
+
+ //Instantiate PepRequestFactory
+ pepRequestFactory = new StdPepRequestFactory(pepConfig, mapperRegistry);
+ //Instantiate PepResponseFactory
+ pepResponseFactory = new StdPepResponseFactory(pepConfig, oRouter);
+ }
+
+ @Override
+ public PepResponse decide(Object... objects) {
+ return decide(pepRequestFactory.newPepRequest(objects)).get(0);
+ }
+
+ @Override
+ public PepResponse simpleDecide(String subjectId, String actionId,
+ String resourceId) {
+ return decide(Subject.newInstance(subjectId), Action.newInstance(actionId), Resource.newInstance(resourceId));
+ }
+
+ @Override
+ public List<PepResponse> bulkDecide(List<?> actionResourcePairs, Object... objects) {
+ return decide(pepRequestFactory.newBulkPepRequest(actionResourcePairs, objects));
+ }
+
+ private List<PepResponse> decide(PepRequest pepRequest) {
+ List<PepResponse> pepResponses = new ArrayList<PepResponse>();
+ Request request = pepRequest.getWrappedRequest();
+
+ //Log request
+ if(logger.isDebugEnabled()) {
+ logRequest(request);
+ }
+
+ Response response;
+ try {
+ response = pdpEngine.decide(request);
+ } catch (PDPException e) {
+ logger.error(e);
+ throw new PepException(e);
+ }
+
+ //Log the response
+ if(logger.isDebugEnabled()) {
+ logResponse(response);
+ }
+
+ for(Result result: response.getResults()) {
+ pepResponses.add(pepResponseFactory.newPepResponse(result));
+ }
+ return pepResponses;
+ }
+
+ private void logRequest(Request request) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try {
+ JSONRequest.convert(request, out);
+ logger.debug(out.toString("UTF-8"));
+ } catch (IOException e) {
+ logger.debug("Error printing XACML request in JSON", e);
+ } catch (JSONStructureException e) {
+ logger.debug("Error printing XACML request in JSON", e);
+ }finally {
+ if(out != null) {
+ try {
+ out.close();
+ } catch (IOException e) {
+ logger.debug("Error closing stream");
+ }
+ }
+ }
+ }
+
+ private void logResponse(Response response) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try {
+ JSONResponse.convert(response, out);
+ logger.debug(out.toString("UTF-8"));
+ } catch (IOException e) {
+ logger.debug("Error printing XACML response in JSON", e);
+ } catch (JSONStructureException e) {
+ logger.debug("Error printing XACML response in JSON", e);
+ }finally {
+ if(out != null) {
+ try {
+ out.close();
+ } catch (IOException e) {
+ logger.debug("Error closing stream");
+ }
+ }
+ }
+ }
+
+ public PDPEngine getPdpEngine() {
+ return pdpEngine;
+ }
+
+ public PepConfig getPepConfig() {
+ return pepConfig;
+ }
+
+ void setPdpEngineFactory(PDPEngineFactory pdpEngineFactory) {
+ this.pdpEngineFactory = pdpEngineFactory;
+ }
+
+ void setPepConfig(PepConfig pepConfig) {
+ this.pepConfig = pepConfig;
+ }
+
+ void setXacmlProperties(Properties properties) {
+ this.xacmlProperties = properties;
+ }
+
+ void setObligationHandlers(List<ObligationStoreAware> obligationHandlers) {
+ if(obligationHandlers != null) {
+ this.obligationHandlers = new ArrayList<ObligationStoreAware>();
+ this.obligationHandlers.addAll(obligationHandlers);
+ }
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.java
new file mode 100755
index 0000000..bcff6fd
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.java
@@ -0,0 +1,59 @@
+package org.openliberty.openaz.pepapi.std;
+
+import com.att.research.xacml.api.pdp.PDPEngineFactory;
+import com.att.research.xacml.util.FactoryException;
+import org.openliberty.openaz.pepapi.*;
+
+import java.util.List;
+import java.util.Properties;
+
+
+public class StdPepAgentFactory implements PepAgentFactory {
+
+ private volatile PepAgent pepAgent;
+
+ private PDPEngineFactory pdpEngineFactory;
+
+ private Properties xacmlProperties;
+
+ private PepConfig pepConfig;
+
+ private List<ObligationStoreAware> obligationHandlers;
+
+ public StdPepAgentFactory(String propertyFile) {
+ this(PepUtils.loadProperties(propertyFile));
+ }
+
+ public StdPepAgentFactory(Properties properties) {
+ this.xacmlProperties = properties;
+ this.pepConfig = new StdPepConfig(properties);
+ try {
+ //FIXME: Error when invoking newInstance() with properties.
+ pdpEngineFactory = PDPEngineFactory.newInstance();
+ } catch (FactoryException e) {
+ throw new PepException(e);
+ }
+ }
+
+ @Override
+ public PepAgent getPepAgent() {
+ if(pepAgent == null) {
+ synchronized(this) {
+ if(this.pepAgent == null) {
+ StdPepAgent pa = new StdPepAgent();
+ pa.setPepConfig(pepConfig);
+ pa.setXacmlProperties(xacmlProperties);
+ pa.setPdpEngineFactory(pdpEngineFactory);
+ pa.setObligationHandlers(obligationHandlers);
+ pa.initialize();
+ pepAgent = pa;
+ }
+ }
+ }
+ return pepAgent;
+ }
+
+ public void setObligationHandlers(List<ObligationStoreAware> obligationHandlers) {
+ this.obligationHandlers = obligationHandlers;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepConfig.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepConfig.java
new file mode 100755
index 0000000..7aee915
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepConfig.java
@@ -0,0 +1,144 @@
+package org.openliberty.openaz.pepapi.std;
+
+import com.att.research.xacml.api.XACML3;
+import com.google.common.base.Splitter;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.PepConfig;
+import org.openliberty.openaz.pepapi.PepResponseBehavior;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+
+public final class StdPepConfig implements PepConfig {
+
+ private static final Log logger = LogFactory.getLog(StdPepConfig.class);
+
+ private static final String PEP_ISSUER = "pep.issuer";
+
+ private static final String PEP_DEFAULT_SUBJECT_ID = "pep.subject.id";
+
+ private static final String PEP_DEFAULT_ACTION_ID = "pep.action.id";
+
+ private static final String PEP_DEFAULT_RESOURCE_ID = "pep.resource.id";
+
+ private static final String PEP_INDETERMINATE_BEHAVIOR = "pep.indeterminate.behavior";
+
+ private static final String PEP_NOTAPPLICABLE_BEHAVIOR = "pep.notapplicable.behavior";
+
+ private static final String PEP_MAPPER_CLASSES = "pep.mapper.classes";
+
+ private String issuer;
+
+ private String subjectIdURI;
+
+ private String actionIdURI;
+
+ private String resourceIdURI;
+
+ private PepResponseBehavior indeterminateBehavior;
+
+ private PepResponseBehavior notApplicableBehavior;
+
+ private List<String> mapperClassNames;
+
+ public StdPepConfig() {
+ //Defaults
+ subjectIdURI = XACML3.ID_SUBJECT_SUBJECT_ID.stringValue();
+ actionIdURI = XACML3.ID_ACTION_ACTION_ID.stringValue();
+ resourceIdURI = XACML3.ID_RESOURCE_RESOURCE_ID.stringValue();
+ indeterminateBehavior = PepResponseBehavior.THROW_EXCEPTION;
+ notApplicableBehavior = PepResponseBehavior.RETURN_NO;
+ mapperClassNames = Collections.EMPTY_LIST;
+ }
+
+ public StdPepConfig(Properties properties) {
+ this();
+ issuer = properties.getProperty(PEP_ISSUER);
+
+ String subjectIdURI = properties.getProperty(PEP_DEFAULT_SUBJECT_ID);
+ if(!StringUtils.isEmpty(subjectIdURI)){
+ this.subjectIdURI = subjectIdURI;
+ }
+
+ String actionIdURI = properties.getProperty(PEP_DEFAULT_ACTION_ID);
+ if(!StringUtils.isEmpty(actionIdURI)) {
+ this.actionIdURI = actionIdURI;
+ }
+
+ String resourceIdURI = properties.getProperty(PEP_DEFAULT_RESOURCE_ID);
+ if(!StringUtils.isEmpty(resourceIdURI)) {
+ this.resourceIdURI = resourceIdURI;
+ }
+
+ String indeterminateString = properties.getProperty(PEP_INDETERMINATE_BEHAVIOR);
+ if(!StringUtils.isEmpty(indeterminateString)) {
+ PepResponseBehavior indeterminateBehavior = PepResponseBehavior.valueOf(indeterminateString);
+ if(indeterminateBehavior == null) {
+ logger.error("Invalid indeterminate behavior found in configuration.");
+ //TODO: Throw exception ?
+ }
+ this.indeterminateBehavior = indeterminateBehavior;
+ }
+
+ String notapplicableString = properties.getProperty(PEP_NOTAPPLICABLE_BEHAVIOR);
+ if(!StringUtils.isEmpty(notapplicableString)) {
+ PepResponseBehavior notApplicableBehavior = PepResponseBehavior.valueOf(notapplicableString);
+ if(notApplicableBehavior == null) {
+ logger.error("Invalid notapplicable behavior found in configuration.");
+ //TODO: Throw exception ?
+ }
+ this.notApplicableBehavior = notApplicableBehavior;
+ }
+
+
+ String mapperClassNameString = properties.getProperty(PEP_MAPPER_CLASSES);
+ if(!StringUtils.isEmpty(mapperClassNameString)) {
+ List mapperClassNames = new ArrayList<String>();
+ for(String className: Splitter.on(",").omitEmptyStrings().trimResults().split(mapperClassNameString)) {
+ mapperClassNames.add(className);
+ }
+ this.mapperClassNames = Collections.unmodifiableList(mapperClassNames);
+ }
+
+ }
+
+ @Override
+ public String getIssuer() {
+ return issuer;
+ }
+
+ @Override
+ public String getDefaultSubjectId() {
+ return subjectIdURI;
+ }
+
+ @Override
+ public String getDefaultResourceId() {
+ return resourceIdURI;
+ }
+
+ @Override
+ public String getDefaultActionId() {
+ return actionIdURI;
+ }
+
+ @Override
+ public PepResponseBehavior getIndeterminateBehavior() {
+ return indeterminateBehavior;
+ }
+
+ @Override
+ public PepResponseBehavior getNotApplicableBehavior() {
+ return notApplicableBehavior;
+ }
+
+ @Override
+ public List<String> getMapperClassNames() {
+ return mapperClassNames;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequest.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequest.java
new file mode 100755
index 0000000..3b08374
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequest.java
@@ -0,0 +1,91 @@
+package org.openliberty.openaz.pepapi.std;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.std.StdMutableRequest;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.*;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+
+final class StdPepRequest implements PepRequest {
+
+ private static final String REQUEST_ATTR_ID_PREFIX = "attributes";
+
+ private static final Log logger = LogFactory.getLog(StdPepRequest.class);
+
+ private final StdMutableRequest wrappedRequest;
+
+ private final Map<Identifier, PepRequestAttributes> pepRequestAttributesMapByCategory;
+
+ private final MapperRegistry mapperRegistry;
+
+ private final PepConfig pepConfig;
+
+ private final Object[] requestObjects;
+
+ private final AtomicInteger idCounter;
+
+ static StdPepRequest newInstance(PepConfig pepConfig, MapperRegistry mapperRegistry, Object[] requestObjects) {
+ StdPepRequest stdPepRequest = new StdPepRequest(pepConfig, mapperRegistry, requestObjects);
+ stdPepRequest.map();
+ return stdPepRequest;
+ }
+
+ /**
+ *
+ * @return
+ */
+ private String generateRequestAttributesXmlId() {
+ return REQUEST_ATTR_ID_PREFIX + idCounter.getAndIncrement();
+ }
+
+ private StdPepRequest(PepConfig pepConfig, MapperRegistry mapperRegistry, Object[] requestObjects) {
+ this.pepConfig = pepConfig;
+ this.mapperRegistry = mapperRegistry;
+ this.requestObjects = requestObjects;
+ this.pepRequestAttributesMapByCategory = new HashMap<Identifier, PepRequestAttributes>();
+ this.idCounter = new AtomicInteger(1);
+ this.wrappedRequest = new StdMutableRequest();
+ }
+
+ @Override
+ public PepRequestAttributes getPepRequestAttributes(Identifier categoryIdentifier) {
+ PepRequestAttributes pepRequestAttributes = pepRequestAttributesMapByCategory.get(categoryIdentifier);
+ if(pepRequestAttributes == null) {
+ String xmlId = generateRequestAttributesXmlId();
+ StdPepRequestAttributes p = new StdPepRequestAttributes(xmlId, categoryIdentifier);
+ p.setIssuer(pepConfig.getIssuer());
+ pepRequestAttributes = p;
+ pepRequestAttributesMapByCategory.put(categoryIdentifier, pepRequestAttributes);
+ wrappedRequest.add(pepRequestAttributes.getWrappedRequestAttributes());
+ }
+ return pepRequestAttributes;
+ }
+
+ private void map() {
+ if(requestObjects == null) {
+ throw new IllegalArgumentException("One or more arguments are null");
+ }
+ for(Object o: requestObjects) {
+ if(o == null) {
+ throw new IllegalArgumentException("One or more arguments are null");
+ }
+ ObjectMapper mapper = mapperRegistry.getMapper(o.getClass());
+ if(mapper == null) {
+ throw new IllegalArgumentException("No mappers found for class: " + o.getClass().getName());
+ }
+ mapper.map(o, this);
+ }
+ }
+
+ @Override
+ public Request getWrappedRequest() {
+ return wrappedRequest;
+ }
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.java
new file mode 100755
index 0000000..40a0409
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.java
@@ -0,0 +1,125 @@
+package org.openliberty.openaz.pepapi.std;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.RequestAttributes;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdAttributeValue;
+import com.att.research.xacml.std.StdMutableAttribute;
+import com.att.research.xacml.std.StdMutableRequestAttributes;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.PepRequestAttributes;
+
+import java.net.URI;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+
+final class StdPepRequestAttributes implements PepRequestAttributes {
+
+ private static final Log log = LogFactory.getLog(StdPepRequestAttributes.class);
+
+ private final String id;
+
+ private final Identifier categoryIdentifier;
+
+ private String issuer;
+
+ private StdMutableRequestAttributes wrappedRequestAttributes;
+
+ //Internal map to hold mutable attributes as StdMutableRequestAttributes
+ // does not return a mutable view of Attributes.
+ private Map<Identifier, StdMutableAttribute> attributeMapById;
+
+ StdPepRequestAttributes(String id, Identifier categoryIdentifier) {
+ this.id = id;
+ this.categoryIdentifier = categoryIdentifier;
+ this.attributeMapById = new HashMap<Identifier, StdMutableAttribute>();
+ this.wrappedRequestAttributes = new StdMutableRequestAttributes();
+ this.wrappedRequestAttributes.setCategory(categoryIdentifier);
+ this.wrappedRequestAttributes.setXmlId(id);
+ }
+
+ @Override
+ public Identifier getCategory() {
+ return categoryIdentifier;
+ }
+
+ @Override
+ public void addAttribute(String name, Date... values) {
+ addAttribute(name, values, XACML3.ID_DATATYPE_DATE);
+ }
+
+ @Override
+ public void addAttribute(String name, String... values) {
+ addAttribute(name, values, XACML3.ID_DATATYPE_STRING);
+ }
+
+ @Override
+ public void addAttribute(String name, Integer... values) {
+ addAttribute(name, values, XACML3.ID_DATATYPE_INTEGER);
+ }
+
+ @Override
+ public void addAttribute(String name, Boolean... values) {
+ addAttribute(name, values, XACML3.ID_DATATYPE_BOOLEAN);
+ }
+
+ @Override
+ public void addAttribute(String name, Long... values) {
+ addAttribute(name, values, XACML3.ID_DATATYPE_INTEGER);
+ }
+
+ @Override
+ public void addAttribute(String name, Double... values) {
+ addAttribute(name, values, XACML3.ID_DATATYPE_DOUBLE);
+ }
+
+ @Override
+ public void addAttribute(String name, URI... values) {
+ addAttribute(name, values, XACML3.ID_DATATYPE_ANYURI);
+ }
+
+ private <T> void addAttribute(String name, T[] values, Identifier dataTypeId) {
+ if(values == null) {
+ throw new IllegalArgumentException("Null attribute value provided for attribute: " + name);
+ }
+ Identifier attributeId = new IdentifierImpl(name);
+ StdMutableAttribute mutableAttribute = attributeMapById.get(attributeId);
+ if(mutableAttribute == null) {
+ mutableAttribute = new StdMutableAttribute();
+ mutableAttribute.setAttributeId(new IdentifierImpl(name));
+ mutableAttribute.setCategory(categoryIdentifier);
+ mutableAttribute.setIncludeInResults(false);
+ mutableAttribute.setIssuer(issuer == null?"":issuer);
+ attributeMapById.put(attributeId, mutableAttribute);
+ wrappedRequestAttributes.add(mutableAttribute);
+ }
+ for(T value: values) {
+ if(value != null) {
+ mutableAttribute.addValue(new StdAttributeValue<T>(dataTypeId, value));
+ }
+ }
+ }
+
+ @Override
+ public RequestAttributes getWrappedRequestAttributes() {
+ return wrappedRequestAttributes;
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ public String getIssuer() {
+ return issuer;
+ }
+
+ public void setIssuer(String issuer) {
+ this.issuer = issuer;
+ }
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.java
new file mode 100755
index 0000000..a6a81b9
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.java
@@ -0,0 +1,40 @@
+package org.openliberty.openaz.pepapi.std;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.MapperRegistry;
+import org.openliberty.openaz.pepapi.PepConfig;
+import org.openliberty.openaz.pepapi.PepRequest;
+import org.openliberty.openaz.pepapi.PepRequestFactory;
+
+import java.util.List;
+
+
+final class StdPepRequestFactory implements PepRequestFactory {
+
+ private static final Log logger = LogFactory.getLog(StdPepRequestFactory.class);
+
+ private final PepConfig pepConfig;
+
+ private final MapperRegistry mapperRegistry;
+
+ /**
+ *
+ * @param pepConfig
+ */
+ StdPepRequestFactory(PepConfig pepConfig, MapperRegistry mapperRegistry) {
+ this.pepConfig = pepConfig;
+ this.mapperRegistry = mapperRegistry;
+ }
+
+ @Override
+ public PepRequest newPepRequest(Object[] objects) {
+ return StdPepRequest.newInstance(pepConfig, mapperRegistry, objects);
+ }
+
+ @Override
+ public PepRequest newBulkPepRequest(List<?> associations, Object[] objects) {
+ return MultiRequest.newInstance(pepConfig, mapperRegistry, associations, objects);
+ }
+
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponse.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponse.java
new file mode 100755
index 0000000..2a19d30
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponse.java
@@ -0,0 +1,127 @@
+package org.openliberty.openaz.pepapi.std;
+
+import com.att.research.xacml.api.*;
+import com.att.research.xacml.api.Attribute;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.Advice;
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+
+final class StdPepResponse implements PepResponse {
+
+ private static final Log logger = LogFactory.getLog(StdPepResponse.class);
+
+ private final Result wrappedResult;
+
+ private final PepConfig pepConfig;
+
+ private final ObligationRouter obligationRouter;
+
+ static PepResponse newInstance(PepConfig pepConfig, ObligationRouter obligationRouter, Result result) {
+ return new StdPepResponse(pepConfig, obligationRouter, result);
+ }
+
+ private StdPepResponse(PepConfig pepConfig, ObligationRouter obligationRouter, Result result) {
+ this.pepConfig = pepConfig;
+ this.wrappedResult = result;
+ this.obligationRouter = obligationRouter;
+ }
+
+ @Override
+ public boolean allowed() throws PepException {
+ if(obligationRouter != null) {
+ obligationRouter.routeObligations(getObligations());
+ }
+ switch(wrappedResult.getDecision()) {
+ case PERMIT:
+ return true;
+ case DENY:
+ return false;
+ case NOTAPPLICABLE:
+ return enforceBehavior(pepConfig.getNotApplicableBehavior(), "Not Applicable");
+ //TODO: Handle various indeterminate status codes.
+ case INDETERMINATE:
+ case INDETERMINATE_DENY:
+ case INDETERMINATE_DENYPERMIT:
+ case INDETERMINATE_PERMIT:
+ Status status = wrappedResult.getStatus();
+ String formatted = String.format("Decision: Indeterminate, Status Code: %s, Status Message: %s",
+ status.getStatusCode(), status.getStatusMessage());
+ logger.error(formatted);
+ throw new PepException(formatted);
+ default:
+ throw new PepException("Invalid response from PDP");
+ }
+ }
+
+ @Override
+ public Map<String, Obligation> getObligations() throws PepException {
+ Map<String, Obligation> obligationMap = new HashMap<String, Obligation>();
+ for(com.att.research.xacml.api.Obligation wrappedObligation: wrappedResult.getObligations()) {
+ Obligation obligation = new StdObligation(wrappedObligation);
+ obligationMap.put(obligation.getId(), obligation);
+ }
+ return obligationMap;
+ }
+
+ @Override
+ public Map<String, Advice> getAdvices() throws PepException {
+ Map<String, Advice> adviceMap = new HashMap<String, Advice>();
+ for(com.att.research.xacml.api.Advice wrappedAdvice: wrappedResult.getAssociatedAdvice()) {
+ Advice advice = new StdAdvice(wrappedAdvice);
+ adviceMap.put(advice.getId(), advice);
+ }
+ return adviceMap;
+ }
+
+ @Override
+ public Object getAssociation() throws PepException {
+ return null;
+ }
+
+ @Override
+ public Collection<Attribute> getAttributes() {
+ Collection<Attribute> attributes = new ArrayList<Attribute>();
+ for(AttributeCategory category: wrappedResult.getAttributes()) {
+ attributes.addAll(category.getAttributes());
+ }
+ return attributes;
+ }
+
+ @Override
+ public Map<Identifier, Collection<Attribute>> getAttributesByCategory() {
+ Map<Identifier, Collection<Attribute>> attributesByCategory = new HashMap<Identifier, Collection<Attribute>>();
+ for(AttributeCategory category: wrappedResult.getAttributes()) {
+ attributesByCategory.put(category.getCategory(), category.getAttributes());
+ }
+ return attributesByCategory;
+ }
+
+ @Override
+ public Result getWrappedResult() {
+ return wrappedResult;
+ }
+
+ private boolean enforceBehavior(
+ PepResponseBehavior pepResponseBehavior, String decision) throws PepException {
+ switch (pepResponseBehavior) {
+ case RETURN_YES:
+ return true;
+ case RETURN_NO:
+ return false;
+ case THROW_EXCEPTION:
+ logger.info("Throwing an exception as per configured behavior for decision: " + decision);
+ throw new PepException("Exception being thrown based on configured " +
+ "behavior for decision: " + decision);
+ default:
+ throw new PepException("Invalid PepResponseBehavior");
+ }
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.java
new file mode 100755
index 0000000..627f80e
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.java
@@ -0,0 +1,29 @@
+package org.openliberty.openaz.pepapi.std;
+
+import com.att.research.xacml.api.Result;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.ObligationRouter;
+import org.openliberty.openaz.pepapi.PepConfig;
+import org.openliberty.openaz.pepapi.PepResponse;
+import org.openliberty.openaz.pepapi.PepResponseFactory;
+
+
+final class StdPepResponseFactory implements PepResponseFactory {
+
+ private static final Log logger = LogFactory.getLog(StdPepResponseFactory.class);
+
+ private PepConfig pepConfig;
+
+ private ObligationRouter obligationRouter;
+
+ StdPepResponseFactory(PepConfig pepConfig, ObligationRouter obligationRouter) {
+ this.pepConfig = pepConfig;
+ this.obligationRouter = obligationRouter;
+ }
+
+ @Override
+ public PepResponse newPepResponse(Result result) {
+ return StdPepResponse.newInstance(pepConfig, obligationRouter, result);
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/SubjectMapper.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/SubjectMapper.java
new file mode 100755
index 0000000..82c4bee
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/SubjectMapper.java
@@ -0,0 +1,22 @@
+package org.openliberty.openaz.pepapi.std;
+
+
+import org.openliberty.openaz.pepapi.Subject;
+
+/**
+ * Created by ajith on 12/11/14.
+ */
+public class SubjectMapper extends CategoryContainerMapper {
+
+ public SubjectMapper() {
+ super(Subject.class);
+ }
+
+ @Override
+ protected String resolveAttributeId(String attributeId) {
+ if(attributeId.equals(Subject.SUBJECT_ID_KEY)) {
+ return getPepConfig().getDefaultSubjectId();
+ }
+ return attributeId;
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.java b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.java
new file mode 100755
index 0000000..2c1d981
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.java
@@ -0,0 +1,96 @@
+package org.openliberty.openaz.pepapi.std;
+
+
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.ObligationStore;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * Acts as a store for Obligation instances in the current thread of execution.
+ *
+ * @author Ajith Nair, David Laurance, Darshak Kothari
+ *
+ */
+public final class ThreadLocalObligationStore implements ObligationStore {
+
+ private static final ThreadLocal<Map<Class<?>, Set<Obligation>>> obligationMapContainer =
+ new ThreadLocal<Map<Class<?>, Set<Obligation>>>();
+
+ private ThreadLocalObligationStore(){}
+
+ public static ThreadLocalObligationStore newInstance() {
+ return new ThreadLocalObligationStore();
+ }
+
+ /**
+ * Set Obligations for the current thread of execution.
+ *
+ * @param obligationMap a <code>Map</code> containing <code>Obligation</code> instances keyed by ObligationHandler Class.
+ */
+ void setObligations(Map<Class<?>, Set<Obligation>> obligationMap) {
+ if(obligationMap != null && !obligationMap.isEmpty()) {
+ obligationMapContainer.set(Collections.unmodifiableMap(obligationMap));
+ }else {
+ obligationMapContainer.set(null);
+ }
+ }
+
+ /**
+ * Returns all obligations in the current thread of execution.
+ *
+ * @return a <code>Set</code> of <code>Obligation</code> instances.
+ */
+ public Set<Obligation> getAllObligations() {
+ Set<Obligation> allObligations = new HashSet<Obligation>();
+ Map<Class<?>, Set<Obligation>> obligationMap = obligationMapContainer.get();
+ if(obligationMap != null){
+ for(Entry<Class<?>, Set<Obligation>> e: obligationMap.entrySet()){
+ allObligations.addAll(e.getValue());
+ }
+ }
+ return allObligations;
+ }
+
+ /**
+ * Returns all obligations that the given ObligationHandler can handle, in the current thread of execution.
+ *
+ * @param oHandlerClass
+ * @return a <code>Set</code> of <code>Obligation</code> instances.
+ */
+ @Override
+ public Set<Obligation> getHandlerObligations(Class<?> oHandlerClass) {
+ Set<Obligation> obligations = new HashSet<Obligation>();
+ Map<Class<?>, Set<Obligation>> obligationMap = obligationMapContainer.get();
+ if(obligationMap != null && obligationMap.get(oHandlerClass) != null){
+ obligations.addAll(obligationMap.get(oHandlerClass));
+ }
+ return obligations;
+ }
+
+
+ @Override
+ public Obligation getHandlerObligationById(Class<?> oHandlerClass,
+ String obligationId) {
+ Set<Obligation> obligations = getHandlerObligations(oHandlerClass);
+ if(obligations != null){
+ for(Obligation obligation: obligations){
+ if(obligation.getId().equals(obligationId)){
+ return obligation;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Clear all obligations in the current thread.
+ */
+ void clear() {
+ obligationMapContainer.remove();
+ }
+}
diff --git a/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/package.html b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/package.html
new file mode 100755
index 0000000..a9013f8
--- /dev/null
+++ b/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/package.html
@@ -0,0 +1,1058 @@
+<html>
+<body>
+This package is the
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/package-summary.html"
+>OpenAz reference "implementation"</a>
+of the OpenAz
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/pep/package-summary.html"
+>"PepApi interface package"</a>,
+and therefore generally contains implementation classes
+and only implementation-specific interfaces, also included is a
+<a href="#tutorial">PepApi tutorial</a> that describes the approach
+to building a PepApi implementation for a specific authorization
+provider, as well as a 2nd <a href="#tutorialmappers">Mapper tutorial</a>
+that describes the overall approach to writing mappers.
+<p>
+The goal of this package is twofold:
+<ul>
+<li>The primary goal is to provide a reference implementation of PepApi
+that uses an AzApi-based authorization provider, which in this case is the
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/provider/SimpleConcreteSunXacmlService.html"
+>SimpleConcreteSunXacmlService</a>,
+which is the SunXacml PDP wrapped in an
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/package-summary.html"
+>implementation of the AzApi interface</a>.
+<li>The secondary goal is to provide a reference framework, which other
+providers can use as a model for implementation strategy of both AzApi
+and non-AzApi based authorization providers.
+</ul>
+
+In order to support the 2nd objective, the following is a high level
+"tutorial" about the PepApi and this implementation of it. At present,
+this tutorial is in preliminary form, however, even in the current
+state, the information may prove useful to anyone who is interested in
+developing an implementation of PepApi.
+
+<a name="tutorial"><H2>OpenAz PepApi Implementation Tutorial (v113)</H2></a>
+<H3>Contents</H3>
+<ul>
+<li><a href="#highleveloverview">High Level Overview</a>
+<li><a href="#sixlayerlist">List of Six OpenAz Layers</a>
+<li><a href="#separationapispi">Separation of PepApi to application API
+and provider SPI</a>
+<li><a href="#highlevelsepapispi">High Level Overview API/SPI Separation</a>
+<li><a href="#detailsepapispi">Detail list of API/SPI separated methods</a>
+<li><a href="#pepapilayer">Appl client PepApi "API LAYER"</a>
+<li><a href="#suggestedspiapproaches">Suggested approaches for XyzApi provider SPI implementation</a>
+<li><a href="#pepapiseqmodel">PepApi Object Sequence Model</a>
+<li><a href="#somediscussion">Some discussion items</a>
+<ul>
+<li><a href="#basicpattern">Basic Processing Pattern</a>
+<li><a href="#highlowinterfacHigh Level and Low Level Interface Layers</a>
+<li><a href="#basicpurpose">Basic Purpose of PepApi</a>
+<li><a href="#standardpdps">Standard PDPs</a>
+<li><a href="#xacmlreps">Representations of XACML</a>
+<li><a href="#openazreleases">OpenAz Release Philosophy</a>
+<li><a href="#thesixlayersdisc">The Six Layers</a>
+<li><a href="#layer5disc">Layer 5: AzApi Impl</a>
+<li><a href="#azapivssunxacml">AzApi vs SunXacml</a>
+<li><a href="#canonicalform">Canonical Form</a>
+</ul>
+<li><a href="#tutorialmappers">Part II: Mappers Tutorial</a>
+</ul>
+
+<a name="highleveloverview">
+<H3>High Level Overview: Appl, PepApi, AzApi, AzProvider</H3></a>
+<p>
+To understand the "top level" picture of what is currently provided
+for implementations in the OpenAz project, we can identify six layers
+of operational modules (including "interfaces" as a layer). Each layer
+description starts with the identifier of a jar file in the OpenAz project
+that contains an implementation of the functionality described in the layer.
+<p>
+In addition, experience with OpenAz has shown, the PepApi is best represented
+as having 2 portions: an application-oriented API, and a provider-oriented SPI,
+which will be noted in the following list and explained further below.
+<p>
+The PepApi provider is primarily concerned with implementing Layer 3 in the
+list below. The other layers are generally provided either from the OpenAz site
+(layers 2,4 for interfaces, layer 1 for test code, layers 5,6 for sample
+AzApi impl and PDP), or from customer application environments (layer 1,
+when customer is ready to implement PepApi client), or from PDP vendors
+(layers 5 and 6).
+<p>
+<a name="sixlayerlist"><H4>List of the Six OpenAz Module Layers</H4></a>
+<ul>
+<li><b>Layer 1:</b>
+"<top-of-project>\openaz\test\build\openliberty-openaz-test.jar"
+<br>
+This layer is implemented by a package that contains sample test programs,
+and may be thought of as the "application layer", and generally only
+uses the "API" portion of PepApi.
+For example, test.TestStyles, demonstrates various usage scenarios
+of PepApi.
+
+<li><b>Layer 2:</b> "<top-of-project>
+"<top-of-project>\openaz\azapi\build\openliberty-openaz-azapi.jar"
+<br>
+This layer is implemented by a package that contains the actual
+"PepApi interfaces" (API and SPI), and may be considered to be the second layer
+of "modules", which, while not having any executable code, do control
+what code can be compiled that is purported to "implement" the interface.
+(Note: Even though the jar file contains "azapi" in the name,
+it also contains the "pepapi".)
+
+<li><b>Layer 3:</b>
+"<top-of-project>\openaz\pep\build\openliberty-openaz-pep.jar"
+<br>
+This package contains an example implementation of the PepApi,
+and may be considered to be the "third layer" of OpenAz.
+It also contains an implementation of an "AzApi client", i.e. a
+module that uses AzApi directly to make authorization decisions.
+As such, this layer may be considered to both implement a PepApi
+provider, as well as, in this case, an AzApi client, or in the more
+general, case a client to any request-response oriented
+authorization provider.
+<br>
+In addition, this layer generally uses its own implementation of
+the SPI portion of PepApi, which facilitates its implementation
+of the API portion.
+
+<li><b>Layer 4:</b>
+"<top-of-project>\openaz\azapi\build\openliberty-openaz-azapi.jar"
+<br>
+This package contains the actual "interfaces" that comprise the AzApi,
+and, in the same sense as the layer 2 PepApi above, may be considered
+to be a layer of modules that control compatibility with other
+modules, esp in layer 5. (Note: this is the same jar file as used
+by layer 2, i.e. it contains both sets of interfaces.)
+
+<li><b>Layer 5:</b>
+"<top-of-project>\openaz\pdp\build\openliberty-openaz-pdp.jar"
+<br>
+This package contains an example implementation of AzApi, and may be
+considered to be the "fifth layer" of OpenAz. Similarly to Layer 3,
+this package also contains a client implementation, where the client
+in this case is to the SunXacml PDP provider.
+
+<li><b>Layer 6:</b>
+"<top-of-project>/pdp/lib/sunxacml.jar"
+<br>
+This jar file contains the SunXacml PDP impl, which may be considered
+as the sixth layer of modules in OpenAz.
+</ul>
+
+
+<a name="separationapispi">
+<H3>Separation of PepApi into API and SPI parts.</H3></a>
+This section first describes the approach at a high level, then
+provides a detailed review of the complete PepApi interface to
+designate the API and SPI parts of each PepApi interface.
+
+<a name="highlevelsepapispi">
+<H4>High level view of API/SPI separation</H4></a>
+The first thing that is probably useful to recognize is that the PepApi
+really consists of an application facing API plus an implementer's SPI
+(Service Provider Interface).
+If there is sufficient demand for a more formal separation, that will be
+considered in the future.
+<p>
+The following is a high level view of the API/SPI separation:
+<pre>
+ Consider the following functionality as being the main
+ part of each portion of the PepApi:
+
+ APPL API LAYER:
+
+ Use newPepRequest methods to build request
+ Use decide() method to make decision
+ Use allowed and next methods to look at results
+ Use getObligations, getObligationId, getStringValues to
+ look at obligations within each result
+
+ PROVIDER SPI LAYER:
+
+ Take Appl Api Request and
+ submit as Authorization Provider Request
+
+ Take Authorization Provider Response objects and
+ process and return them as Appl Api Response objects
+
+
+ Summary of architecture:
+
+ Appl Client Impl
+ PepApi Appl Client API
+ PepApi Provider SPI
+ PepApi Provider Impl
+ <AzProvider>API {AzProvider = Az | Xyz}
+ <AzProvider> Impl
+
+
+ Current AzApi strategy:
+
+ +--------------------+
+ | Appl client (impl) | <b><i>Layer 1</i></b>
+ +--------------------+
+ | ^
+ v |
+ +-----------------------------------+
+ | PepApi appl client api (intf) | <b><i>Layer 2</i></b>
+ | - - - - - - - - - - - - - - - - - |
+ | PepApi provider api/spi (impl) | <b><i>Layer 3</i></b>
+ | includes use of PepApi spi |
+ | plus AzApi Client |
+ +-----------------------------------+
+ | ^
+ v |
+ +-----------------------------------+
+ | AzApi client api (intf) | <b><i>Layer 4</i></b>
+ | - - - - - - - - - - - - - - - - - |
+ | AzApi provider (impl) | <b><i>Layer 5</i></b>
+ | plus SunXacml client |
+ +-----------------------------------+
+ | ^
+ v |
+ +----------------------------+
+ | SunXacml provider (impl) | <b><i>Layer 6</i></b>
+ +----------------------------+
+
+
+
+ Suggested strategy for an Xyz provider:
+
+ +--------------------+
+ | Appl client (impl) | <b><i>Layer 1</i></b>
+ +--------------------+
+ | ^
+ v |
+ +-----------------------------------+
+ | PepApi appl client api (intf) | <b><i>Layer 2</i></b>
+ | - - - - - - - - - - - - - - - - - |
+ | PepApi provider api/spi (impl) | <b><i>Layer 3</i></b>
+ | includes use of custom PepApi spi |
+ | plus XyzApi Client |
+ +-----------------------------------+
+ | ^
+ v |
+ +-----------------------------------+
+ | <i>XyzApi client api</i> (intf) | <b><i>Layer 4</i></b>
+ | - - - - - - - - - - - - - - - - - |
+ | XyzApi provider (impl) | <b><i>Layers 5,6</i></b>
+ +-----------------------------------+
+
+
+</pre>
+Note: because in the XyzApi provider case, the "standard" api is effectively
+the XyzApi, itself, there is no need for the impl to act as a client to a
+different interface, and so layers 5 and 6 are effectively consolidated to
+a single logical layer.
+
+<a name="detailsepapispi">
+<H4>Detail list of API/SPI separated methods</H4></a>
+The following list of interfaces and methods describe the API/SPI
+separation.
+<p>Note
+<ul>
+<li>There are only a few interfaces and methods involved with
+the application-facing API, namely:
+<ul>
+<li>PepRequestFactory
+<li>PepRequest
+<li>PepResponse
+<li>Obligation
+</ul>
+<li>All the PepApi interfaces are used and/or include methods that appear
+in the SPI portion.
+<li>Methods marked with "**" have AzApi-specific items in the interface
+that need to be addressed by non-AzApi implementations. In most cases,
+simply making the item null will satisfactorily address the situation for
+a non-AzApi implementation, however, it is likely that a corresponding
+element of the implementation will need to be used instead to fulfill
+the functional capability. For example, a non-AzApi impl will have no
+use for an AzRequestContext, however, it will likely have its own
+RequestContext that will need to be considered as an alternative which
+can be included in an extension class that has an additional provider-specific
+method.
+Note: items marked with "**" are followed by comment at end of line
+with number referring to the suggested approaches for these issues
+described at the end of the SPI detail section.
+</ul>
+
+<pre>
+ -------------------------------------------------------------------
+</pre>
+<a name="pepapilayer"><H4> APPL CLIENT PepApi "API LAYER":</H4></a>
+<pre>
+<a name="apipepreqfact"><H5>Interface PepRequestFactory</H5></a>
+ PepRequest newPepRequest(
+ Object subjectObj, Object actionObj,
+ Object resourceObj, Object environmentObj)
+ PepRequest newPepRequest(
+ Object subjectObj, Object actionResourceObject,
+ Object environmentObj)
+ PepRequest newPepRequest(
+ String subjectName, String actionId,
+ String resourceId)
+
+ PepRequest newBulkPepRequest(
+ Object subjectObj, List actionObjects,
+ List resourceObjects, Object environmentObj)
+ PepRequest newBulkPepRequest(
+ Object subjectObj, List actionResourceObjects,
+ Object environmentObj)
+
+ PepRequest newQueryPepRequest(
+ Object subjectObj, Object environmentObj,
+ String scope, PepRequestQueryType queryType)
+
+<a name="apipepreq"><H5>Interface PepRequest</H5></a>
+ PepResponse decide()
+
+<a name="apipeprsp"><H5>Interface PepResponse</H5></a>
+ boolean allowed()
+ Object getAction()
+ Object getResource()
+ Map<String,Obligation> getObligations()
+ boolean next()
+
+<a name="apiobligation"><H5>Interface Obligation</H5></a>
+ String getObligationId()
+ Map<String,String> getStringValues()
+
+ -------------------------------------------------------------------
+</pre>
+<a name="pepspilayer"><H4> PROVIDER PepApi "SPI LAYER":</H4></a>
+<pre>
+<a name="spipepreqfact"><H5>Interface PepRequestFactory</H5></a>
+ ** AzService getAzService() // (#1) return null for non-AzApi
+
+ String getContainerName()
+ String getProviderClassName()
+
+ RequestAttributesFactory<T> getRequestAttributesFactory(T t)
+ <T extends Enum<T> & AzCategoryId>
+ PepResponseFactory getResponseFactory()
+
+ DecisionHandler getDecisionHandler()
+ List<PostDecisionHandler> getPostDecisionHandlers()
+ List<PreDecisionHandler> getPreDecisionHandlers()
+
+<a name="spipepreq"><H5>Interface PepRequest</H5></a>
+ ** AzRequestContext getAzRequestContext() // return null for non-AzApi
+
+ PepRequestFactory getPepRequestFactory()
+
+ void setAccessSubject(Object subjectObject)
+ void setResourceAction(Object resource, Object action)
+ void setEnvironment(Object envObject)
+ void setBulkResourceActions(List resourceObjects, List actionObjects)
+
+ PepRequestOperation getOperation()
+ ** Object getActionObject(AzResourceActionAssociation azRaa) // (#3)
+ ** Object getResourceObject(AzResourceActionAssociation azRaa) // (#3)
+
+ void setScope(String scope)
+ String getScope()
+
+ void setQueryReturnAllowed(boolean queryReturnAllowed)
+ boolean isQueryForAllowedResults()
+
+<a name="spijavaobjmap"><H5>Interface JavaObjectMapper:</H5></a>
+ Set<Class> getSupportedClasses()
+
+ boolean canMapObject(Object obj)
+
+ <T extends Enum<T> & AzCategoryId>
+ RequestAttributes<T> map(
+ Object javaObject,
+ RequestAttributes<T> azWrapperObject)
+
+<a name="spireqattrfact">
+<H5>Interface RequestAttributesFactory<T extends Enum<T> & AzCategoryId></H5></a>
+ RequestAttributes<T> createObject(PepRequest ctx)
+ void setMappers(List<JavaObjectMapper> mappers)
+ List<JavaObjectMapper> getMappers()
+ Set<Class> getSupportedClasses()
+
+<a name="spiattr">
+<H5>Interface Attributes<T extends Enum<T> & AzCategoryId></H5></a>
+ ** AzEntity<T> getAzEntity() // (#1) return null for non-AzApi
+
+<a name="spireqattr">
+<H5>Interface RequestAttributes<T extends Enum<T> & AzCategoryId>
+ extends Attributes<T></H5></a>
+ PepRequest getPepRequest()
+
+ void setAttribute(String name, Boolean value)
+ void setAttribute(String name, Date date)
+ void setAttribute(String name, Integer value)
+ void setAttribute(String name, String value)
+
+<a name="spidechnd"><H5>Interface DecisionHandler</H5></a>
+ PepResponse decide(PepRequest request)
+<a name="spipredechnd"><H5>Interface PreDecisionHandler</H5></a>
+ void preDecide(PepRequest request)
+<a name="spipostdechnd"><H5>Interface PostDecisionHandler</H5></a>
+ void postDecide(PepRequest request, PepResponse response)
+
+<a name="spipepreqrspfact"><H5>Interface PepResponseFactory:</H5></a>
+ ** PepResponse createPepResponse(
+ AzResponseContext responseContext, // (#1) pass null for non-AzApi
+ PepRequest pepRequest,
+ PepRequestOperation operation)
+
+ ** PepResponse createPepResponse(
+ Set<AzResourceActionAssociation> actionResourceAssociations, // (#3)
+ PepRequest pepRequest,
+ boolean queryAllowed)
+
+ ObligationFactory getObligationFactory()
+
+ PepResponseBehavior getMissingAttributeBehavior()
+ PepResponseBehavior getNotApplicableBehavior()
+ PepResponseBehavior getProcessingErrorBehavior()
+ PepResponseBehavior getSyntaxErrorBehavior()
+
+ void setMissingAttributeBehavior(
+ PepResponseBehavior missingAttributeBehavior)
+ void setNotApplicableBehavior(
+ PepResponseBehavior notApplicableBehavior)
+ void setProcessingErrorBehavior(
+ PepResponseBehavior processingErrorBehavior)
+ void setSyntaxErrorBehavior(
+ PepResponseBehavior syntaxErrorBehavior)
+
+<a name="spipeprsp"><H5>Interface PepResponse</H5></a>
+ ** AzResponseContext getAzResponseContext() // (#1) return null for non-AzApi
+
+<a name="spioblfact"><H5>Interface ObligationFactory</H5></a>
+ ** Obligation createObject(AzEntity<AzCategoryIdObligation> entity) // (#2) pass null for non-AzApi
+
+<a name="spiobl"><H5>Interface Obligation
+ extends ResponseAttributes<AzCategoryIdObligation></H5></a>
+
+<a name="spirspattrfact">
+<H5>Interface ResponseAttributesFactory<T extends Enum<T> & AzCategoryId></H5></a>
+ ** ResponseAttributes<T> createObject(AzEntity<T> entity) // (#2) pass null for non-AzApi
+
+<a name="spirspattr">
+<H5>Interface ResponseAttributes<T extends Enum<T> & AzCategoryId>
+ extends Attributes<T></H5></a>
+
+ -------------------------------------------------------------------
+</pre>
+<a name="suggestedspiapproaches">
+<H4>Suggested approaches for XyzApi provider SPI implementation</H4></a>
+<pre>
+Note: these suggestions presume the Xyz provider is following the
+code structure in the org.openliberty.openaz.pep impl package
+and that the approach is to substitute Xyz request and response objects,
+and Xyz entity attribute collections for those provided by AzApi.
+The basic idea would be to have a parallel impl, for example:
+org.openliberty.openaz.xyz, with basically the same set of classes,
+but with some of the following modifications considered.
+
+ 1. return null for getAz<object>() in:
+ PepRequestFactory.getAzService()
+ PepRequest.getAzRequestContext()
+ Attributes<T>.getAzEntity()
+ PepResponse.getAzResponseContext()
+
+ 2. Pass null for az<object> parameter in:
+ PepResponseFactory.createPepResponse(azResponseContext, ...)
+ ResponseAttributesFactory.createObject(azEntity)
+ ObligationFactory.createObject(azEntity)
+
+ 3. Consider extending AzResourceActionAssociation as
+ XyzResourceActionAssociation and use in the following:
+
+ PepRequest.getActionObject(AzResourceActionAssociation azRaa)
+ PepRequest.getResourceObject(AzResourceActionAssociation azRaa)
+
+ PepResponseFactory.createPepResponse(
+ Set<AzResourceActionAssociation> azRaas,
+ PepRequest pepRequest,
+ boolean queryAllowed)
+
+ AzResourceActionAssociation javadoc is here:
+ http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/AzResourceActionAssociation.html
+
+ Within XyzResourceActionAssociation extension return null for the
+ following AzApi-dependent methods:
+
+ AzResourceActionAssociation.getAzAction()
+ AzResourceActionAssociation.getAzResource()
+ AzResourceActionAssociation.getAzResourceActionAssociationId()
+
+ Add new XyzResourceActionAssociation method to return
+ action and resource objects:
+
+ XyzObject getXyzAction()
+ XyzObject getXyzResource()
+
+ Then the XyzResourceActionAssociation object can be used
+ for correlation based on the XyzObject references for
+ action and resource in the XyzPepRequestImpl that
+ implement PepRequest, i.e.
+
+ PepRequest.getActionObject(XyzResourceActionAssociation xyzRaa)
+ PepRequest.getResourceObject(XyzResourceActionAssociation xyzRaa)
+
+ Similarly for creating a collection of return objects
+ in response to a query, the XyzPepResponseFactoryImpl
+ should be able to pass:
+
+ PepResponseFactory.createPepResponse(
+ Set<XyzResourceActionAssociation> xyzRaas,
+ PepRequest pepRequest,
+ boolean queryAllowed)
+
+ although one needs to check if generics will allow this pass
+ of a Set of subclasses of the class for which the interface
+ is defined.
+
+</pre>
+<a name="pepapiseqmodel"><H3>PepApi Object sequence model</H3></a>
+The following section contains a quasi-sequence diagram that shows the
+relations between the components of the PepApi in approximate order of
+their invocation at runtime.
+<pre>
+
+ +------------------------------------------+
+ | PepRequestFactory |
+ | PepReqFactImpl(azSvc) // impl azSvc set |
+ | pr = newPepRequest |
+ | | (sObj,aObj,rObj,eObj) |
+ | | newPEPRequest(op) |
+ | | azReqCtx = azSvc.createAzReqCtx() |
+ | | new PepReqImpl(azReqCtx, this, op) |
+ | | setAccessSubject(sObj) |
+ +---|--------------------------------------+
+ |
+ V
+ +---------------------------------------------------------------+
+ | PepRequest |
+ | PepReqImpl(azReqCtx, this, op) // set values from params |
+ | setAccessSubject(subjObj) |
+ | createAccessSubject(subjObj) //'Subject' implies <T> |
+ | subjFact = getPepReqFact.getReqAttrFact(catId<T>) |
+ | +<-- subjInit = subjFact.createObj(this) |
+ | | subjMapd = mapJavObject(subjObj, subjInit, subjFact) |
+ | | mapJavaObject(subjObj, subjInit, subjFact) |
+ | +<---- mapper = subjFact.getMappers().next() |
+ | | | mapper.map(subjObj, subjInit) |
+ |+<--- decide() |
+ +|-|-|----------------------------------------------------------+
+ | | |
+ | | V
+ | | +-----------------------------------------------------------+
+ | | | SubjectFactory |
+ | | | createObject(pr) |
+ | | | azReqCtx = pr.getAzReqCtx() |
+ | | | azSubjInit = azReqCtx.createAzEntity(catIdSubj) |
+ | | | azReqCtx.addAzEntity(azSubjInit) |
+ | | | +<- return new Subject(azSubjInit, pr, this) |
+ | | +-|---------------------------------------------------------+
+ | | |
+ | | V
+ | | +-----------------------------------------------------------+
+ | | | Subject |
+ | | | Subject(azSubjInit, pr, subjFact) |
+ | | | +<- super[RequestAttributes](azSubjInit, pr, subjFact) |
+ | | +-|---------------------------------------------------------+
+ | | |
+ | | V
+ | | +-----------------------------------------------------------+
+ | | | RequestAttributes |
+ | | | RequestAttributes(azSubjInit, pr, subjFact) |
+ | | | set this.pr, this.subjFact |
+ | | | +<- super[Attributes](azSubjInit) |
+ | | +-|---------------------------------------------------------+
+ | | |
+ | | V
+ | | +-----------------------------------------------------------+
+ | | | Attributes |
+ | | | Attributes(azSubjInit) |
+ | | | this.azEntity = azSubjInit |
+ | | +-----------------------------------------------------------+
+ | |
+ | V
+ | +-----------------------------------------------------------+
+ | | JavaObjectMapper |
+ | | map(subjObj, reqAttrSubjInit) |
+ | | convertObj(subjObj, reqAttrSubjInit) |
+ | | attrId = getVocab(subjObj) |
+ | | +<- reqAttrSubjInit.setAttribute(attrId, subjObj) |
+ | +---|-------------------------------------------------------+
+ | |
+ | V
+ | +-----------------------------------------------------------+
+ | | RequestAttributes |
+ | | setAttribute(attrId, subjObj) |
+ | | azEntity.createAzAttribute(issuer, attrId, |
+ | | azEntity.createAzAttributeValue(azDataTyp, subjObj) |
+ | +-----------------------------------------------------------+
+ |
+ V
+ +----------------------------------------------------------+
+ | DecisionHandler |
+ | decide(pepReq) |
+ | azRspCtx = azSvc.decide(pepReq.getAzReqCtx() |
+ | +<- pepRspFact = pepReq.getPepReqFact.getRspFact() |
+ | | pepRsp = pepRspFact.createPepRsp(azRspCtx,pepReq,op) | |
+ | | return pepRsp |
+ +-|--------------------------------------------------------+
+ |
+ V
+ +----------------------------------------------------------+
+ | PepResponseFactory |
+ | createPepRsp(azRspCtx,pepReq,op) |
+ | +<- pepRsp = new PepRspImpl(azRspCtx, pepReq, this, op) |
+ | | return pepRsp |
+ +-|--------------------------------------------------------+
+ |
+ V
+ +----------------------------------------------------------+
+ | PepResponse |
+ | PepRspImpl(azRspCtx,pepReq,pepRspFact,op) |
+ | set this.azRspCtx,this.pepReq,this.pepRspFact,this.op |
+ | this.azResultIterator = azRspCtx.getRslts.iterator() |
+ | allowed() |
+ | next() // point to next azResult |
+ | curAzResult = azResultIterator.next() |
+ | getResource(), getAction() |
+ | azRaa = this.getAzResourceActionAssociation() |
+ | resObj = this.getPepReq.getResourceObject(azRaa) |
+ | return resObj |
+ | getObligations() |
+ | curAzObls = curAzResult.getAzObligations() |
+ | curAzObl = curAzObls.next() |
+ | oblFact = this.getRspFact.getOblFact() |
+ | Obligation pepObl = oblFact.createObject(curAzObl) |
+ +-|--------------------------------------------------------+
+ |
+ V
+ +----------------------------------------------------------+
+ | ObligationFactory |
+ | createObject(azObligation) |
+ | +<- return new Obligation(azObligation) |
+ +----------------------------------------------------------+
+ |
+ V
+ +-----------------------------------------------------------+
+ | Obligation |
+ | Obligation(azObligaion) |
+ | +<- super[ResponseAttributes](azObligation) |
+ +-|---------------------------------------------------------+
+ |
+ V
+ +-----------------------------------------------------------+
+ | ResponseAttributes |
+ | ResponseAttributes(azObligation) |
+ | +<- super[Attributes](azObligation) |
+ +-|---------------------------------------------------------+
+ |
+ V
+ +-----------------------------------------------------------+
+ | Attributes |
+ | Attributes(azObligation) |
+ | this.azEntity = azObligation |
+ +-----------------------------------------------------------+
+
+
+</pre>
+
+<a name="somediscussion"><h3>Some discussion items</h3></a>
+
+<a name="basicpattern"><h4>Basic Processing Pattern</h4></a>
+The basic pattern is that the "container" of applications provides
+both checking requests before the application receives them, and
+checking requests in the process of application execution, where
+it is necessary to determine if the current user has sufficient
+authorization established to continue the current operation.
+<p>
+
+<a name="highlowinterfaces">
+<h4>High Level and Low Level Interface Layers</h4></a>
+PepApi is a "high level interface" intended to be totally flexible
+in terms of the applications and containers that can use it, and
+to also be "easy to use", comparable to existing platform-specific
+authorization models, such as J2SE checkPermission and WebLogic
+isAccessAllowed.
+<p>
+By contrast, AzApi is a "low level interface" intended to provide
+a Java binding to the more general platform independent XACML
+authorization model, which provides a general interface consisting
+of a collection of collections of "canonical" Attributes that contain
+both Attribute metadata and AttributeValues.
+<p>
+
+<a name="basicpurpose"><h4>Basic Purpose of PepApi</h4></a>
+Therefore, the intended purpose of a PepApi Impl, for example,
+this package ({@link org.openliberty.openaz.pep}), is
+to provide a "mapping" from the simple, application-friendly, PepApi
+that the applications (and containers) use, to the more complex
+AzApi, that the container would then typically use
+to submit requests to standard XACML PDPs.
+<p>
+
+<a name="standardpdps"><h4>Standard PDPs</h4></a>
+"Standard XACML PDPs" are accessed using the XACML
+Request/Response protocol, which is described in the XACML
+specifications using XML to represent the details. However,
+implementations are not required to use XML, but they are
+required to maintain the semantics of XACML, which are normatively
+defined in the specifications using the XML representation.
+<p>
+
+<a name="xacmlreps"><h4>Representations of XACML</h4></a>
+Furthermore, the XACML specifications do not specify what
+representation is required in the PEP-PDP connection, so it is
+possible that one end is expecting to use XML and the other
+end is expecting to use some other serialization format of the
+same information. Therefore, interoperability is somewhat
+dependent on the "bindings" that XACML PEP and XACML PDPs have
+provided for support. In the absence of a match, it would be
+up to the vendors and/or enterprise system developers to either
+provide a translation module or to simply select another
+product that would be compatible.
+<p>
+It is not a goal of either the XACML Technical Committee nor
+of the OpenAz project to attempt to resolve this issue, except
+on an as-needed basis to serve the purposes of implementations
+that are used within or want to integrate with the OpenAz Project.
+<p>
+So, for example, the initial release of OpenAz has, effectively,
+two "providers" for AzApi, the top level classes of which are:
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/provider/SimpleConcreteDummyService.html">
+<b>SimpleConcreteDummyService</b></a> and
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/provider/SimpleConcreteSunXacmlService.html">
+<b>SimpleConcreteSunXacmlService</b></a>.
+The former, the "dummy service",
+simply gives canned responses, and should be regarded as no more than
+a test tool, however, its existence as an independent "provider" may
+be useful for some types of demos.
+<p>
+
+<a name="openazreleases"><h4>OpenAz Release Philosophy</h4></a>
+To understand the working example in the "initial release of OpenAz"
+(which is the current release, which should be considered to be
+using the interfaces, i.e. AzApi and PepApi, in their "final form".
+The "final form" is "final" in the sense that until there is a critical
+mass (for example 3 implementations, including the current ref impl),
+fixes to "bugs" found in either API should be considered fair game.
+However, any "functionality" above and beyond what is currently
+represented as the functionality of those interfaces, should be
+considered candidates for a "second" or "next" release.)
+
+<a name="thesixlayersdisc"><H4>The Six Layers</H4></a>
+One may think of the 6 layers as kind of a "stepladder" of mapping
+the Objects from the local form within the application (Layer 1) to the
+canonical form within AzApi (Layer 5).
+<p>
+
+<a name="layer5disc"><H5>Layer 5: AzApi Impl</H5></a>
+Then, from the AzApi impl (layer 5) the canonical form objects may
+be mapped a 2nd time into the local object form required by the
+XACML PDP.
+
+From the perspective of the six layers, we can examine some of the
+possible "usage scenarios" for OpenAz. It turns out that there
+really are two major pieces of standardization that OpenAz facilitates:
+
+<ul>
+<li> First is the upper level "PepApi" (layer two), which provides
+a standard Java interface to application environments, regardless
+of the specific Objects the applications pass to PepApi.
+
+<ul>
+<li>Note: It is "standard" in the sense that
+applications do not have to be aware that
+what is done with the Objects when they are passed to PepApi.
+is that the Objects are "mapped" by the
+layer 3 PepApi Impl to be used as input to the layer 4 AzApi
+interface.
+</ul>
+
+<li> Second is the lower level "AzApi" (layer four), which provides
+a standard Java interface to XACML PDPs.
+
+<ul>
+<li>Note: Again that the layer 5 AzApi Impl needs to generally
+"map" the AzApi objects to those of the XACML Impl.
+</ul>
+</ul>
+
+The reason that layer 5 may need to do mapping is the existing
+XACML implementations, in general, will not yet be using AzApi,
+and so the most effective path to use AzApi is to implement a
+mapping to the current objects used by the XACML PDP.
+<ul>
+<li> In fact, this is exactly what is done in the OpenAz layer five,
+where the AzApi top level impl,
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pdp/provider/SimpleConcreteSunXacmlService.html">
+<b>SimpleConcreteSunXacmlService</b></a>,
+wraps the SunXacml PDP, which has its own interface,
+<ul>
+<li> <a href="http://sunxacml.sourceforge.net/javadoc/com/sun/xacml/PDP.html#evaluate(com.sun.xacml.ctx.RequestCtx)">
+ResponseCtx response = PDP.evaluate(RequestCtx request)</a>
+</ul>
+</ul>
+
+<a name="azapivssunxacml"><H4>AzApi vs SunXacml</H4></a>
+
+<p>
+While the SunXacml interface is "similar" to the AzApi interface,
+particularly the AzApi "decide()" call
+<p>
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/AzService.html#decide(org.openliberty.openaz.azapi.AzRequestContext)">
+<b>AzService.decide</b></a>
+(
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/AzRequestContext.html">
+<b>AzRequestContext</b></a>
+};
+
+<ul>
+<li> AzResponseContext azRspCtx = AzService.decide(AzRequestContext azReqCtx)
+</ul>
+
+<p>
+there is still a "mapping" required to go from the AzApi implementation
+objects to the SunXacml implementation objects. i.e. one must map the
+AzApi
+<a href="http://sunxacml.sourceforge.net/javadoc/com/sun/xacml/ctx/RequestCtx.html">
+<b>RequestCtx</b></a>
+to the SunXacml and on the return, map the SunXacml
+<a href="http://sunxacml.sourceforge.net/javadoc/com/sun/xacml/ctx/ResponseCtx.html">
+<b>ResponseCtx</b></a> to the AzApi
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/AzResponseContext.html">
+<b>AzResponseContext</b></a>
+
+
+<a name="canonicalform"><H4>Canonical Form</H4></a>
+Given the above description, one may ask why map to the canonical form
+at all? Why not have layer 3 map directly to the local form of the
+PDP, and therefore skip layers 4 and 5?
+
+<ul>
+<li>In fact, the architecture is designed so that is a perfectly
+legitimate strategy to take. However, the major drawback to this strategy
+is that if the enterprise has a mix of PDPs from multiple vendors,
+then configuration may begin to become complex, as one must keep track
+of which vendor's PDP is servicing which application, so as to ensure
+that the proper mappers are in place to map from the application
+objects to the specific PDP vendor objects.
+
+<li>From a purely technical engineering for performance perspective,
+it may appear that the benefit of an intermediate canonical form in
+the runtime path, as kind of a standard "clearinghouse" is not
+compelling enough on its own to justify the effort to achieve it.
+
+<li>However, there are additional considerations. Security Policy
+is an all-encompassing concern for an enterprise that generally
+applies to every activity conducted by the enterprise, whether
+for concern of privacy, risk-avoidance, compliance, integrity, etc.,
+there needs to be a way to integrate security Policy to any activity.
+
+<li>In order to effectively manage security Policy, there needs to
+be standard representations of the information in those Policies,
+as well as a method to relate that information to the corresponding
+representation of information in the enterprise that is collected
+and assembled to a Request to be evaluated by Policy.
+</ul>
+
+<a name="tutorialmappers"><H2>OpenAz Mappers Writing Tutorial (v114)</H2></a>
+<H3>Contents</H3>
+<ul>
+<li><a href="#highleveloverviewmappers">High Level Overview: Mappers</a>
+<li><a href="#structuremappers">Mapper structure</a>
+<li><a href="#methodimplmappers">Mapper method implementation</a>
+<li><a href="#permissionmappers">Permission Mapper</a>
+
+</ul>
+</ul>
+
+<a name="highleveloverviewmappers">
+<H3>High Level Overview: Mappers</H3></a>
+At the most fundamental level, the philosophy of OpenAz and PepApi/AzApi
+that the process of authorization can be abstracted as Policy defined in
+terms of "entities" represented as collections of "attributes", where the
+entities and attributes can be represented by a common standard such
+as XACML. Therefore, in theory, all that is required at runtime when an
+authorization check is required is to look at the entities involved and
+evaluate the Policy to determine if the attributes of the entities meet
+the Policy criteria for granting access.
+<p>
+The "entities" involved in a typical access check include:
+<ul>
+<li>A User Entity, or "Subject", where the Subject is the entity that
+is requesting access.
+<li>A Resource Entity, where the Resource is the entity to which the
+User Entity is requesting access.
+<li>An Action Entity, where the action specifies the explicit operations
+that the User Entity is requesting to apply to the Resource Entity.
+<li>An optional Environment Entity, where the "environment" is generally
+to be considered system conditions, such as time of day, that may factor
+into the decision making process. All such attributes are generally
+collected in an Environment Entity collection of Attributes.
+</li>
+</ul>
+In the XACML Specification, all attributes are of a specific XACML
+DataType, which means, as described in XACML Specification Section A.2:
+<pre>
+ A.2. Data-types
+
+ Although XML instances represent all data-types as strings,
+ an XACML PDP must reason about types of data that, while they
+ have string representations, are not just strings.
+
+ Types such as Boolean, integer and double MUST be converted:
+
+ - from their XML string representations
+ - to values that can be compared with values in their domain
+ of discourse, such as numbers.
+</pre>
+(Note: the XACML Specification uses both the term "data-type" and the
+term "DataType", where the former refers to a generic notion of a
+"data type", but within the XACML context, thus also implicitly
+referring to the latter term, "DataType", which is the name of the
+"XML attribute" used to specify the specific instance of XACML
+data-type to be used in conjunction with the XACML Attribute element
+that contains both the DataType attribute and AttributeValue element.
+OpenAz will not make such a distinction and simply use the term "DataType"
+or "datatype" interchangeably to in any of these contexts.)
+<p>
+In OpenAz, the "lower level" AzApi contains a separate interface for each
+of the Xacml DataTypes and a specific Java Object Type is also associated
+with each Xacml DataType. The collection of
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/AzAttributeValue.html"
+>AzAttributeValue subinterfaces</a>
+along with the associated list of "Known Implementing Classes" that reference
+the reference impl implementations of these interfaces, effectively can
+be considered the specification of the "AzApi Java Language Binding".
+<p>
+As such, in order to make an AzRequest to a XACML PDP, one needs to
+collect the attributes associated with each entity (where the entities
+are distinguished by
+<a href ="">AzCategoryId</a> and submit the Java objects containing the
+attribute values thru these standard interfaces.
+<p>
+The purpose of the lower level AzApi interface is to provide a
+well-structured framework that has a standard representation of all
+information that may ultimately prove necessary to submit a complete
+authorization request.
+<p>
+However, in general, information in the runtime environment is not
+in any particular standard form, so, in order to enable minimal impact
+on existing runtime development practices, the PepApi was developed to
+enable applications to submit whatever information objects are preferred
+to be used in a particular application environment.
+<p>
+In order to make this strategy work the PepApi implementation needs to
+"map" the information in the objects supplied by the application from
+that environment-specific form to the AzApi standard form, which will
+then enable seamless submission to a XACML PDP.
+<p>
+However, as described in the first tutorial above, the same strategy
+will work with almost any PDP. This second tutorial will explain how
+the reference impl mappers are designed, and it is expected that the
+same design strategy can be applied to mapping to other PDP APIs,
+as well, where instead of mapping application objects to azapi objects,
+the mapping would be to the non-Xacml-PDP-specific objects.
+<H3>How to build a Mapper</H3>
+Probably the most straight-forward way to explain how to build a mapper
+is to explain how the existing mappers provided in PepApi work.
+<a name="structuremappers"><h4>Mapper structure</h4></a>
+Looking at the javadoc for
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/SimpleJavaObjectMapper.html"
+>org.openliberty.openaz.pep.SimpleJavaObjectMapper</a> as a
+typical example, we can make the following observations about its structure:
+<ul>
+<li>It implements the
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/pep/JavaObjectMapper.html"
+>org.openliberty.openaz.azapi.pep.JavaObjectMapper</a>
+interface.
+<li>The javadoc says that it supports 3 objects: String, Date, and HashMap,
+and that it maps those objects into RequestAttributes.
+<li>The 3 JavaObjectMapper interface methods: canMapObject(), map(), and
+getSupportedObjects() appear in the Method Summary for the
+SimpleJavaObjectMapper.
+<li>There are additional methods used within the implementation:
+convertDate, convertString, convertMap. These methods do the actual
+conversion of the application input object to the AzAttribute structures.
+</ul>
+<a name="methodimplmappers"><h4>Mapper method implementation</h4></a>
+<h5>getSupportedObjects</h5>
+Implementation of getSupportedObjects() in SimpleJavaObjectMapper is
+to simply create a set containing a class object for each class that
+the mapper supports. This is simply a hard-coded set which can be used
+when configuring mappers to preliminarily determine object types supported.
+<p>
+For the SimpleJavaObjectMapper, this consists of a list of 3 class types:
+String, Date, HashMap.
+<h5>canMapObject</h5>
+Implementation of canMapObject(Object obj) should be straight-forward.
+In SimpleJavaObjectMapper there is simply a sequence of "if statements"
+that use "instanceof" to test whether the obj parameter is an "instanceof"
+one of the supported object classes. If there is a match then true
+is returned, otherwise false is returned.
+<h5>map</h5>
+Implementation of the
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/pep/JavaObjectMapper.html#map(java.lang.Object,%20org.openliberty.openaz.azapi.pep.RequestAttributes)"
+>map(Object obj, RequestAttributes<T> reqAttrs)</a> method is the
+only place where there might be some non-trivial complexity to work thru.
+<p>
+In SimpleJavaObjectMapper, map(obj,reqAttrs) dispatches to a conversion
+method for one of the supported object types by going thru a similar
+sequence of "if instanceof" test and dispatching when a matching object
+class is found.
+<p>
+Within the conversion methods, the first thing considered is the AzCategoryId
+of the RequestAttributes target object, which for AzApi is an AzEntity
+AzAttribute collection. When the Mapper.map method is invoked, the caller
+needs to determine which AzCategoryId to pass to the method as the
+generic parameter T of the RequestAttributes<T> object being passed.
+<p>
+Generally, this will be implicitly determined by the entity for which
+the object being converted is intended. In the
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/azapi/pep/PepRequestFactory.html"
+>PepApi PepRequestFactory.newPepRequest(*) methods</a>,
+the objects passed are in an order that determines whether the object is
+to be considered a Subject, Action, Resource, or Environment as
+described in the signature to the newPepRequest methods.
+<p>
+One can get a rough idea of how this is implemented by following the
+<a href="#pepapiseqmodel">PepApi sequence model</a> in the first tutorial
+above. In particular, starting with PepRequestFactoryImpl call to
+setAccessSubject(sObj), one can follow the diagram logic down to
+the RequestAttributes.setAttribute(attrId, subjObj) method where the
+Mapper has been invoked and the convertObject method within the Mapper
+is setting the attribute on the AzEntity.
+<a name="permissionmappers"><H4>Permission Mapper</H4></a>
+A slightly more interesting case is the
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/SimpleJavaPermissionMapper.html">SimpleJavaPermissionMapper</a>
+<p>
+As described in the javadoc for
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/org/openliberty/openaz/pep/SimpleJavaPermissionMapper.html#map(java.lang.Object,%20org.openliberty.openaz.azapi.pep.RequestAttributes)"
+>SimpleJavaPermissionMapper.map()</a>
+a Permission or any subclass of Permission can be processed and effectively
+serialized into 3 String parameters, where the Permission subclass is assumed
+to be a "resource-type", the name parameter is assumed to be the "resource-id",
+and the action is assumed to be the "action-id", where resource-id and action-id
+are as defined in Xacml, and resource-type is an OpenAz identifier used to
+name a resource type.
+<p>
+Therefore these 3 parameters can be passed to the Xacml PDP and generally
+policies will contain regular expression conditions on resource name in order
+to create scopes of resources and actions subject to the policy. Some examples
+demonstrating this technique are included in the test program
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/doc/test/TestStyles.html"
+>TestStyles</a>
+where the code and javadoc of the testStyle* methods describe some of
+the test cases, and the
+<a href="http://openaz.svn.sourceforge.net/viewvc/openaz/test/src/test/"
+>code from the project</a>
+ may be examined.
+</body>
+</html>
\ No newline at end of file
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPI.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPI.java
new file mode 100755
index 0000000..f2173a8
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPI.java
@@ -0,0 +1,81 @@
+package org.openliberty.openaz.pepapi.std.test;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.openliberty.openaz.pepapi.*;
+import org.openliberty.openaz.pepapi.std.StdPepAgentFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class TestAPI {
+
+ private PepAgentFactory pepAgentFactory;
+
+ @Before
+ public void setup() {
+ pepAgentFactory = new StdPepAgentFactory("/properties/testapi.xacml.properties");
+ }
+
+
+ /**
+ *
+ */
+ @Test
+ public void testPepAgent() {
+ Assert.assertNotNull(getPepAgent());
+ }
+
+
+ /**
+ *
+ */
+ @Test
+ public void testPermit(){
+ PepResponse response = getPepAgent().simpleDecide("Julius Hibbert",
+ "read", "http://medico.com/record/patient/BartSimpson");
+ Assert.assertNotNull(response);
+ Assert.assertEquals(true, response.allowed());
+ }
+
+
+ /**
+ *
+ */
+ @Test
+ public void testNotApplicable(){
+ PepResponse response = getPepAgent().simpleDecide("Julius Hibbert",
+ "read","http://medico.com/record/patient/JohnSmith");
+ Assert.assertNotNull(response);
+ Assert.assertEquals(false, response.allowed());
+ }
+
+
+ /**
+ *
+ */
+ @Test
+ public void testMultiRequest() {
+ List<Action> actions = new ArrayList<Action>();
+ actions.add(Action.newInstance("read"));
+ actions.add(Action.newInstance("write"));
+ actions.add(Action.newInstance("update"));
+ actions.add(Action.newInstance("delete"));
+
+ List<PepResponse> responses = getPepAgent().bulkDecide(actions,
+ Subject.newInstance("Julius Hibbert"),
+ Resource.newInstance("http://medico.com/record/patient/BartSimpson"));
+ Assert.assertNotNull(responses);
+ Assert.assertEquals(true, responses.get(0).allowed());
+ Assert.assertEquals(true, responses.get(1).allowed());
+ Assert.assertEquals(false, responses.get(2).allowed());
+ Assert.assertEquals(false, responses.get(3).allowed());
+
+ }
+
+ public PepAgent getPepAgent() {
+ return pepAgentFactory.getPepAgent();
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.java
new file mode 100755
index 0000000..90cef8e
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.java
@@ -0,0 +1,98 @@
+package org.openliberty.openaz.pepapi.std.test;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.openliberty.openaz.pepapi.*;
+import org.openliberty.openaz.pepapi.std.StdPepAgentFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class TestAPIWithPIP {
+
+ private static final Log log = LogFactory.getLog(TestAPIWithPIP.class);
+
+ private PepAgentFactory pepAgentFactory;
+
+ @Before
+ public void setup() {
+ pepAgentFactory = new StdPepAgentFactory("xacml.properties");
+ }
+
+
+ /**
+ *
+ */
+ @Ignore
+ @Test
+ public void testPepAgent() {
+ Assert.assertNotNull(getPepAgent());
+ }
+
+
+ /**
+ *
+ */
+ @Ignore
+ @Test
+ public void testPermit() {
+ PepResponse response = getPepAgent()
+ .simpleDecide("John Doe",
+ "read",
+ "http://medico.com/record/patient/BartSimpson");
+ Assert.assertNotNull(response);
+ Assert.assertEquals(true, response.allowed());
+ }
+
+
+ /**
+ *
+ */
+ @Ignore
+ @Test
+ public void testNotApplicable() {
+ PepResponse response = getPepAgent()
+ .simpleDecide("John Smith",
+ "read",
+ "http://medico.com/record/patient/BartSimpson");
+ Assert.assertNotNull(response);
+ Assert.assertEquals(false, response.allowed());
+ }
+
+
+ /**
+ *
+ */
+ @Ignore
+ @Test
+ public void testMultiRequest() {
+ List<Action> actions = new ArrayList<Action>();
+ actions.add(Action.newInstance("read"));
+ actions.add(Action.newInstance("update"));
+ actions.add(Action.newInstance("write"));
+ actions.add(Action.newInstance("modify"));
+
+ Resource resource = Resource.newInstance("http://medico.com/record/patient/BartSimpson");
+ Subject subject = Subject.newInstance("John Doe");
+
+ List<PepResponse> responses = getPepAgent().bulkDecide(actions, resource, subject);
+ Assert.assertNotNull(responses);
+ Assert.assertEquals(actions.size(), responses.size());
+ Assert.assertEquals(true, responses.get(0).allowed());
+ Assert.assertEquals(false, responses.get(1).allowed());
+ Assert.assertEquals(true, responses.get(2).allowed());
+ Assert.assertEquals(false, responses.get(3).allowed());
+ for(PepResponse response: responses) {
+ log.debug(response.getAssociation());
+ }
+ }
+
+ public PepAgent getPepAgent() {
+ return pepAgentFactory.getPepAgent();
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.java
new file mode 100755
index 0000000..830d28e
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.java
@@ -0,0 +1,72 @@
+package org.openliberty.openaz.pepapi.std.test;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.openliberty.openaz.pepapi.*;
+import org.openliberty.openaz.pepapi.std.StdPepAgentFactory;
+import org.openliberty.openaz.pepapi.std.test.obligation.AnnotatedCatchAllObligationHandler;
+import org.openliberty.openaz.pepapi.std.test.obligation.AnnotatedFilteringObligationHandler;
+import org.openliberty.openaz.pepapi.std.test.obligation.AnnotatedRedactionObligationHandler;
+
+
+public class TestAnnotatedHandlerRegistration {
+
+ @SuppressWarnings("unused")
+ private static Log log = LogFactory.getLog(TestAnnotatedHandlerRegistration.class);
+
+ private PepAgentFactory pepAgentFactory;
+
+ //TODO: Need to wire
+ private AnnotatedFilteringObligationHandler filterHandler;
+
+ //TODO: Need to wire
+ private AnnotatedRedactionObligationHandler redactionHandler;
+
+ //TODO: Need to wire
+ private AnnotatedCatchAllObligationHandler catchAllHandler;
+
+
+ @Before
+ public void setup() {
+ pepAgentFactory = new StdPepAgentFactory("xacml.properties");
+ }
+
+
+
+ /**
+ *
+ */
+ @Ignore
+ @Test
+ public void testPepAgent() {
+ Assert.assertNotNull(getPepAgent());
+ }
+
+
+
+ /**
+ *
+ */
+ @Ignore
+ @Test
+ public void testRegistration() {
+ Subject subject = Subject.newInstance("John Smith");
+ subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:age", "45");
+ PepResponse response = getPepAgent().decide(subject, Action.newInstance("view"),
+ Resource.newInstance("resource1"));
+ Assert.assertNotNull(response);
+ Assert.assertEquals(true, response.allowed());
+ filterHandler.enforce();
+ redactionHandler.enforce();
+ catchAllHandler.enforce();
+ }
+
+ public PepAgent getPepAgent() {
+ return pepAgentFactory.getPepAgent();
+ }
+
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestDataTypes.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestDataTypes.java
new file mode 100755
index 0000000..40a39da
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestDataTypes.java
@@ -0,0 +1,85 @@
+package org.openliberty.openaz.pepapi.std.test;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.openliberty.openaz.pepapi.*;
+import org.openliberty.openaz.pepapi.std.StdPepAgentFactory;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class TestDataTypes {
+
+ private PepAgentFactory pepAgentFactory;
+
+ @Before
+ public void setup() {
+ /*System.setProperty("xacml.properties" ,
+ getClass().getClassLoader().getResource("properties/testdatatypes.xacml.properties").getPath());*/
+ pepAgentFactory = new StdPepAgentFactory("/properties/testdatatypes.xacml.properties");
+ }
+
+
+ /**
+ *
+ */
+ @Test
+ public void testPepAgent() {
+ Assert.assertNotNull(getPepAgent());
+ }
+
+
+ /**
+ *
+ */
+ @Test
+ public void testPermitWithURIResource() {
+ Subject subject = Subject.newInstance("John Smith");
+ Action action = Action.newInstance("view");
+ Resource resource = Resource.newInstance(URI.create("file://repository/classified/abc"));
+ PepResponse response = getPepAgent().decide(subject, action, resource);
+ Assert.assertNotNull(response);
+ Assert.assertEquals(true, response.allowed());
+ }
+
+
+ /**
+ *
+ */
+ @Test
+ public void testPermitWithIntegerResource() {
+ Subject subject = Subject.newInstance("John Smith");
+ Action action = Action.newInstance("view");
+ Resource resource = Resource.newInstance(101L);
+ PepResponse response = getPepAgent().decide(subject, action, resource);
+ Assert.assertNotNull(response);
+ Assert.assertEquals(true, response.allowed());
+ }
+
+
+ /**
+ *
+ */
+ @Test
+ public void testMultiRequestWithURI() {
+ List<Resource> resources = new ArrayList<Resource>();
+ resources.add(Resource.newInstance(URI.create("file://repository/classified/abc")));
+ resources.add(Resource.newInstance(URI.create("file://repository/classified/xyz")));
+
+ Subject subject = Subject.newInstance("John Smith");
+ Action action = Action.newInstance("view");
+
+ List<PepResponse> responses = getPepAgent().bulkDecide(resources, action, subject);
+ Assert.assertNotNull(responses);
+ for(PepResponse response: responses) {
+ Assert.assertEquals(true, response.allowed());
+ }
+ }
+
+ public PepAgent getPepAgent() {
+ return pepAgentFactory.getPepAgent();
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestMapper.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestMapper.java
new file mode 100755
index 0000000..0c4c50e
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestMapper.java
@@ -0,0 +1,123 @@
+package org.openliberty.openaz.pepapi.std.test;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.openliberty.openaz.pepapi.*;
+import org.openliberty.openaz.pepapi.std.StdPepAgentFactory;
+import org.openliberty.openaz.pepapi.std.test.mapper.BusinessRequestContext;
+import org.openliberty.openaz.pepapi.std.test.mapper.Client;
+import org.openliberty.openaz.pepapi.std.test.mapper.Document;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class TestMapper {
+
+ @SuppressWarnings("unused")
+ private static Log logger = LogFactory.getLog(TestMapper.class);
+
+ private PepAgentFactory pepAgentFactory;
+
+ @Before
+ public void setup() {
+ this.pepAgentFactory = new StdPepAgentFactory("/properties/testmapper.xacml.properties");
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testPepAgent() {
+ Assert.assertNotNull(getPepAgent());
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testPermit() {
+ Subject subject = Subject.newInstance("John Smith");
+ subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:role-id", "ROLE_DOCUMENT_WRITER");
+
+ Action action = Action.newInstance("write");
+
+ Document doc = new Document(1, "OnBoarding Document", "ABC Corporation", "John Smith");
+ PepResponse response = getPepAgent().decide(subject, action, doc);
+ Assert.assertNotNull(response);
+ Assert.assertEquals(true, response.allowed());
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testNotApplicable(){
+ Subject subject = Subject.newInstance("John Smith");
+ subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:role-id", "ROLE_DOCUMENT_WRITER");
+
+ Action action = Action.newInstance("write");
+ Document doc = new Document(2, "OnBoarding Document", "XYZ Corporation", "Jim Doe");
+ PepResponse response = getPepAgent().decide(subject, action, doc);
+ Assert.assertNotNull(response);
+ Assert.assertEquals(false, response.allowed());
+ }
+
+ @Test(expected=PepException.class)
+ public void testMix(){
+ Subject subject = Subject.newInstance("John Smith");
+ subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:role-id", "ROLE_DOCUMENT_WRITER");
+
+ Action action = Action.newInstance("write");
+
+ Document doc1 = new Document(1, "OnBoarding Document", "ABC Corporation", "John Smith");
+ Document doc2 = new Document(2, "OnBoarding Document", "XYZ Corporation", "Jim Doe");
+ List<Object> resourceList = new ArrayList<Object>();
+ resourceList.add(doc1);
+ resourceList.add(doc2);
+
+ PepResponse response = getPepAgent().decide(subject, action, resourceList);
+ Assert.assertNotNull(response);
+ response.allowed();
+ }
+
+ @Test
+ public void testVarArgsPermit(){
+ Subject subject = Subject.newInstance("John Smith");
+ subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:role-id", "ROLE_DOCUMENT_READER");
+ BusinessRequestContext bc = new BusinessRequestContext("USA", "05:00 EST");
+
+ Action action = Action.newInstance("read");
+ List<Object> resources = new ArrayList<Object>();
+ resources.add(new Document(1, "OnBoarding Document", "XYZ Corporation", "Jim Doe"));
+ resources.add(new Client("XYZ Corporation", "USA"));
+
+ PepResponse response = getPepAgent().decide(subject, action, resources, bc);
+ Assert.assertNotNull(response);
+ Assert.assertEquals(true, response.allowed());
+ }
+
+ @Test
+ public void testVarArgsDeny(){
+ Subject subject = Subject.newInstance("John Smith");
+ subject.addAttribute("urn:oasis:names:tc:xacml:1.0:subject:role-id", "ROLE_DOCUMENT_READER");
+ BusinessRequestContext bc = new BusinessRequestContext("INDIA", "05:00 IST");
+
+ List<Object> resources = new ArrayList<Object>();
+ resources.add(new Document(2, "OnBoarding Document", "XYZ Corporation", "Jim Doe"));
+ resources.add(new Client("XYZ Corporation", "USA"));
+
+ Action action = Action.newInstance("write");
+
+ PepResponse response = getPepAgent().decide(subject, action, resources, bc);
+ Assert.assertNotNull(response);
+ Assert.assertEquals(false, response.allowed());
+ }
+
+ public PepAgent getPepAgent() {
+ return pepAgentFactory.getPepAgent();
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.java
new file mode 100755
index 0000000..1820428
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.java
@@ -0,0 +1,21 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;
+
+public class BusinessRequestContext {
+
+ private final String requestCountry;
+
+ private final String requestTime;
+
+ public BusinessRequestContext(String country, String time){
+ this.requestCountry = country;
+ this.requestTime = time;
+ }
+
+ public String getRequestCountry() {
+ return requestCountry;
+ }
+
+ public String getRequestTime() {
+ return requestTime;
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.java
new file mode 100755
index 0000000..3b1c93a
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.java
@@ -0,0 +1,34 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;
+
+import com.att.research.xacml.api.XACML3;
+import org.openliberty.openaz.pepapi.*;
+
+public class BusinessRequestContextMapper implements ObjectMapper {
+
+ private MapperRegistry mapperRegistry;
+
+ private PepConfig pepConfig;
+
+ @Override
+ public Class<?> getMappedClass() {
+ return BusinessRequestContext.class;
+ }
+
+ @Override
+ public void map(Object o, PepRequest pepRequest) {
+ BusinessRequestContext bc = (BusinessRequestContext)o;
+ PepRequestAttributes envAttributes = pepRequest.getPepRequestAttributes(XACML3.ID_ATTRIBUTE_CATEGORY_ENVIRONMENT);
+ envAttributes.addAttribute("jpmc:request-context:country", bc.getRequestCountry());
+ envAttributes.addAttribute("jpmc:request-context:time", bc.getRequestTime());
+ }
+
+ @Override
+ public void setMapperRegistry(MapperRegistry mapperRegistry) {
+ this.mapperRegistry = mapperRegistry;
+ }
+
+ @Override
+ public void setPepConfig(PepConfig pepConfig) {
+ this.pepConfig = pepConfig;
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Client.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Client.java
new file mode 100755
index 0000000..9c2ca08
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Client.java
@@ -0,0 +1,20 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;
+
+public class Client {
+
+ private final String name;
+
+ private final String countryOfDomicile;
+
+ public Client(String name, String countryOfDomicile){
+ this.name = name;
+ this.countryOfDomicile = countryOfDomicile;
+ }
+
+ public String getName() {
+ return name;
+ }
+ public String getCountryOfDomicile() {
+ return countryOfDomicile;
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.java
new file mode 100755
index 0000000..b482a44
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.java
@@ -0,0 +1,34 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;
+
+import com.att.research.xacml.api.XACML3;
+import org.openliberty.openaz.pepapi.*;
+
+public class ClientMapper implements ObjectMapper {
+
+ private MapperRegistry mapperRegistry;
+
+ private PepConfig pepConfig;
+
+ @Override
+ public Class<?> getMappedClass() {
+ return Client.class;
+ }
+
+ @Override
+ public void map(Object o, PepRequest pepRequest) {
+ Client c = (Client)o;
+ PepRequestAttributes resAttributes = pepRequest.getPepRequestAttributes(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
+ resAttributes.addAttribute("jpmc:client:name", c.getName());
+ resAttributes.addAttribute("jpmc:client:country-of-domicile", c.getCountryOfDomicile());
+ }
+
+ @Override
+ public void setMapperRegistry(MapperRegistry mapperRegistry) {
+ this.mapperRegistry = mapperRegistry;
+ }
+
+ @Override
+ public void setPepConfig(PepConfig pepConfig) {
+ this.pepConfig = pepConfig;
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Document.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Document.java
new file mode 100755
index 0000000..cd36245
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Document.java
@@ -0,0 +1,32 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;
+
+public class Document {
+
+ private final Integer documentId;
+ private final String documentName;
+ private final String clientName;
+ private final String documentOwner;
+
+ public Document(Integer documentId, String documentName, String clientName, String documentOwner){
+ this.documentId = documentId;
+ this.documentName = documentName;
+ this.clientName = clientName;
+ this.documentOwner = documentOwner;
+ }
+
+ public Integer getDocumentId() {
+ return documentId;
+ }
+
+ public String getDocumentName() {
+ return documentName;
+ }
+
+ public String getDocumentOwner() {
+ return documentOwner;
+ }
+
+ public String getClientName() {
+ return clientName;
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.java
new file mode 100755
index 0000000..498d3ee
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.java
@@ -0,0 +1,37 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;
+
+import com.att.research.xacml.api.XACML3;
+import org.openliberty.openaz.pepapi.*;
+
+public class DocumentMapper implements ObjectMapper {
+
+ private MapperRegistry mapperRegistry;
+
+ private PepConfig pepConfig;
+
+ @Override
+ public Class<?> getMappedClass() {
+ return Document.class;
+ }
+
+ @Override
+ public void map(Object o, PepRequest pepRequest) {
+ Document d = (Document)o;
+ PepRequestAttributes resourceAttributes = pepRequest.getPepRequestAttributes(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
+ resourceAttributes.addAttribute("urn:oasis:names:tc:xacml:1.0:resource:resource-id", d.getDocumentId());
+ resourceAttributes.addAttribute("urn:oasis:names:tc:xacml:1.0:resource:resource-type", "Document");
+ resourceAttributes.addAttribute("jpmc:document:document-name", d.getDocumentName());
+ resourceAttributes.addAttribute("jpmc:document:client-name", d.getClientName());
+ resourceAttributes.addAttribute("jpmc:document:document-owner", d.getDocumentOwner());
+ }
+
+ @Override
+ public void setMapperRegistry(MapperRegistry mapperRegistry) {
+ this.mapperRegistry = mapperRegistry;
+ }
+
+ @Override
+ public void setPepConfig(PepConfig pepConfig) {
+ this.pepConfig = pepConfig;
+ }
+}
\ No newline at end of file
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.java
new file mode 100755
index 0000000..6a7b317
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.java
@@ -0,0 +1,37 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MedicalRecord {
+
+ private String id;
+
+ private List<String> accessUserGroup;
+
+ public MedicalRecord(String id){
+ this.id = id;
+ accessUserGroup = new ArrayList<String>();
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public List<String> getAccessUserGroup() {
+ return accessUserGroup;
+ }
+
+ public void setAccessUserGroup(List<String> accessUserGroup) {
+ this.accessUserGroup = accessUserGroup;
+ }
+
+ public void addUserToAccessGroup(String user) {
+ this.accessUserGroup.add(user);
+ }
+
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.java
new file mode 100755
index 0000000..9882d30
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.java
@@ -0,0 +1,36 @@
+package org.openliberty.openaz.pepapi.std.test.mapper;
+
+import com.att.research.xacml.api.XACML3;
+import org.openliberty.openaz.pepapi.*;
+
+public class MedicalRecordMapper implements ObjectMapper {
+
+ private MapperRegistry mapperRegistry;
+
+ private PepConfig pepConfig;
+
+ @Override
+ public Class<?> getMappedClass() {
+ return MedicalRecord.class;
+ }
+
+ @Override
+ public void map(Object o, PepRequest pepRequest) {
+ MedicalRecord md = (MedicalRecord) o;
+ PepRequestAttributes resourceAttributes = pepRequest.getPepRequestAttributes(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
+ resourceAttributes.addAttribute("urn:oasis:names:tc:xacml:1.0:resource:resource-type", "PatientMedicalRecord");
+ resourceAttributes.addAttribute("urn:oasis:names:tc:xacml:1.0:resource:resource-id", md.getId());
+ for(String accessUser: md.getAccessUserGroup()) {
+ resourceAttributes.addAttribute("urn:oasis:names:tc:xacml:1.0:resource:resource-access-group", accessUser);
+ }
+ }
+ @Override
+ public void setMapperRegistry(MapperRegistry mapperRegistry) {
+ this.mapperRegistry = mapperRegistry;
+ }
+
+ @Override
+ public void setPepConfig(PepConfig pepConfig) {
+ this.pepConfig = pepConfig;
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.java
new file mode 100755
index 0000000..2fd5b9a
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.java
@@ -0,0 +1,56 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;
+
+import junit.framework.Assert;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.ObligationHandler;
+import org.openliberty.openaz.pepapi.ObligationStore;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+
+public class AccessRestrictionObligationHandler implements ObligationHandler {
+
+ private static Log log = LogFactory.getLog(AccessRestrictionObligationHandler.class);
+
+ private ObligationStore obligationStore;
+
+ public void enforce() {
+ Set<Obligation> accessOblgSet = obligationStore.getHandlerObligations(this.getClass());
+ Assert.assertEquals(true, accessOblgSet.size() == 1);
+ for(Obligation oblg: accessOblgSet) {
+ Map<String, Object[]> attributeMap = oblg.getAttributeMap();
+ Assert.assertNotNull(attributeMap);
+ for(Entry<String, Object[]> e: attributeMap.entrySet()){
+ if(e.getKey().equals("urn:oasis:names:tc:xacml:1.0:subject:subject-id")){
+ Assert.assertNotNull(e.getValue());
+ }
+ if(e.getKey().equals("urn:oasis:names:tc:xacml:1.0:resource:resource-access-group")){
+ Object[] values = e.getValue();
+ Assert.assertNotNull(values);
+ Assert.assertEquals(3, values.length);
+ }
+ }
+ }
+ Obligation accessGroupOblg = obligationStore.getHandlerObligationById(
+ this.getClass(),
+ "urn:oasis:names:tc:xacml:2.0:obligation:access-restriction");
+ Assert.assertNotNull(accessGroupOblg);
+ log.info(accessGroupOblg.getId());
+ }
+
+ @Override
+ public boolean match(Obligation obligation) {
+ return obligation.getId().
+ equals("urn:oasis:names:tc:xacml:2.0:obligation:access-restriction");
+ }
+
+ @Override
+ public void setObligationStore(ObligationStore oStore) {
+ this.obligationStore = oStore;
+ }
+
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.java
new file mode 100755
index 0000000..6239412
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.java
@@ -0,0 +1,52 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;
+
+import junit.framework.Assert;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.ObligationHandler;
+import org.openliberty.openaz.pepapi.ObligationStore;
+import org.openliberty.openaz.pepapi.std.test.util.HasResult;
+
+import java.util.Map;
+import java.util.Set;
+
+public class AgeRestrictionObligationHandler implements ObligationHandler, HasResult {
+
+ private static Log log = LogFactory.getLog(AgeRestrictionObligationHandler.class);
+
+ private ObligationStore obligationStore;
+
+ public String enforce() {
+ Set<Obligation> ageOblgSet = obligationStore.getHandlerObligations(this.getClass());
+ Assert.assertEquals(true, ageOblgSet.size() == 1);
+ Obligation ageOblg = obligationStore.getHandlerObligationById(this.getClass(),
+ "urn:oasis:names:tc:xacml:2.0:obligation:age-restriction");
+ Assert.assertNotNull(ageOblg);
+ String value = null;
+ log.info(ageOblg.getId());
+ //Enforcement Logic
+ Map<String, Object[]> attributeMap = ageOblg.getAttributeMap();
+ Object[] values = attributeMap.get("urn:oasis:names:tc:xacml:1.0:subject:age");
+ if(values != null) {
+ value = (String)values[0];
+ }
+ return value;
+ }
+
+ @Override
+ public boolean match(Obligation obligation) {
+ return obligation.getId().
+ equals("urn:oasis:names:tc:xacml:2.0:obligation:age-restriction");
+ }
+
+ @Override
+ public void setObligationStore(ObligationStore obligationStore) {
+ this.obligationStore = obligationStore;
+ }
+
+ @Override
+ public String getResult() {
+ return enforce();
+ }
+}
\ No newline at end of file
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.java
new file mode 100755
index 0000000..d717acb
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.java
@@ -0,0 +1,44 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;
+
+import junit.framework.Assert;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.ObligationStore;
+import org.openliberty.openaz.pepapi.ObligationStoreAware;
+import org.openliberty.openaz.pepapi.MatchAnyObligation;
+
+import java.util.Map.Entry;
+
+@MatchAnyObligation("urn:oasis:names:tc:xacml:2.0:obligation:access-restriction")
+public class AnnotatedAccessRestrictionObligationHandler implements ObligationStoreAware {
+
+ private static Log log = LogFactory.getLog(AnnotatedAccessRestrictionObligationHandler.class);
+
+ private ObligationStore obligationStore;
+
+ public void enforce() {
+ Obligation accessGroupOblg = obligationStore.getHandlerObligationById(
+ this.getClass(),
+ "urn:oasis:names:tc:xacml:2.0:obligation:access-restriction");
+ Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:access-restriction",
+ accessGroupOblg.getId());
+ log.info(accessGroupOblg.getId());
+ for(Entry<String, Object[]> e: accessGroupOblg.getAttributeMap().entrySet()){
+ if(e.getKey().equals("urn:oasis:names:tc:xacml:1.0:subject:subject-id")){
+ Assert.assertNotNull(e.getValue());
+ }
+ if(e.getKey().equals("urn:oasis:names:tc:xacml:1.0:resource:resource-access-group")){
+ Object[] values = e.getValue();
+ Assert.assertNotNull(values);
+ Assert.assertEquals(3, values.length);
+ }
+ }
+ //Enforcement Logic
+ }
+
+ @Override
+ public void setObligationStore(ObligationStore obligationStore) {
+ this.obligationStore = obligationStore;
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.java
new file mode 100755
index 0000000..9a10cfc
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.java
@@ -0,0 +1,46 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;
+
+import junit.framework.Assert;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.ObligationStore;
+import org.openliberty.openaz.pepapi.ObligationStoreAware;
+import org.openliberty.openaz.pepapi.MatchAnyObligation;
+import org.openliberty.openaz.pepapi.std.test.util.HasResult;
+
+import java.util.Map;
+
+@MatchAnyObligation("urn:oasis:names:tc:xacml:2.0:obligation:age-restriction")
+public class AnnotatedAgeRestrictionObligationHandler implements ObligationStoreAware, HasResult {
+
+ private static Log log = LogFactory.getLog(AnnotatedAgeRestrictionObligationHandler.class);
+
+ private ObligationStore obligationStore;
+
+ public String enforce() {
+ Obligation ageOblg = obligationStore.getHandlerObligationById(
+ this.getClass(),
+ "urn:oasis:names:tc:xacml:2.0:obligation:age-restriction");
+ String value = null;
+ Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:age-restriction", ageOblg.getId());
+ log.info(ageOblg.getId());
+ //Enforcement Logic
+ Map<String, Object[]> attributeMap = ageOblg.getAttributeMap();
+ Object[] values = attributeMap.get("urn:oasis:names:tc:xacml:1.0:subject:age");
+ if(values != null) {
+ value = (String)values[0];
+ }
+ return value;
+ }
+
+ @Override
+ public void setObligationStore(ObligationStore obligationStore) {
+ this.obligationStore = obligationStore;
+ }
+
+ @Override
+ public String getResult() {
+ return enforce();
+ }
+}
\ No newline at end of file
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.java
new file mode 100755
index 0000000..c7a6780
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.java
@@ -0,0 +1,36 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;
+
+import junit.framework.Assert;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.ObligationStore;
+import org.openliberty.openaz.pepapi.ObligationStoreAware;
+import org.openliberty.openaz.pepapi.MatchAnyObligation;
+
+import java.util.Set;
+
+@MatchAnyObligation("urn:oasis:names:tc:xacml:2.0:obligation:audit")
+public class AnnotatedAuditObligationHandler implements ObligationStoreAware {
+
+ private static Log log = LogFactory.getLog(AnnotatedAuditObligationHandler.class);
+
+ private ObligationStore obligationStore;
+
+ public void enforce() {
+ Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass());
+ if(obligationSet.size() == 1) {
+ for(Obligation obligation: obligationSet) {
+ Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:audit", obligation.getId());
+ log.info(obligation.getId());
+ }
+ }else {
+ Assert.assertFalse(true);
+ }
+ }
+
+ @Override
+ public void setObligationStore(ObligationStore obligationStore) {
+ this.obligationStore = obligationStore;
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.java
new file mode 100755
index 0000000..0e74d8d
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.java
@@ -0,0 +1,36 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;
+
+import junit.framework.Assert;
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.ObligationStore;
+import org.openliberty.openaz.pepapi.ObligationStoreAware;
+import org.openliberty.openaz.pepapi.MatchAnyObligation;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@MatchAnyObligation
+public class AnnotatedCatchAllObligationHandler implements ObligationStoreAware {
+
+ private ObligationStore obligationStore;
+
+ public void enforce() {
+ Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass());
+ if(obligationSet.size() == 2) {
+ Set<String> obligationIds = new HashSet<String>();
+ for(Obligation oblg: obligationSet){
+ obligationIds.add(oblg.getId());
+ }
+ Assert.assertTrue(obligationIds.contains("urn:oasis:names:tc:xacml:2.0:obligation:obligation-1"));
+ Assert.assertTrue(obligationIds.contains("urn:oasis:names:tc:xacml:2.0:obligation:obligation-2"));
+ }else {
+ Assert.assertFalse(true);
+ }
+
+ }
+
+ @Override
+ public void setObligationStore(ObligationStore obligationStore) {
+ this.obligationStore = obligationStore;
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.java
new file mode 100755
index 0000000..29f49a0
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.java
@@ -0,0 +1,36 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;
+
+import junit.framework.Assert;
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.ObligationStore;
+import org.openliberty.openaz.pepapi.ObligationStoreAware;
+import org.openliberty.openaz.pepapi.Attribute;
+import org.openliberty.openaz.pepapi.MatchAllObligationAttributes;
+
+import java.util.Set;
+
+@MatchAllObligationAttributes({
+ @Attribute(id="jpmc:obligation:obligation-type", anyValue="Filtering"),
+ @Attribute(id="urn:oasis:names:tc:xacml:1.0:subject:subject-id")
+})
+public class AnnotatedFilteringObligationHandler implements ObligationStoreAware {
+
+ private ObligationStore obligationStore;
+
+ public void enforce() {
+ Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass());
+ if(obligationSet.size() == 1) {
+ for(Obligation obligation: obligationSet) {
+ Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:obligation-1",
+ obligation.getId());
+ }
+ }else {
+ Assert.assertFalse(true);
+ }
+ }
+
+ @Override
+ public void setObligationStore(ObligationStore obligationStore) {
+ this.obligationStore = obligationStore;
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.java
new file mode 100755
index 0000000..57d5adf
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.java
@@ -0,0 +1,19 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;
+
+import org.openliberty.openaz.pepapi.Attribute;
+import org.openliberty.openaz.pepapi.MatchAllObligationAttributes;
+import org.openliberty.openaz.pepapi.MatchAnyObligation;
+
+@MatchAnyObligation({"jpmc:obligation:one","jpmc:obligation:two","jpmc:obligation:three"})
+@MatchAllObligationAttributes({
+ @Attribute(id="jpmc:obligation:obligation-type", anyValue={"FILTERING","REDACTION"}),
+ @Attribute(id="jpmc:resource:attribute:resource-type", anyValue={"Card"}),
+ @Attribute(id="jpmc:obligation:attribute:attribute-1")
+})
+public class AnnotatedObligationHandler {
+
+ public void enforce() {
+
+ }
+
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.java
new file mode 100755
index 0000000..780a69e
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.java
@@ -0,0 +1,35 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;
+
+import junit.framework.Assert;
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.ObligationStore;
+import org.openliberty.openaz.pepapi.ObligationStoreAware;
+import org.openliberty.openaz.pepapi.Attribute;
+import org.openliberty.openaz.pepapi.MatchAllObligationAttributes;
+
+import java.util.Set;
+
+@MatchAllObligationAttributes(
+ @Attribute(id="urn:oasis:names:tc:xacml:1.0:subject:age")
+)
+public class AnnotatedRedactionObligationHandler implements ObligationStoreAware {
+
+ private ObligationStore obligationStore;
+
+ public void enforce() {
+ Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass());
+ if(obligationSet.size() == 1) {
+ for(Obligation obligation: obligationSet) {
+ Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:obligation-2",
+ obligation.getId());
+ }
+ }else {
+ Assert.assertFalse(true);
+ }
+ }
+
+ @Override
+ public void setObligationStore(ObligationStore obligationStore) {
+ this.obligationStore = obligationStore;
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.java
new file mode 100755
index 0000000..64c6c41
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.java
@@ -0,0 +1,37 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;
+
+import junit.framework.Assert;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.ObligationHandler;
+import org.openliberty.openaz.pepapi.ObligationStore;
+
+import java.util.Set;
+
+public class AuditObligationHandler implements ObligationHandler {
+
+ private static Log log = LogFactory.getLog(AuditObligationHandler.class);
+
+ private ObligationStore obligationStore;
+
+ public void enforce() {
+ Set<Obligation> auditOblgSet = obligationStore.getHandlerObligations(this.getClass());
+ Assert.assertEquals(true, auditOblgSet.size() == 1);
+ Obligation auditOblg = obligationStore.getHandlerObligationById(
+ this.getClass(),
+ "urn:oasis:names:tc:xacml:2.0:obligation:audit");
+ Assert.assertNotNull(auditOblg);
+ log.info(auditOblg.getId());
+ }
+
+ @Override
+ public boolean match(Obligation t) {
+ return t.getId().equals("urn:oasis:names:tc:xacml:2.0:obligation:audit");
+ }
+
+ @Override
+ public void setObligationStore(ObligationStore obligationStore) {
+ this.obligationStore = obligationStore;
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.java
new file mode 100755
index 0000000..68732f3
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.java
@@ -0,0 +1,41 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;
+
+import junit.framework.Assert;
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.ObligationHandler;
+import org.openliberty.openaz.pepapi.ObligationStore;
+
+import java.util.HashSet;
+import java.util.Set;
+
+
+public class CatchAllObligationHandler implements ObligationHandler {
+
+ private ObligationStore obligationStore;
+
+ public void enforce() {
+ Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass());
+ if(obligationSet.size() == 2) {
+ Set<String> obligationIds = new HashSet<String>();
+ for(Obligation oblg: obligationSet){
+ obligationIds.add(oblg.getId());
+ }
+ Assert.assertTrue(obligationIds.contains("urn:oasis:names:tc:xacml:2.0:obligation:obligation-1"));
+ Assert.assertTrue(obligationIds.contains("urn:oasis:names:tc:xacml:2.0:obligation:obligation-2"));
+ }else {
+ Assert.assertFalse(true);
+ }
+
+ }
+
+ @Override
+ public boolean match(Obligation obligation) {
+ return true;
+ }
+
+ @Override
+ public void setObligationStore(ObligationStore obligationStore) {
+ this.obligationStore = obligationStore;
+ }
+
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.java
new file mode 100755
index 0000000..427b1e3
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.java
@@ -0,0 +1,45 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;
+
+import junit.framework.Assert;
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.ObligationHandler;
+import org.openliberty.openaz.pepapi.ObligationStore;
+
+import java.util.Map;
+import java.util.Set;
+
+public class FilteringObligationHandler implements ObligationHandler {
+
+ private ObligationStore obligationStore;
+
+ public void enforce() {
+ Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass());
+ if(obligationSet.size() == 1) {
+ for(Obligation obligation: obligationSet) {
+ Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:obligation-1",
+ obligation.getId());
+ }
+ }else {
+ Assert.assertFalse(true);
+ }
+ }
+
+ @Override
+ public boolean match(Obligation obligation) {
+ Map<String, Object[]> map = obligation.getAttributeMap();
+ if(map.containsKey("jpmc:obligation:obligation-type")) {
+ Object[] values = map.get("jpmc:obligation:obligation-type");
+ if(values != null && values.length != 0) {
+ for(Object value: values) {
+ return value.equals("Filtering");
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void setObligationStore(ObligationStore obligationStore) {
+ this.obligationStore = obligationStore;
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.java
new file mode 100755
index 0000000..7a262b0
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.java
@@ -0,0 +1,37 @@
+package org.openliberty.openaz.pepapi.std.test.obligation;
+
+import junit.framework.Assert;
+import org.openliberty.openaz.pepapi.Obligation;
+import org.openliberty.openaz.pepapi.ObligationHandler;
+import org.openliberty.openaz.pepapi.ObligationStore;
+
+import java.util.Map;
+import java.util.Set;
+
+public class RedactionObligationHandler implements ObligationHandler {
+
+ private ObligationStore obligationStore;
+
+ public void enforce() {
+ Set<Obligation> obligationSet = obligationStore.getHandlerObligations(this.getClass());
+ if(obligationSet.size() == 1) {
+ for(Obligation obligation: obligationSet) {
+ Assert.assertEquals("urn:oasis:names:tc:xacml:2.0:obligation:obligation-2",
+ obligation.getId());
+ }
+ }else {
+ Assert.assertFalse(true);
+ }
+ }
+
+ @Override
+ public boolean match(Obligation obligation) {
+ Map<String, Object[]> map = obligation.getAttributeMap();
+ return map.containsKey("urn:oasis:names:tc:xacml:1.0:subject:age");
+ }
+
+ @Override
+ public void setObligationStore(ObligationStore obligationStore) {
+ this.obligationStore = obligationStore;
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.java
new file mode 100755
index 0000000..e6b524a
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.java
@@ -0,0 +1,53 @@
+package org.openliberty.openaz.pepapi.std.test.util;
+
+import org.openliberty.openaz.pepapi.PepAgent;
+import org.openliberty.openaz.pepapi.PepResponse;
+
+import java.util.concurrent.Callable;
+
+
+public class AzInvoker implements Callable<String> {
+
+ private final PepAgent pepAgent;
+
+ private final Object subject;
+
+ private final Object action;
+
+ private final Object resource;
+
+ private final long sleepDuration;
+
+ private final HasResult handler;
+
+ public AzInvoker(PepAgent pepAgent, Object subject, Object action,
+ Object resource, HasResult handler, long sleepDuration) {
+ this.pepAgent = pepAgent;
+ this.subject = subject;
+ this.action = action;
+ this.resource = resource;
+ this.handler = handler;
+ this.sleepDuration = sleepDuration;
+ }
+
+ private String invoke()throws InterruptedException{
+ PepResponse response = pepAgent.decide(subject, action, resource);
+ if(response != null){
+ response.allowed();
+ }
+ Thread.sleep(this.sleepDuration);
+ return handler.getResult();
+ }
+
+ public String call() throws Exception {
+ return invoke();
+ }
+
+ public long getSleepDuration() {
+ return sleepDuration;
+ }
+
+ public HasResult getPep() {
+ return handler;
+ }
+}
diff --git a/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/HasResult.java b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/HasResult.java
new file mode 100755
index 0000000..c22258f
--- /dev/null
+++ b/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/HasResult.java
@@ -0,0 +1,7 @@
+package org.openliberty.openaz.pepapi.std.test.util;
+
+public interface HasResult {
+
+ public String getResult();
+
+}
diff --git a/openaz-pep/src/test/resources/log4j.xml b/openaz-pep/src/test/resources/log4j.xml
new file mode 100755
index 0000000..ff481f9
--- /dev/null
+++ b/openaz-pep/src/test/resources/log4j.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
+
+ <appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} [%t] %5p %c{1} - %m%n"/>
+ </layout>
+ </appender>
+
+ <appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">
+ <param name="append" value="false"/>
+ <param name="file" value="target/openaz-junit-tests.log"/>
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} [%t] %5p %c{1} - %m%n"/>
+ </layout>
+ </appender>
+
+ <logger name="org.openliberty.openaz">
+ <level value="debug"/>
+ </logger>
+
+ <logger name="org.springframework">
+ <level value="error"/>
+ </logger>
+
+ <root>
+ <level value="debug"/>
+ <appender-ref ref="consoleAppender"/>
+ <!-- <appender-ref ref="fileAppender"/> -->
+ </root>
+
+</log4j:configuration>
\ No newline at end of file
diff --git a/openaz-pep/src/test/resources/policies/TestPolicy001.xml b/openaz-pep/src/test/resources/policies/TestPolicy001.xml
new file mode 100755
index 0000000..4f2a711
--- /dev/null
+++ b/openaz-pep/src/test/resources/policies/TestPolicy001.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test001:policy"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd">
+ <Description></Description>
+ <Target/>
+ <Rule RuleId="urn:oasis:names:tc:xacml:1.0:test001:rule-1" Effect="Permit">
+ <Description>
+ Julius Hibbert can read or write Bart Simpson's medical record.
+ </Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">Julius Hibbert</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ </Rule>
+</Policy>
diff --git a/openaz-pep/src/test/resources/policies/TestPolicy002.xml b/openaz-pep/src/test/resources/policies/TestPolicy002.xml
new file mode 100755
index 0000000..d0308c9
--- /dev/null
+++ b/openaz-pep/src/test/resources/policies/TestPolicy002.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Policy
+ xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ PolicyId="urn:oasis:names:tc:xacml:1.0:conformance-test:IIA2:policy"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides">
+ <Description>
+ Policy for Conformance Test IIA001.
+ </Description>
+ <Target/>
+ <Rule
+ RuleId="urn:oasis:names:tc:xacml:1.0:test-2:rule-1"
+ Effect="Permit">
+ <Description>
+ Physicians can read or write Bart Simpson's medical record.
+ </Description>
+ <Target>
+ <Subjects>
+ <Subject>
+ <SubjectMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">Physician</AttributeValue>
+ <SubjectAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </SubjectMatch>
+ </Subject>
+ </Subjects>
+ <Resources>
+ <Resource>
+ <ResourceMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue>
+ <ResourceAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ResourceMatch>
+ </Resource>
+ </Resources>
+ <Actions>
+ <Action>
+ <ActionMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
+ <ActionAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ActionMatch>
+ </Action>
+ <Action>
+ <ActionMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue>
+ <ActionAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ActionMatch>
+ </Action>
+ </Actions>
+ </Target>
+ </Rule>
+ <Rule
+ RuleId="urn:oasis:names:tc:xacml:1.0:test-2:rule-2"
+ Effect="Permit">
+ <Description>
+ Patient is allowed to read his/her medical record.
+ </Description>
+ <Target>
+ <Subjects>
+ <Subject>
+ <SubjectMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">Patient</AttributeValue>
+ <SubjectAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </SubjectMatch>
+ </Subject>
+ </Subjects>
+ <Resources>
+ <Resource>
+ <ResourceMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue>
+ <ResourceAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ResourceMatch>
+ </Resource>
+ </Resources>
+ <Actions>
+ <Action>
+ <ActionMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
+ <ActionAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ActionMatch>
+ </Action>
+ </Actions>
+ </Target>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-owner"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <SubjectAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"
+ SubjectCategory="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" />
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+</Policy>
diff --git a/openaz-pep/src/test/resources/policies/TestPolicy003.xml b/openaz-pep/src/test/resources/policies/TestPolicy003.xml
new file mode 100755
index 0000000..f730e34
--- /dev/null
+++ b/openaz-pep/src/test/resources/policies/TestPolicy003.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test003:policy"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd">
+ <Description></Description>
+ <Target/>
+ <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test003:rule1" Effect="Permit">
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#anyURI">file://repository/classified/abc</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
+ DataType="http://www.w3.org/2001/XMLSchema#anyURI" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ </Rule>
+ <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test003:rule2" Effect="Permit">
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#anyURI">file://repository/classified/xyz</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
+ DataType="http://www.w3.org/2001/XMLSchema#anyURI" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ </Rule>
+ <Rule RuleId="urn:oasis:names:tc:xacml:1.0:conformance-test:IIA3:rule3" Effect="Permit">
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:integer-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#integer">101</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
+ DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ </Rule>
+</Policy>
diff --git a/openaz-pep/src/test/resources/policies/TestPolicy004.xml b/openaz-pep/src/test/resources/policies/TestPolicy004.xml
new file mode 100755
index 0000000..83ec917
--- /dev/null
+++ b/openaz-pep/src/test/resources/policies/TestPolicy004.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test004:policy"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd">
+ <Description></Description>
+ <Target/>
+ <Rule
+ RuleId="urn:oasis:names:tc:xacml:1.0:mapper-test:rule1"
+ Effect="Permit">
+ <Description></Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">ROLE_DOCUMENT_WRITER</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">Document</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ AttributeId="jpmc:document:document-owner"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule
+ RuleId="urn:oasis:names:tc:xacml:1.0:mapper-test:rule2"
+ Effect="Permit">
+ <Description></Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">ROLE_DOCUMENT_READER</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Document</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <AttributeDesignator AttributeId="jpmc:client:country-of-domicile"
+ Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <AttributeDesignator AttributeId="jpmc:request-context:country"
+ Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+</Policy>
diff --git a/openaz-pep/src/test/resources/policies/TestPolicy005.xml b/openaz-pep/src/test/resources/policies/TestPolicy005.xml
new file mode 100755
index 0000000..e8d43b5
--- /dev/null
+++ b/openaz-pep/src/test/resources/policies/TestPolicy005.xml
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<PolicySet
+ xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os
+ access_control-xacml-2.0-policy-schema-os.xsd"
+ PolicySetId="urn:oasis:names:tc:xacml:2.0:test005:policyset"
+ PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable">
+ <Description>
+ PolicySet for Test 005.
+ </Description>
+ <Target/>
+ <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy1"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>
+ Policy for Test 005.
+ </Description>
+ <Target/>
+ <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule1"
+ Effect="Permit">
+ <Target>
+ <Subjects>
+ <Subject>
+ <SubjectMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">Physician</AttributeValue>
+ <SubjectAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </SubjectMatch>
+ </Subject>
+ </Subjects>
+ <Resources>
+ <Resource>
+ <ResourceMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue>
+ <ResourceAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ResourceMatch>
+ </Resource>
+ </Resources>
+ <Actions>
+ <Action>
+ <ActionMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
+ <ActionAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ActionMatch>
+ </Action>
+ </Actions>
+ </Target>
+ </Rule>
+ <Obligations>
+ <Obligation
+ ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:simpletest"
+ FulfillOn="Permit">
+ <AttributeAssignment
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>
+ </Obligation>
+ </Obligations>
+ </Policy>
+ <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy2"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>
+ Policy for Test 005.
+ </Description>
+ <Target/>
+ <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule2"
+ Effect="Permit">
+ <Target>
+ <Subjects>
+ <Subject>
+ <SubjectMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">Patient</AttributeValue>
+ <SubjectAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </SubjectMatch>
+ </Subject>
+ </Subjects>
+ <Resources>
+ <Resource>
+ <ResourceMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue>
+ <ResourceAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ResourceMatch>
+ </Resource>
+ </Resources>
+ <Actions>
+ <Action>
+ <ActionMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
+ <ActionAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ActionMatch>
+ </Action>
+ </Actions>
+ </Target>
+ </Rule>
+ <Obligations>
+ <Obligation
+ ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:age-restriction"
+ FulfillOn="Permit">
+ <AttributeAssignment
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:age"
+ DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>
+ </Obligation>
+ <Obligation
+ ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:audit"
+ FulfillOn="Permit"/>
+ </Obligations>
+ </Policy>
+ <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy3"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>
+ Policy for Test 005.
+ </Description>
+ <Target/>
+ <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule3"
+ Effect="Permit">
+ <Target>
+ <Subjects>
+ <Subject>
+ <SubjectMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">InsuranceAgent</AttributeValue>
+ <SubjectAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </SubjectMatch>
+ </Subject>
+ </Subjects>
+ <Resources>
+ <Resource>
+ <ResourceMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue>
+ <ResourceAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ResourceMatch>
+ </Resource>
+ </Resources>
+ <Actions>
+ <Action>
+ <ActionMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
+ <ActionAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ActionMatch>
+ </Action>
+ </Actions>
+ </Target>
+ </Rule>
+ <Obligations>
+ <Obligation
+ ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:access-restriction"
+ FulfillOn="Permit">
+ <AttributeAssignment
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-access-group"
+ DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_RESOURCE_ATTRIBUTE</AttributeAssignment>
+ <AttributeAssignment
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>
+ </Obligation>
+ </Obligations>
+ </Policy>
+</PolicySet>
diff --git a/openaz-pep/src/test/resources/policies/TestPolicy006.xml b/openaz-pep/src/test/resources/policies/TestPolicy006.xml
new file mode 100755
index 0000000..d609e58
--- /dev/null
+++ b/openaz-pep/src/test/resources/policies/TestPolicy006.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<PolicySet
+ xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os
+ access_control-xacml-2.0-policy-schema-os.xsd"
+ PolicySetId="urn:oasis:names:tc:xacml:2.0:test005:policyset"
+ PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable">
+ <Description>
+ PolicySet for Test 005.
+ </Description>
+ <Target/>
+ <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy1"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>
+ Policy for Test 005.
+ </Description>
+ <Target/>
+ <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule1"
+ Effect="Permit">
+ <Target>
+ <Subjects>
+ <Subject>
+ <SubjectMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>
+ <SubjectAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </SubjectMatch>
+ </Subject>
+ </Subjects>
+ <Resources>
+ <Resource>
+ <ResourceMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">resource1</AttributeValue>
+ <ResourceAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ResourceMatch>
+ </Resource>
+ </Resources>
+ <Actions>
+ <Action>
+ <ActionMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>
+ <ActionAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ActionMatch>
+ </Action>
+ </Actions>
+ </Target>
+ </Rule>
+ <Obligations>
+ <Obligation
+ ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:obligation-1"
+ FulfillOn="Permit">
+ <AttributeAssignment
+ AttributeId="jpmc:obligation:obligation-type"
+ DataType="http://www.w3.org/2001/XMLSchema#string">Filtering</AttributeAssignment>
+ <AttributeAssignment
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>
+ </Obligation>
+ <Obligation
+ ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:obligation-2"
+ FulfillOn="Permit">
+ <AttributeAssignment
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:age"
+ DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>
+ </Obligation>
+ </Obligations>
+ </Policy>
+</PolicySet>
diff --git a/openaz-pep/src/test/resources/properties/testapi.xacml.properties b/openaz-pep/src/test/resources/properties/testapi.xacml.properties
new file mode 100755
index 0000000..b45d2c1
--- /dev/null
+++ b/openaz-pep/src/test/resources/properties/testapi.xacml.properties
@@ -0,0 +1,20 @@
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+xacml.rootPolicies=testPolicy
+testPolicy.file=src/test/resources/policies/TestPolicy001.xml
+
+# If there is a standard policy for the engine:
+# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/openaz-pep/src/test/resources/properties/testdatatypes.xacml.properties b/openaz-pep/src/test/resources/properties/testdatatypes.xacml.properties
new file mode 100755
index 0000000..cb6d77b
--- /dev/null
+++ b/openaz-pep/src/test/resources/properties/testdatatypes.xacml.properties
@@ -0,0 +1,20 @@
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+xacml.rootPolicies=testPolicy
+testPolicy.file=src/test/resources/policies/TestPolicy003.xml
+
+# If there is a standard policy for the engine:
+# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/openaz-pep/src/test/resources/properties/testmapper.xacml.properties b/openaz-pep/src/test/resources/properties/testmapper.xacml.properties
new file mode 100755
index 0000000..12e1754
--- /dev/null
+++ b/openaz-pep/src/test/resources/properties/testmapper.xacml.properties
@@ -0,0 +1,24 @@
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+xacml.rootPolicies=testPolicy
+testPolicy.file=src/test/resources/policies/TestPolicy004.xml
+
+#pep properties
+pep.issuer=test
+pep.mapper.classes=org.openliberty.openaz.pepapi.std.test.mapper.BusinessRequestContextMapper,\
+ org.openliberty.openaz.pepapi.std.test.mapper.DocumentMapper, \
+ org.openliberty.openaz.pepapi.std.test.mapper.ClientMapper, \
+ org.openliberty.openaz.pepapi.std.test.mapper.MedicalRecordMapper
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Action.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Action.class
new file mode 100644
index 0000000..2337848
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Action.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ActionResourcePair.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ActionResourcePair.class
new file mode 100644
index 0000000..4ed0074
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ActionResourcePair.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Advice.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Advice.class
new file mode 100644
index 0000000..5663013
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Advice.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Attribute.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Attribute.class
new file mode 100644
index 0000000..3ca8211
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Attribute.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/CategoryContainer.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/CategoryContainer.class
new file mode 100644
index 0000000..55f44fa
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/CategoryContainer.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Environment.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Environment.class
new file mode 100644
index 0000000..2c2d853
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Environment.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/InvalidAnnotationException.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/InvalidAnnotationException.class
new file mode 100644
index 0000000..3c8156c
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/InvalidAnnotationException.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MapperRegistry.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MapperRegistry.class
new file mode 100644
index 0000000..c90e3dc
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MapperRegistry.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.class
new file mode 100644
index 0000000..559631e
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAnyObligation.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAnyObligation.class
new file mode 100644
index 0000000..b177a57
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/MatchAnyObligation.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Matchable.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Matchable.class
new file mode 100644
index 0000000..e68def5
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Matchable.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObjectMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObjectMapper.class
new file mode 100644
index 0000000..f734523
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObjectMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Obligation.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Obligation.class
new file mode 100644
index 0000000..58100f3
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Obligation.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandler.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandler.class
new file mode 100644
index 0000000..380ef97
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.class
new file mode 100644
index 0000000..c00f13b
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationRouter.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationRouter.class
new file mode 100644
index 0000000..7f340b4
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationRouter.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStore.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStore.class
new file mode 100644
index 0000000..2d7c325
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStore.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStoreAware.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStoreAware.class
new file mode 100644
index 0000000..d028684
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/ObligationStoreAware.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgent.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgent.class
new file mode 100644
index 0000000..867d637
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgent.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgentFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgentFactory.class
new file mode 100644
index 0000000..ad8c396
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepAgentFactory.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepConfig.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepConfig.class
new file mode 100644
index 0000000..b99e517
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepConfig.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepException.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepException.class
new file mode 100644
index 0000000..bbf8f9f
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepException.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequest.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequest.class
new file mode 100644
index 0000000..17b60d9
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequest.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestAttributes.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestAttributes.class
new file mode 100644
index 0000000..a883e56
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestAttributes.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestFactory.class
new file mode 100644
index 0000000..528ae1c
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepRequestFactory.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponse.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponse.class
new file mode 100644
index 0000000..5ca7518
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponse.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseBehavior.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseBehavior.class
new file mode 100644
index 0000000..ffae897
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseBehavior.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseFactory.class
new file mode 100644
index 0000000..4e8444f
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseFactory.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseType.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseType.class
new file mode 100644
index 0000000..f29a013
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PepResponseType.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PostDecisionHandler.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PostDecisionHandler.class
new file mode 100644
index 0000000..42a8847
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PostDecisionHandler.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PreDecisionHandler.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PreDecisionHandler.class
new file mode 100644
index 0000000..f063d54
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/PreDecisionHandler.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Resource.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Resource.class
new file mode 100644
index 0000000..ed02ad2
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Resource.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Subject.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Subject.class
new file mode 100644
index 0000000..4bc1534
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/Subject.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/UnhandleableObligationException.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/UnhandleableObligationException.class
new file mode 100644
index 0000000..28d8c6f
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/UnhandleableObligationException.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionMapper.class
new file mode 100644
index 0000000..289d996
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.class
new file mode 100644
index 0000000..137c003
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ArrayMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ArrayMapper.class
new file mode 100644
index 0000000..e1d5084
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ArrayMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.class
new file mode 100644
index 0000000..bdc1594
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CollectionMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CollectionMapper.class
new file mode 100644
index 0000000..886b01e
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/CollectionMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.class
new file mode 100644
index 0000000..0d05e93
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MultiRequest.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MultiRequest.class
new file mode 100644
index 0000000..c78308b
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/MultiRequest.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.class
new file mode 100644
index 0000000..46edec4
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteria.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteria.class
new file mode 100644
index 0000000..b43d1d2
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteria.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.class
new file mode 100644
index 0000000..e36b451
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriterion.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriterion.class
new file mode 100644
index 0000000..4f89184
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationCriterion.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.class
new file mode 100644
index 0000000..3bed007
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/PepUtils.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/PepUtils.class
new file mode 100644
index 0000000..25f293f
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/PepUtils.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ResourceMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ResourceMapper.class
new file mode 100644
index 0000000..08ab7f2
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ResourceMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdAdvice.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdAdvice.class
new file mode 100644
index 0000000..5f14c38
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdAdvice.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdMapperRegistry.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdMapperRegistry.class
new file mode 100644
index 0000000..12702eb
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdMapperRegistry.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligation.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligation.class
new file mode 100644
index 0000000..eae5972
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligation.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.class
new file mode 100644
index 0000000..992a93c
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationRouter.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationRouter.class
new file mode 100644
index 0000000..e4e7054
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdObligationRouter.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgent.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgent.class
new file mode 100644
index 0000000..835bd43
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgent.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.class
new file mode 100644
index 0000000..8a81c8c
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepConfig.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepConfig.class
new file mode 100644
index 0000000..d3ffc48
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepConfig.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequest.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequest.class
new file mode 100644
index 0000000..a7d9bbc
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequest.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.class
new file mode 100644
index 0000000..465fabf
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.class
new file mode 100644
index 0000000..076c058
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse$1.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse$1.class
new file mode 100644
index 0000000..f1db827
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse$1.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse.class
new file mode 100644
index 0000000..e5998e5
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponse.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.class
new file mode 100644
index 0000000..b03a334
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/SubjectMapper.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/SubjectMapper.class
new file mode 100644
index 0000000..f759572
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/SubjectMapper.class
Binary files differ
diff --git a/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.class b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.class
new file mode 100644
index 0000000..7a718e2
--- /dev/null
+++ b/openaz-pep/target/classes/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.class
Binary files differ
diff --git a/openaz-pep/target/maven-archiver/pom.properties b/openaz-pep/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..3c34336
--- /dev/null
+++ b/openaz-pep/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Tue Apr 07 07:45:26 EDT 2015
+version=0.0.1-SNAPSHOT
+groupId=org.openliberty.openaz
+artifactId=openaz-pep
diff --git a/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..7e4a8f3
--- /dev/null
+++ b/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,64 @@
+org/openliberty/openaz/pepapi/ActionResourcePair.class
+org/openliberty/openaz/pepapi/PepConfig.class
+org/openliberty/openaz/pepapi/std/ResourceMapper.class
+org/openliberty/openaz/pepapi/PepResponseType.class
+org/openliberty/openaz/pepapi/std/SubjectMapper.class
+org/openliberty/openaz/pepapi/std/StdObligation.class
+org/openliberty/openaz/pepapi/Subject.class
+org/openliberty/openaz/pepapi/MatchAllObligationAttributes.class
+org/openliberty/openaz/pepapi/std/StdPepConfig.class
+org/openliberty/openaz/pepapi/InvalidAnnotationException.class
+org/openliberty/openaz/pepapi/PepAgent.class
+org/openliberty/openaz/pepapi/PostDecisionHandler.class
+org/openliberty/openaz/pepapi/std/StdObligationRouter.class
+org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.class
+org/openliberty/openaz/pepapi/std/PepUtils.class
+org/openliberty/openaz/pepapi/PreDecisionHandler.class
+org/openliberty/openaz/pepapi/std/StdPepResponseFactory.class
+org/openliberty/openaz/pepapi/PepResponse.class
+org/openliberty/openaz/pepapi/PepAgentFactory.class
+org/openliberty/openaz/pepapi/std/MatchAnyCriterion.class
+org/openliberty/openaz/pepapi/ObligationHandler.class
+org/openliberty/openaz/pepapi/ObligationStore.class
+org/openliberty/openaz/pepapi/std/StdPepAgent.class
+org/openliberty/openaz/pepapi/PepResponseFactory.class
+org/openliberty/openaz/pepapi/UnhandleableObligationException.class
+org/openliberty/openaz/pepapi/PepRequestAttributes.class
+org/openliberty/openaz/pepapi/std/StdPepAgentFactory.class
+org/openliberty/openaz/pepapi/ObligationStoreAware.class
+org/openliberty/openaz/pepapi/PepResponseBehavior.class
+org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.class
+org/openliberty/openaz/pepapi/std/StdPepRequest.class
+org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.class
+org/openliberty/openaz/pepapi/Environment.class
+org/openliberty/openaz/pepapi/ObjectMapper.class
+org/openliberty/openaz/pepapi/std/ObligationCriterion.class
+org/openliberty/openaz/pepapi/Resource.class
+org/openliberty/openaz/pepapi/Obligation.class
+org/openliberty/openaz/pepapi/std/StdPepResponse$1.class
+org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.class
+org/openliberty/openaz/pepapi/MapperRegistry.class
+org/openliberty/openaz/pepapi/std/CollectionMapper.class
+org/openliberty/openaz/pepapi/Matchable.class
+org/openliberty/openaz/pepapi/std/ActionMapper.class
+org/openliberty/openaz/pepapi/Action.class
+org/openliberty/openaz/pepapi/Advice.class
+org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.class
+org/openliberty/openaz/pepapi/Attribute.class
+org/openliberty/openaz/pepapi/std/StdPepResponse.class
+org/openliberty/openaz/pepapi/std/ArrayMapper.class
+org/openliberty/openaz/pepapi/std/StdAdvice.class
+org/openliberty/openaz/pepapi/ObligationRouter.class
+org/openliberty/openaz/pepapi/std/ObligationCriteria.class
+org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.class
+org/openliberty/openaz/pepapi/PepRequest.class
+org/openliberty/openaz/pepapi/std/ObligationIdCriterion.class
+org/openliberty/openaz/pepapi/std/StdMapperRegistry.class
+org/openliberty/openaz/pepapi/std/StdPepRequestFactory.class
+org/openliberty/openaz/pepapi/PepRequestFactory.class
+org/openliberty/openaz/pepapi/PepException.class
+org/openliberty/openaz/pepapi/std/MultiRequest.class
+org/openliberty/openaz/pepapi/std/CategoryContainerMapper.class
+org/openliberty/openaz/pepapi/MatchAnyObligation.class
+org/openliberty/openaz/pepapi/CategoryContainer.class
+org/openliberty/openaz/pepapi/ObligationHandlerRegistry.class
diff --git a/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..dafd73c
--- /dev/null
+++ b/openaz-pep/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,63 @@
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Attribute.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdAdvice.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStoreAware.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationIdCriterion.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepException.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligation.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseBehavior.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationRouter.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgentFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/PepUtils.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionResourcePairMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CategoryContainerMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Advice.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdMapperRegistry.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Environment.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MapperRegistry.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ThreadLocalObligationStore.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PreDecisionHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ResourceMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Obligation.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriterion.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MultiRequest.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/SubjectMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Matchable.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponseType.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteriaBuilder.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationCriteria.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepResponse.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgent.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Action.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepConfig.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ActionMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ObligationAttributeCriterion.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationHandlerRegistry.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepConfig.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponseFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepAgent.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObligationStore.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequest.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/InvalidAnnotationException.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAnyObligation.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepAgentFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/ArrayMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationRouter.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Resource.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestAttributes.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ActionResourcePair.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PostDecisionHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/CollectionMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequestFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/Subject.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/UnhandleableObligationException.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/CategoryContainer.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/MatchAllObligationAttributes.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/PepRequest.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdObligationHandlerRegistry.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepResponse.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/MatchAnyCriterion.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/std/StdPepRequestAttributes.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/main/java/org/openliberty/openaz/pepapi/ObjectMapper.java
diff --git a/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
new file mode 100644
index 0000000..25cd122
--- /dev/null
+++ b/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
@@ -0,0 +1,28 @@
+org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/util/AzInvoker.class
+org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.class
+org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/util/HasResult.class
+org/openliberty/openaz/pepapi/std/test/mapper/Client.class
+org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.class
+org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/mapper/Document.class
+org/openliberty/openaz/pepapi/std/test/TestAPI.class
+org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/TestMapper.class
+org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.class
+org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.class
+org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.class
+org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/TestDataTypes.class
+org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.class
+org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.class
+org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.class
+org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.class
diff --git a/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..571d370
--- /dev/null
+++ b/openaz-pep/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
@@ -0,0 +1,28 @@
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Document.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/Client.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestDataTypes.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestAPI.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/TestMapper.java
+/Users/ajith/IdeaProjects/openaz/openaz-pep/src/test/java/org/openliberty/openaz/pepapi/std/test/util/HasResult.java
diff --git a/openaz-pep/target/openaz-pep-0.0.1-SNAPSHOT.jar b/openaz-pep/target/openaz-pep-0.0.1-SNAPSHOT.jar
new file mode 100644
index 0000000..b7949c2
--- /dev/null
+++ b/openaz-pep/target/openaz-pep-0.0.1-SNAPSHOT.jar
Binary files differ
diff --git a/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPI.xml b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPI.xml
new file mode 100644
index 0000000..67ca2a1
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPI.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<testsuite name="org.openliberty.openaz.pepapi.std.test.TestAPI" time="0.662" tests="4" errors="0" skipped="0" failures="0">
+ <properties>
+ <property name="idea.version" value="14.0.3"/>
+ <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
+ <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib"/>
+ <property name="java.vm.version" value="24.75-b04"/>
+ <property name="gopherProxySet" value="false"/>
+ <property name="java.vm.vendor" value="Oracle Corporation"/>
+ <property name="java.vendor.url" value="http://java.oracle.com/"/>
+ <property name="path.separator" value=":"/>
+ <property name="guice.disable.misplaced.annotation.check" value="true"/>
+ <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/>
+ <property name="file.encoding.pkg" value="sun.io"/>
+ <property name="idea.launcher.port" value="7534"/>
+ <property name="user.country" value="US"/>
+ <property name="sun.java.launcher" value="SUN_STANDARD"/>
+ <property name="sun.os.patch.level" value="unknown"/>
+ <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+ <property name="user.dir" value="/Users/ajith/IdeaProjects/openaz"/>
+ <property name="java.runtime.version" value="1.7.0_75-b13"/>
+ <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/>
+ <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/endorsed"/>
+ <property name="os.arch" value="x86_64"/>
+ <property name="java.io.tmpdir" value="/var/folders/xs/4h_cw5ds0bj_lpk90db3v9dr0000gn/T/"/>
+ <property name="line.separator" value=" "/>
+ <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
+ <property name="os.name" value="Mac OS X"/>
+ <property name="classworlds.conf" value="/Applications/apache-maven-3.1.1/bin/m2.conf"/>
+ <property name="sun.jnu.encoding" value="UTF-8"/>
+ <property name="java.library.path" value="/Users/ajith/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/>
+ <property name="java.specification.name" value="Java Platform API Specification"/>
+ <property name="java.class.version" value="51.0"/>
+ <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
+ <property name="os.version" value="10.10.2"/>
+ <property name="user.home" value="/Users/ajith"/>
+ <property name="user.timezone" value="America/New_York"/>
+ <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/>
+ <property name="java.specification.version" value="1.7"/>
+ <property name="idea.launcher.bin.path" value="/Applications/IntelliJ IDEA 14 CE.app/Contents/bin"/>
+ <property name="file.encoding" value="UTF-8"/>
+ <property name="user.name" value="ajith"/>
+ <property name="java.class.path" value="/Applications/apache-maven-3.1.1/boot/plexus-classworlds-2.5.1.jar:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar"/>
+ <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/>
+ <property name="java.vm.specification.version" value="1.7"/>
+ <property name="sun.arch.data.model" value="64"/>
+ <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre"/>
+ <property name="sun.java.command" value="com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=14.0.3 install -rf :openaz-pep"/>
+ <property name="java.specification.vendor" value="Oracle Corporation"/>
+ <property name="user.language" value="en"/>
+ <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/>
+ <property name="java.vm.info" value="mixed mode"/>
+ <property name="java.version" value="1.7.0_75"/>
+ <property name="java.ext.dirs" value="/Users/ajith/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/>
+ <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/classes"/>
+ <property name="java.vendor" value="Oracle Corporation"/>
+ <property name="maven.home" value="/Applications/apache-maven-3.1.1"/>
+ <property name="file.separator" value="/"/>
+ <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/>
+ <property name="sun.cpu.endian" value="little"/>
+ <property name="sun.io.unicode.encoding" value="UnicodeBig"/>
+ <property name="sun.cpu.isalist" value=""/>
+ </properties>
+ <testcase name="testMultiRequest" classname="org.openliberty.openaz.pepapi.std.test.TestAPI" time="0.629"/>
+ <testcase name="testNotApplicable" classname="org.openliberty.openaz.pepapi.std.test.TestAPI" time="0.017"/>
+ <testcase name="testPepAgent" classname="org.openliberty.openaz.pepapi.std.test.TestAPI" time="0.001"/>
+ <testcase name="testPermit" classname="org.openliberty.openaz.pepapi.std.test.TestAPI" time="0.015"/>
+</testsuite>
\ No newline at end of file
diff --git a/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.xml b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.xml
new file mode 100644
index 0000000..160982b
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<testsuite name="org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP" time="0" tests="4" errors="0" skipped="4" failures="0">
+ <properties>
+ <property name="idea.version" value="14.0.3"/>
+ <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
+ <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib"/>
+ <property name="java.vm.version" value="24.75-b04"/>
+ <property name="gopherProxySet" value="false"/>
+ <property name="java.vm.vendor" value="Oracle Corporation"/>
+ <property name="java.vendor.url" value="http://java.oracle.com/"/>
+ <property name="path.separator" value=":"/>
+ <property name="guice.disable.misplaced.annotation.check" value="true"/>
+ <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/>
+ <property name="file.encoding.pkg" value="sun.io"/>
+ <property name="idea.launcher.port" value="7534"/>
+ <property name="user.country" value="US"/>
+ <property name="sun.java.launcher" value="SUN_STANDARD"/>
+ <property name="sun.os.patch.level" value="unknown"/>
+ <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+ <property name="user.dir" value="/Users/ajith/IdeaProjects/openaz"/>
+ <property name="java.runtime.version" value="1.7.0_75-b13"/>
+ <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/>
+ <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/endorsed"/>
+ <property name="os.arch" value="x86_64"/>
+ <property name="java.io.tmpdir" value="/var/folders/xs/4h_cw5ds0bj_lpk90db3v9dr0000gn/T/"/>
+ <property name="line.separator" value=" "/>
+ <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
+ <property name="os.name" value="Mac OS X"/>
+ <property name="classworlds.conf" value="/Applications/apache-maven-3.1.1/bin/m2.conf"/>
+ <property name="sun.jnu.encoding" value="UTF-8"/>
+ <property name="java.library.path" value="/Users/ajith/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/>
+ <property name="java.specification.name" value="Java Platform API Specification"/>
+ <property name="java.class.version" value="51.0"/>
+ <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
+ <property name="os.version" value="10.10.2"/>
+ <property name="user.home" value="/Users/ajith"/>
+ <property name="user.timezone" value="America/New_York"/>
+ <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/>
+ <property name="java.specification.version" value="1.7"/>
+ <property name="idea.launcher.bin.path" value="/Applications/IntelliJ IDEA 14 CE.app/Contents/bin"/>
+ <property name="file.encoding" value="UTF-8"/>
+ <property name="user.name" value="ajith"/>
+ <property name="java.class.path" value="/Applications/apache-maven-3.1.1/boot/plexus-classworlds-2.5.1.jar:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar"/>
+ <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/>
+ <property name="java.vm.specification.version" value="1.7"/>
+ <property name="sun.arch.data.model" value="64"/>
+ <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre"/>
+ <property name="sun.java.command" value="com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=14.0.3 install -rf :openaz-pep"/>
+ <property name="java.specification.vendor" value="Oracle Corporation"/>
+ <property name="user.language" value="en"/>
+ <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/>
+ <property name="java.vm.info" value="mixed mode"/>
+ <property name="java.version" value="1.7.0_75"/>
+ <property name="java.ext.dirs" value="/Users/ajith/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/>
+ <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/classes"/>
+ <property name="java.vendor" value="Oracle Corporation"/>
+ <property name="maven.home" value="/Applications/apache-maven-3.1.1"/>
+ <property name="file.separator" value="/"/>
+ <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/>
+ <property name="sun.cpu.endian" value="little"/>
+ <property name="sun.io.unicode.encoding" value="UnicodeBig"/>
+ <property name="sun.cpu.isalist" value=""/>
+ </properties>
+ <testcase name="testMultiRequest" classname="org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP" time="0">
+ <skipped/>
+ </testcase>
+ <testcase name="testNotApplicable" classname="org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP" time="0">
+ <skipped/>
+ </testcase>
+ <testcase name="testPepAgent" classname="org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP" time="0">
+ <skipped/>
+ </testcase>
+ <testcase name="testPermit" classname="org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP" time="0">
+ <skipped/>
+ </testcase>
+</testsuite>
\ No newline at end of file
diff --git a/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.xml b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.xml
new file mode 100644
index 0000000..fea22f8
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<testsuite name="org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration" time="0" tests="2" errors="0" skipped="2" failures="0">
+ <properties>
+ <property name="idea.version" value="14.0.3"/>
+ <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
+ <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib"/>
+ <property name="java.vm.version" value="24.75-b04"/>
+ <property name="gopherProxySet" value="false"/>
+ <property name="java.vm.vendor" value="Oracle Corporation"/>
+ <property name="java.vendor.url" value="http://java.oracle.com/"/>
+ <property name="path.separator" value=":"/>
+ <property name="guice.disable.misplaced.annotation.check" value="true"/>
+ <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/>
+ <property name="file.encoding.pkg" value="sun.io"/>
+ <property name="idea.launcher.port" value="7534"/>
+ <property name="user.country" value="US"/>
+ <property name="sun.java.launcher" value="SUN_STANDARD"/>
+ <property name="sun.os.patch.level" value="unknown"/>
+ <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+ <property name="user.dir" value="/Users/ajith/IdeaProjects/openaz"/>
+ <property name="java.runtime.version" value="1.7.0_75-b13"/>
+ <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/>
+ <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/endorsed"/>
+ <property name="os.arch" value="x86_64"/>
+ <property name="java.io.tmpdir" value="/var/folders/xs/4h_cw5ds0bj_lpk90db3v9dr0000gn/T/"/>
+ <property name="line.separator" value=" "/>
+ <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
+ <property name="os.name" value="Mac OS X"/>
+ <property name="classworlds.conf" value="/Applications/apache-maven-3.1.1/bin/m2.conf"/>
+ <property name="sun.jnu.encoding" value="UTF-8"/>
+ <property name="java.library.path" value="/Users/ajith/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/>
+ <property name="java.specification.name" value="Java Platform API Specification"/>
+ <property name="java.class.version" value="51.0"/>
+ <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
+ <property name="os.version" value="10.10.2"/>
+ <property name="user.home" value="/Users/ajith"/>
+ <property name="user.timezone" value="America/New_York"/>
+ <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/>
+ <property name="java.specification.version" value="1.7"/>
+ <property name="idea.launcher.bin.path" value="/Applications/IntelliJ IDEA 14 CE.app/Contents/bin"/>
+ <property name="file.encoding" value="UTF-8"/>
+ <property name="user.name" value="ajith"/>
+ <property name="java.class.path" value="/Applications/apache-maven-3.1.1/boot/plexus-classworlds-2.5.1.jar:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar"/>
+ <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/>
+ <property name="java.vm.specification.version" value="1.7"/>
+ <property name="sun.arch.data.model" value="64"/>
+ <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre"/>
+ <property name="sun.java.command" value="com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=14.0.3 install -rf :openaz-pep"/>
+ <property name="java.specification.vendor" value="Oracle Corporation"/>
+ <property name="user.language" value="en"/>
+ <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/>
+ <property name="java.vm.info" value="mixed mode"/>
+ <property name="java.version" value="1.7.0_75"/>
+ <property name="java.ext.dirs" value="/Users/ajith/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/>
+ <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/classes"/>
+ <property name="java.vendor" value="Oracle Corporation"/>
+ <property name="maven.home" value="/Applications/apache-maven-3.1.1"/>
+ <property name="file.separator" value="/"/>
+ <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/>
+ <property name="sun.cpu.endian" value="little"/>
+ <property name="sun.io.unicode.encoding" value="UnicodeBig"/>
+ <property name="sun.cpu.isalist" value=""/>
+ </properties>
+ <testcase name="testRegistration" classname="org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration" time="0">
+ <skipped/>
+ </testcase>
+ <testcase name="testPepAgent" classname="org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration" time="0">
+ <skipped/>
+ </testcase>
+</testsuite>
\ No newline at end of file
diff --git a/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestDataTypes.xml b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestDataTypes.xml
new file mode 100644
index 0000000..5c7ae2e
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestDataTypes.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<testsuite name="org.openliberty.openaz.pepapi.std.test.TestDataTypes" time="0.556" tests="4" errors="0" skipped="0" failures="0">
+ <properties>
+ <property name="idea.version" value="14.0.3"/>
+ <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
+ <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib"/>
+ <property name="java.vm.version" value="24.75-b04"/>
+ <property name="gopherProxySet" value="false"/>
+ <property name="java.vm.vendor" value="Oracle Corporation"/>
+ <property name="java.vendor.url" value="http://java.oracle.com/"/>
+ <property name="path.separator" value=":"/>
+ <property name="guice.disable.misplaced.annotation.check" value="true"/>
+ <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/>
+ <property name="file.encoding.pkg" value="sun.io"/>
+ <property name="idea.launcher.port" value="7534"/>
+ <property name="user.country" value="US"/>
+ <property name="sun.java.launcher" value="SUN_STANDARD"/>
+ <property name="sun.os.patch.level" value="unknown"/>
+ <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+ <property name="user.dir" value="/Users/ajith/IdeaProjects/openaz"/>
+ <property name="java.runtime.version" value="1.7.0_75-b13"/>
+ <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/>
+ <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/endorsed"/>
+ <property name="os.arch" value="x86_64"/>
+ <property name="java.io.tmpdir" value="/var/folders/xs/4h_cw5ds0bj_lpk90db3v9dr0000gn/T/"/>
+ <property name="line.separator" value=" "/>
+ <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
+ <property name="os.name" value="Mac OS X"/>
+ <property name="classworlds.conf" value="/Applications/apache-maven-3.1.1/bin/m2.conf"/>
+ <property name="sun.jnu.encoding" value="UTF-8"/>
+ <property name="java.library.path" value="/Users/ajith/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/>
+ <property name="java.specification.name" value="Java Platform API Specification"/>
+ <property name="java.class.version" value="51.0"/>
+ <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
+ <property name="os.version" value="10.10.2"/>
+ <property name="user.home" value="/Users/ajith"/>
+ <property name="user.timezone" value="America/New_York"/>
+ <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/>
+ <property name="java.specification.version" value="1.7"/>
+ <property name="idea.launcher.bin.path" value="/Applications/IntelliJ IDEA 14 CE.app/Contents/bin"/>
+ <property name="file.encoding" value="UTF-8"/>
+ <property name="user.name" value="ajith"/>
+ <property name="java.class.path" value="/Applications/apache-maven-3.1.1/boot/plexus-classworlds-2.5.1.jar:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar"/>
+ <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/>
+ <property name="java.vm.specification.version" value="1.7"/>
+ <property name="sun.arch.data.model" value="64"/>
+ <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre"/>
+ <property name="sun.java.command" value="com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=14.0.3 install -rf :openaz-pep"/>
+ <property name="java.specification.vendor" value="Oracle Corporation"/>
+ <property name="user.language" value="en"/>
+ <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/>
+ <property name="java.vm.info" value="mixed mode"/>
+ <property name="java.version" value="1.7.0_75"/>
+ <property name="java.ext.dirs" value="/Users/ajith/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/>
+ <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/classes"/>
+ <property name="java.vendor" value="Oracle Corporation"/>
+ <property name="maven.home" value="/Applications/apache-maven-3.1.1"/>
+ <property name="file.separator" value="/"/>
+ <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/>
+ <property name="sun.cpu.endian" value="little"/>
+ <property name="sun.io.unicode.encoding" value="UnicodeBig"/>
+ <property name="sun.cpu.isalist" value=""/>
+ </properties>
+ <testcase name="testMultiRequestWithURI" classname="org.openliberty.openaz.pepapi.std.test.TestDataTypes" time="0.511"/>
+ <testcase name="testPermitWithURIResource" classname="org.openliberty.openaz.pepapi.std.test.TestDataTypes" time="0.022"/>
+ <testcase name="testPermitWithIntegerResource" classname="org.openliberty.openaz.pepapi.std.test.TestDataTypes" time="0.022"/>
+ <testcase name="testPepAgent" classname="org.openliberty.openaz.pepapi.std.test.TestDataTypes" time="0.001"/>
+</testsuite>
\ No newline at end of file
diff --git a/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestMapper.xml b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestMapper.xml
new file mode 100644
index 0000000..4c652e2
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/TEST-org.openliberty.openaz.pepapi.std.test.TestMapper.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<testsuite name="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.515" tests="6" errors="0" skipped="0" failures="0">
+ <properties>
+ <property name="idea.version" value="14.0.3"/>
+ <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
+ <property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib"/>
+ <property name="java.vm.version" value="24.75-b04"/>
+ <property name="gopherProxySet" value="false"/>
+ <property name="java.vm.vendor" value="Oracle Corporation"/>
+ <property name="java.vendor.url" value="http://java.oracle.com/"/>
+ <property name="path.separator" value=":"/>
+ <property name="guice.disable.misplaced.annotation.check" value="true"/>
+ <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/>
+ <property name="file.encoding.pkg" value="sun.io"/>
+ <property name="idea.launcher.port" value="7534"/>
+ <property name="user.country" value="US"/>
+ <property name="sun.java.launcher" value="SUN_STANDARD"/>
+ <property name="sun.os.patch.level" value="unknown"/>
+ <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+ <property name="user.dir" value="/Users/ajith/IdeaProjects/openaz"/>
+ <property name="java.runtime.version" value="1.7.0_75-b13"/>
+ <property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/>
+ <property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/endorsed"/>
+ <property name="os.arch" value="x86_64"/>
+ <property name="java.io.tmpdir" value="/var/folders/xs/4h_cw5ds0bj_lpk90db3v9dr0000gn/T/"/>
+ <property name="line.separator" value=" "/>
+ <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
+ <property name="os.name" value="Mac OS X"/>
+ <property name="classworlds.conf" value="/Applications/apache-maven-3.1.1/bin/m2.conf"/>
+ <property name="sun.jnu.encoding" value="UTF-8"/>
+ <property name="java.library.path" value="/Users/ajith/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/>
+ <property name="java.specification.name" value="Java Platform API Specification"/>
+ <property name="java.class.version" value="51.0"/>
+ <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
+ <property name="os.version" value="10.10.2"/>
+ <property name="user.home" value="/Users/ajith"/>
+ <property name="user.timezone" value="America/New_York"/>
+ <property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/>
+ <property name="java.specification.version" value="1.7"/>
+ <property name="idea.launcher.bin.path" value="/Applications/IntelliJ IDEA 14 CE.app/Contents/bin"/>
+ <property name="file.encoding" value="UTF-8"/>
+ <property name="user.name" value="ajith"/>
+ <property name="java.class.path" value="/Applications/apache-maven-3.1.1/boot/plexus-classworlds-2.5.1.jar:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar"/>
+ <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/>
+ <property name="java.vm.specification.version" value="1.7"/>
+ <property name="sun.arch.data.model" value="64"/>
+ <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre"/>
+ <property name="sun.java.command" value="com.intellij.rt.execution.application.AppMain org.codehaus.classworlds.Launcher -Didea.version=14.0.3 install -rf :openaz-pep"/>
+ <property name="java.specification.vendor" value="Oracle Corporation"/>
+ <property name="user.language" value="en"/>
+ <property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/>
+ <property name="java.vm.info" value="mixed mode"/>
+ <property name="java.version" value="1.7.0_75"/>
+ <property name="java.ext.dirs" value="/Users/ajith/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/>
+ <property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/classes"/>
+ <property name="java.vendor" value="Oracle Corporation"/>
+ <property name="maven.home" value="/Applications/apache-maven-3.1.1"/>
+ <property name="file.separator" value="/"/>
+ <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/>
+ <property name="sun.cpu.endian" value="little"/>
+ <property name="sun.io.unicode.encoding" value="UnicodeBig"/>
+ <property name="sun.cpu.isalist" value=""/>
+ </properties>
+ <testcase name="testMix" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.441"/>
+ <testcase name="testVarArgsDeny" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.02"/>
+ <testcase name="testVarArgsPermit" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.018"/>
+ <testcase name="testNotApplicable" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.016"/>
+ <testcase name="testPepAgent" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.001"/>
+ <testcase name="testPermit" classname="org.openliberty.openaz.pepapi.std.test.TestMapper" time="0.019"/>
+</testsuite>
\ No newline at end of file
diff --git a/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPI.txt b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPI.txt
new file mode 100644
index 0000000..3ad938b
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPI.txt
@@ -0,0 +1,4 @@
+-------------------------------------------------------------------------------
+Test set: org.openliberty.openaz.pepapi.std.test.TestAPI
+-------------------------------------------------------------------------------
+Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.736 sec - in org.openliberty.openaz.pepapi.std.test.TestAPI
diff --git a/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.txt b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.txt
new file mode 100644
index 0000000..b725ae3
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP.txt
@@ -0,0 +1,4 @@
+-------------------------------------------------------------------------------
+Test set: org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP
+-------------------------------------------------------------------------------
+Tests run: 4, Failures: 0, Errors: 0, Skipped: 4, Time elapsed: 0.058 sec - in org.openliberty.openaz.pepapi.std.test.TestAPIWithPIP
diff --git a/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.txt b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.txt
new file mode 100644
index 0000000..23471ca
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration.txt
@@ -0,0 +1,4 @@
+-------------------------------------------------------------------------------
+Test set: org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration
+-------------------------------------------------------------------------------
+Tests run: 2, Failures: 0, Errors: 0, Skipped: 2, Time elapsed: 0.066 sec - in org.openliberty.openaz.pepapi.std.test.TestAnnotatedHandlerRegistration
diff --git a/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestDataTypes.txt b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestDataTypes.txt
new file mode 100644
index 0000000..d07c3f4
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestDataTypes.txt
@@ -0,0 +1,4 @@
+-------------------------------------------------------------------------------
+Test set: org.openliberty.openaz.pepapi.std.test.TestDataTypes
+-------------------------------------------------------------------------------
+Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.631 sec - in org.openliberty.openaz.pepapi.std.test.TestDataTypes
diff --git a/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestMapper.txt b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestMapper.txt
new file mode 100644
index 0000000..3457155
--- /dev/null
+++ b/openaz-pep/target/surefire-reports/org.openliberty.openaz.pepapi.std.test.TestMapper.txt
@@ -0,0 +1,4 @@
+-------------------------------------------------------------------------------
+Test set: org.openliberty.openaz.pepapi.std.test.TestMapper
+-------------------------------------------------------------------------------
+Tests run: 6, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.675 sec - in org.openliberty.openaz.pepapi.std.test.TestMapper
diff --git a/openaz-pep/target/test-classes/log4j.xml b/openaz-pep/target/test-classes/log4j.xml
new file mode 100644
index 0000000..ff481f9
--- /dev/null
+++ b/openaz-pep/target/test-classes/log4j.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
+
+ <appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} [%t] %5p %c{1} - %m%n"/>
+ </layout>
+ </appender>
+
+ <appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">
+ <param name="append" value="false"/>
+ <param name="file" value="target/openaz-junit-tests.log"/>
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} [%t] %5p %c{1} - %m%n"/>
+ </layout>
+ </appender>
+
+ <logger name="org.openliberty.openaz">
+ <level value="debug"/>
+ </logger>
+
+ <logger name="org.springframework">
+ <level value="error"/>
+ </logger>
+
+ <root>
+ <level value="debug"/>
+ <appender-ref ref="consoleAppender"/>
+ <!-- <appender-ref ref="fileAppender"/> -->
+ </root>
+
+</log4j:configuration>
\ No newline at end of file
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPI.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPI.class
new file mode 100644
index 0000000..3aff1fb
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPI.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.class
new file mode 100644
index 0000000..4884fbf
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAPIWithPIP.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.class
new file mode 100644
index 0000000..c8aac30
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestAnnotatedHandlerRegistration.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestDataTypes.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestDataTypes.class
new file mode 100644
index 0000000..a1b1126
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestDataTypes.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestMapper.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestMapper.class
new file mode 100644
index 0000000..918799c
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/TestMapper.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.class
new file mode 100644
index 0000000..0d80c1f
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContext.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.class
new file mode 100644
index 0000000..7681006
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/BusinessRequestContextMapper.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Client.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Client.class
new file mode 100644
index 0000000..2dc35b6
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Client.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.class
new file mode 100644
index 0000000..a65c689
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/ClientMapper.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Document.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Document.class
new file mode 100644
index 0000000..9bb4d24
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/Document.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.class
new file mode 100644
index 0000000..4a12f1c
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/DocumentMapper.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.class
new file mode 100644
index 0000000..62cf6e2
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecord.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.class
new file mode 100644
index 0000000..b0d1fec
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/mapper/MedicalRecordMapper.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.class
new file mode 100644
index 0000000..e3f3659
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AccessRestrictionObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.class
new file mode 100644
index 0000000..9ea4d49
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AgeRestrictionObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.class
new file mode 100644
index 0000000..a239d16
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAccessRestrictionObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.class
new file mode 100644
index 0000000..f5e751d
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAgeRestrictionObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.class
new file mode 100644
index 0000000..26ac39e
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedAuditObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.class
new file mode 100644
index 0000000..b07bf19
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedCatchAllObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.class
new file mode 100644
index 0000000..e5ac144
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedFilteringObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.class
new file mode 100644
index 0000000..04017a5
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.class
new file mode 100644
index 0000000..b2dbde5
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AnnotatedRedactionObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.class
new file mode 100644
index 0000000..9d3ccbf
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/AuditObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.class
new file mode 100644
index 0000000..070c920
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/CatchAllObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.class
new file mode 100644
index 0000000..867f3df
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/FilteringObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.class
new file mode 100644
index 0000000..387f894
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/obligation/RedactionObligationHandler.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.class
new file mode 100644
index 0000000..4fb49b6
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/AzInvoker.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/HasResult.class b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/HasResult.class
new file mode 100644
index 0000000..a82a6fd
--- /dev/null
+++ b/openaz-pep/target/test-classes/org/openliberty/openaz/pepapi/std/test/util/HasResult.class
Binary files differ
diff --git a/openaz-pep/target/test-classes/policies/TestPolicy001.xml b/openaz-pep/target/test-classes/policies/TestPolicy001.xml
new file mode 100644
index 0000000..4f2a711
--- /dev/null
+++ b/openaz-pep/target/test-classes/policies/TestPolicy001.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test001:policy"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd">
+ <Description></Description>
+ <Target/>
+ <Rule RuleId="urn:oasis:names:tc:xacml:1.0:test001:rule-1" Effect="Permit">
+ <Description>
+ Julius Hibbert can read or write Bart Simpson's medical record.
+ </Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">Julius Hibbert</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ </Rule>
+</Policy>
diff --git a/openaz-pep/target/test-classes/policies/TestPolicy002.xml b/openaz-pep/target/test-classes/policies/TestPolicy002.xml
new file mode 100644
index 0000000..d0308c9
--- /dev/null
+++ b/openaz-pep/target/test-classes/policies/TestPolicy002.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Policy
+ xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ PolicyId="urn:oasis:names:tc:xacml:1.0:conformance-test:IIA2:policy"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides">
+ <Description>
+ Policy for Conformance Test IIA001.
+ </Description>
+ <Target/>
+ <Rule
+ RuleId="urn:oasis:names:tc:xacml:1.0:test-2:rule-1"
+ Effect="Permit">
+ <Description>
+ Physicians can read or write Bart Simpson's medical record.
+ </Description>
+ <Target>
+ <Subjects>
+ <Subject>
+ <SubjectMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">Physician</AttributeValue>
+ <SubjectAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </SubjectMatch>
+ </Subject>
+ </Subjects>
+ <Resources>
+ <Resource>
+ <ResourceMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue>
+ <ResourceAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ResourceMatch>
+ </Resource>
+ </Resources>
+ <Actions>
+ <Action>
+ <ActionMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
+ <ActionAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ActionMatch>
+ </Action>
+ <Action>
+ <ActionMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue>
+ <ActionAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ActionMatch>
+ </Action>
+ </Actions>
+ </Target>
+ </Rule>
+ <Rule
+ RuleId="urn:oasis:names:tc:xacml:1.0:test-2:rule-2"
+ Effect="Permit">
+ <Description>
+ Patient is allowed to read his/her medical record.
+ </Description>
+ <Target>
+ <Subjects>
+ <Subject>
+ <SubjectMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">Patient</AttributeValue>
+ <SubjectAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </SubjectMatch>
+ </Subject>
+ </Subjects>
+ <Resources>
+ <Resource>
+ <ResourceMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">http://medico.com/record/patient/BartSimpson</AttributeValue>
+ <ResourceAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ResourceMatch>
+ </Resource>
+ </Resources>
+ <Actions>
+ <Action>
+ <ActionMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
+ <ActionAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ActionMatch>
+ </Action>
+ </Actions>
+ </Target>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-owner"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <SubjectAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"
+ SubjectCategory="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" />
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+</Policy>
diff --git a/openaz-pep/target/test-classes/policies/TestPolicy003.xml b/openaz-pep/target/test-classes/policies/TestPolicy003.xml
new file mode 100644
index 0000000..f730e34
--- /dev/null
+++ b/openaz-pep/target/test-classes/policies/TestPolicy003.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test003:policy"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd">
+ <Description></Description>
+ <Target/>
+ <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test003:rule1" Effect="Permit">
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#anyURI">file://repository/classified/abc</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
+ DataType="http://www.w3.org/2001/XMLSchema#anyURI" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ </Rule>
+ <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test003:rule2" Effect="Permit">
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#anyURI">file://repository/classified/xyz</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
+ DataType="http://www.w3.org/2001/XMLSchema#anyURI" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ </Rule>
+ <Rule RuleId="urn:oasis:names:tc:xacml:1.0:conformance-test:IIA3:rule3" Effect="Permit">
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:integer-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#integer">101</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
+ DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ </Rule>
+</Policy>
diff --git a/openaz-pep/target/test-classes/policies/TestPolicy004.xml b/openaz-pep/target/test-classes/policies/TestPolicy004.xml
new file mode 100644
index 0000000..83ec917
--- /dev/null
+++ b/openaz-pep/target/test-classes/policies/TestPolicy004.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:test004:policy"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:policy:schema:os access_control-xacml-2.0-policy-schema-os.xsd">
+ <Description></Description>
+ <Target/>
+ <Rule
+ RuleId="urn:oasis:names:tc:xacml:1.0:mapper-test:rule1"
+ Effect="Permit">
+ <Description></Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">ROLE_DOCUMENT_WRITER</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">Document</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ AttributeId="jpmc:document:document-owner"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule
+ RuleId="urn:oasis:names:tc:xacml:1.0:mapper-test:rule2"
+ Effect="Permit">
+ <Description></Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">ROLE_DOCUMENT_READER</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Document</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <AttributeDesignator AttributeId="jpmc:client:country-of-domicile"
+ Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <AttributeDesignator AttributeId="jpmc:request-context:country"
+ Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment"
+ DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" />
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+</Policy>
diff --git a/openaz-pep/target/test-classes/policies/TestPolicy005.xml b/openaz-pep/target/test-classes/policies/TestPolicy005.xml
new file mode 100644
index 0000000..e8d43b5
--- /dev/null
+++ b/openaz-pep/target/test-classes/policies/TestPolicy005.xml
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<PolicySet
+ xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os
+ access_control-xacml-2.0-policy-schema-os.xsd"
+ PolicySetId="urn:oasis:names:tc:xacml:2.0:test005:policyset"
+ PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable">
+ <Description>
+ PolicySet for Test 005.
+ </Description>
+ <Target/>
+ <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy1"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>
+ Policy for Test 005.
+ </Description>
+ <Target/>
+ <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule1"
+ Effect="Permit">
+ <Target>
+ <Subjects>
+ <Subject>
+ <SubjectMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">Physician</AttributeValue>
+ <SubjectAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </SubjectMatch>
+ </Subject>
+ </Subjects>
+ <Resources>
+ <Resource>
+ <ResourceMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue>
+ <ResourceAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ResourceMatch>
+ </Resource>
+ </Resources>
+ <Actions>
+ <Action>
+ <ActionMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
+ <ActionAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ActionMatch>
+ </Action>
+ </Actions>
+ </Target>
+ </Rule>
+ <Obligations>
+ <Obligation
+ ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:simpletest"
+ FulfillOn="Permit">
+ <AttributeAssignment
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>
+ </Obligation>
+ </Obligations>
+ </Policy>
+ <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy2"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>
+ Policy for Test 005.
+ </Description>
+ <Target/>
+ <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule2"
+ Effect="Permit">
+ <Target>
+ <Subjects>
+ <Subject>
+ <SubjectMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">Patient</AttributeValue>
+ <SubjectAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </SubjectMatch>
+ </Subject>
+ </Subjects>
+ <Resources>
+ <Resource>
+ <ResourceMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue>
+ <ResourceAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ResourceMatch>
+ </Resource>
+ </Resources>
+ <Actions>
+ <Action>
+ <ActionMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
+ <ActionAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ActionMatch>
+ </Action>
+ </Actions>
+ </Target>
+ </Rule>
+ <Obligations>
+ <Obligation
+ ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:age-restriction"
+ FulfillOn="Permit">
+ <AttributeAssignment
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:age"
+ DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>
+ </Obligation>
+ <Obligation
+ ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:audit"
+ FulfillOn="Permit"/>
+ </Obligations>
+ </Policy>
+ <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy3"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>
+ Policy for Test 005.
+ </Description>
+ <Target/>
+ <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule3"
+ Effect="Permit">
+ <Target>
+ <Subjects>
+ <Subject>
+ <SubjectMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">InsuranceAgent</AttributeValue>
+ <SubjectAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </SubjectMatch>
+ </Subject>
+ </Subjects>
+ <Resources>
+ <Resource>
+ <ResourceMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">PatientMedicalRecord</AttributeValue>
+ <ResourceAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-type"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ResourceMatch>
+ </Resource>
+ </Resources>
+ <Actions>
+ <Action>
+ <ActionMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
+ <ActionAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ActionMatch>
+ </Action>
+ </Actions>
+ </Target>
+ </Rule>
+ <Obligations>
+ <Obligation
+ ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:access-restriction"
+ FulfillOn="Permit">
+ <AttributeAssignment
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-access-group"
+ DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_RESOURCE_ATTRIBUTE</AttributeAssignment>
+ <AttributeAssignment
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>
+ </Obligation>
+ </Obligations>
+ </Policy>
+</PolicySet>
diff --git a/openaz-pep/target/test-classes/policies/TestPolicy006.xml b/openaz-pep/target/test-classes/policies/TestPolicy006.xml
new file mode 100644
index 0000000..d609e58
--- /dev/null
+++ b/openaz-pep/target/test-classes/policies/TestPolicy006.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<PolicySet
+ xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os
+ access_control-xacml-2.0-policy-schema-os.xsd"
+ PolicySetId="urn:oasis:names:tc:xacml:2.0:test005:policyset"
+ PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable">
+ <Description>
+ PolicySet for Test 005.
+ </Description>
+ <Target/>
+ <Policy PolicyId="urn:oasis:names:tc:xacml:2.0:test005:policy1"
+ RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>
+ Policy for Test 005.
+ </Description>
+ <Target/>
+ <Rule RuleId="urn:oasis:names:tc:xacml:2.0:test005:rule1"
+ Effect="Permit">
+ <Target>
+ <Subjects>
+ <Subject>
+ <SubjectMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">John Smith</AttributeValue>
+ <SubjectAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </SubjectMatch>
+ </Subject>
+ </Subjects>
+ <Resources>
+ <Resource>
+ <ResourceMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">resource1</AttributeValue>
+ <ResourceAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ResourceMatch>
+ </Resource>
+ </Resources>
+ <Actions>
+ <Action>
+ <ActionMatch
+ MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue
+ DataType="http://www.w3.org/2001/XMLSchema#string">view</AttributeValue>
+ <ActionAttributeDesignator
+ AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string"/>
+ </ActionMatch>
+ </Action>
+ </Actions>
+ </Target>
+ </Rule>
+ <Obligations>
+ <Obligation
+ ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:obligation-1"
+ FulfillOn="Permit">
+ <AttributeAssignment
+ AttributeId="jpmc:obligation:obligation-type"
+ DataType="http://www.w3.org/2001/XMLSchema#string">Filtering</AttributeAssignment>
+ <AttributeAssignment
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
+ DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>
+ </Obligation>
+ <Obligation
+ ObligationId="urn:oasis:names:tc:xacml:2.0:obligation:obligation-2"
+ FulfillOn="Permit">
+ <AttributeAssignment
+ AttributeId="urn:oasis:names:tc:xacml:1.0:subject:age"
+ DataType="http://www.w3.org/2001/XMLSchema#string">EVAL_SUBJECT_ATTRIBUTE</AttributeAssignment>
+ </Obligation>
+ </Obligations>
+ </Policy>
+</PolicySet>
diff --git a/openaz-pep/target/test-classes/properties/testapi.xacml.properties b/openaz-pep/target/test-classes/properties/testapi.xacml.properties
new file mode 100644
index 0000000..b45d2c1
--- /dev/null
+++ b/openaz-pep/target/test-classes/properties/testapi.xacml.properties
@@ -0,0 +1,20 @@
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+xacml.rootPolicies=testPolicy
+testPolicy.file=src/test/resources/policies/TestPolicy001.xml
+
+# If there is a standard policy for the engine:
+# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/openaz-pep/target/test-classes/properties/testdatatypes.xacml.properties b/openaz-pep/target/test-classes/properties/testdatatypes.xacml.properties
new file mode 100644
index 0000000..cb6d77b
--- /dev/null
+++ b/openaz-pep/target/test-classes/properties/testdatatypes.xacml.properties
@@ -0,0 +1,20 @@
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+xacml.rootPolicies=testPolicy
+testPolicy.file=src/test/resources/policies/TestPolicy003.xml
+
+# If there is a standard policy for the engine:
+# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/openaz-pep/target/test-classes/properties/testmapper.xacml.properties b/openaz-pep/target/test-classes/properties/testmapper.xacml.properties
new file mode 100644
index 0000000..12e1754
--- /dev/null
+++ b/openaz-pep/target/test-classes/properties/testmapper.xacml.properties
@@ -0,0 +1,24 @@
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+xacml.rootPolicies=testPolicy
+testPolicy.file=src/test/resources/policies/TestPolicy004.xml
+
+#pep properties
+pep.issuer=test
+pep.mapper.classes=org.openliberty.openaz.pepapi.std.test.mapper.BusinessRequestContextMapper,\
+ org.openliberty.openaz.pepapi.std.test.mapper.DocumentMapper, \
+ org.openliberty.openaz.pepapi.std.test.mapper.ClientMapper, \
+ org.openliberty.openaz.pepapi.std.test.mapper.MedicalRecordMapper
diff --git a/openaz-xacml-pap-admin/pom.xml b/openaz-xacml-pap-admin/pom.xml
new file mode 100755
index 0000000..78f7817
--- /dev/null
+++ b/openaz-xacml-pap-admin/pom.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>openaz</artifactId>
+ <groupId>org.openliberty.openaz</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>openaz-xacml-pap-admin</artifactId>
+
+
+</project>
\ No newline at end of file
diff --git a/openaz-xacml-pap-admin/target/maven-archiver/pom.properties b/openaz-xacml-pap-admin/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..d531585
--- /dev/null
+++ b/openaz-xacml-pap-admin/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Tue Apr 07 07:42:37 EDT 2015
+version=0.0.1-SNAPSHOT
+groupId=org.openliberty.openaz
+artifactId=openaz-xacml-pap-admin
diff --git a/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
diff --git a/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/openaz-xacml-pap-admin/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
diff --git a/openaz-xacml-pap-admin/target/openaz-xacml-pap-admin-0.0.1-SNAPSHOT.jar b/openaz-xacml-pap-admin/target/openaz-xacml-pap-admin-0.0.1-SNAPSHOT.jar
new file mode 100644
index 0000000..00bbf9f
--- /dev/null
+++ b/openaz-xacml-pap-admin/target/openaz-xacml-pap-admin-0.0.1-SNAPSHOT.jar
Binary files differ
diff --git a/openaz-xacml-pap-rest/WebContent/META-INF/MANIFEST.MF b/openaz-xacml-pap-rest/WebContent/META-INF/MANIFEST.MF
new file mode 100755
index 0000000..58630c0
--- /dev/null
+++ b/openaz-xacml-pap-rest/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/openaz-xacml-pap-rest/WebContent/README.txt b/openaz-xacml-pap-rest/WebContent/README.txt
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/openaz-xacml-pap-rest/WebContent/README.txt
diff --git a/openaz-xacml-pap-rest/pdps/annotation/AnnotationPolicy.v1.xml b/openaz-xacml-pap-rest/pdps/annotation/AnnotationPolicy.v1.xml
new file mode 100755
index 0000000..ae838f4
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/annotation/AnnotationPolicy.v1.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:5b82db34-1613-4108-8973-93074182dd94" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>A sample policy to demonstrate use of annotations in a Java class.</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">www.mywebsite.com</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Rule RuleId="urn:com:att:xacml:rule:id:8b257f30-4e06-4c8e-8fb7-691b9534d55c" Effect="Permit">
+ <Description>PERMIT - John can access it</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">John</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ACCESS</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:4fe7c147-7811-4e30-a463-9135afb1cfc2" Effect="Deny">
+ <Description>DENY - Ringo cannot</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Ringo</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ </Rule>
+</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/annotation/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/annotation/xacml.pip.properties
new file mode 100755
index 0000000..999c160
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/annotation/xacml.pip.properties
@@ -0,0 +1,3 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=
diff --git a/openaz-xacml-pap-rest/pdps/annotation/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/annotation/xacml.policy.properties
new file mode 100755
index 0000000..1e6bf8a
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/annotation/xacml.policy.properties
@@ -0,0 +1,5 @@
+xacml.rootPolicies=AnnotationPolicy.v1.xml
+xacml.referencedPolicies=
+
+
+AnnotationPolicy.v1.xml.url=http://localhost:9090/pap/?id=AnnotationPolicy.v1.xml
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Baseball-Hall-Of-Fame-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Baseball-Hall-Of-Fame-v1.xml
new file mode 100755
index 0000000..68c7783
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Baseball-Hall-Of-Fame-v1.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:f3047eab-6f97-49b4-8127-a2737a184b35" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides">
+ <Description>This policy enforces the BBWAA rules for baseball Hall of Fame induction.
+
+http://baseballhall.org/hall-famers/rules-election/bbwaa
+</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">eligible</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Match>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">HOF</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Policy PolicyId="urn:com:att:xacml:policy:id:8f295c67-7b6e-4db6-b558-005b36abd970" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>Active Timeframe:
+
+A. A baseball player must have been active as a player in the Major Leagues at some time during a period beginning twenty (20) years before and ending five (5) years prior to election.</Description>
+ <Target/>
+ <Rule RuleId="urn:com:att:xacml:rule:id:f04b2700-1236-4066-81e4-e341b5b2f3b5" Effect="Permit">
+ <Description>Player's debut date >= (today's date - 20 years) AND final date <= (today's date - 5 years).</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Description>debut within 20 years AND final game more than 5 years ago.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal">
+ <Description>Debut date <= (today's date - 20 years)</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+ <Description>UN-bag player's debut date.</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:debut" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration">
+ <Description>Subtract 20 years from today's date.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+<Description>UN-bag today's date.</Description>
+<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P20Y</AttributeValue>
+ </Apply>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal">
+ <Description>Final Game <= (today's date - 5 years)</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+ <Description>UN-bag final game date</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:finalgame" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration">
+ <Description>Subtract 5 years from today's date.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+<Description>UN-bag today's date.</Description>
+<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P5Y</AttributeValue>
+ </Apply>
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:33a42a79-9d82-4aa1-99d3-9fd168363695" Effect="Deny">
+ <Description>DENY - Default</Description>
+ <Target/>
+ </Rule>
+ </Policy>
+ <Policy PolicyId="urn:com:att:xacml:policy:id:1bf74cc4-658f-4e87-be22-5d5cb741f1f5" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>B. Player must have played in each of ten (10) Major League championship seasons, some part of which must have been within the period described in 3 (A).</Description>
+ <Target/>
+ <Rule RuleId="urn:com:att:xacml:rule:id:54405c39-a3f6-4a88-89bd-084f68567acd" Effect="Permit">
+ <Description>There should be >= 10 years of appearance(s) values.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal">
+ <Description>The number of years a player appeared.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-bag-size">
+ <Description>Count the number.</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:appearance" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">10</AttributeValue>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:912dd1a2-1527-4b6f-a95b-6a729ff9caab" Effect="Deny">
+ <Description>DENY - Default</Description>
+ <Target/>
+ </Rule>
+ </Policy>
+</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Legal-Age-Marriage-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Legal-Age-Marriage-v1.xml
new file mode 100755
index 0000000..15e25ed
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/CSV-Legal-Age-Marriage-v1.xml
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:98779898-b880-44d7-bee5-ce54e42266eb" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides">
+ <Description>Sample policy for the XACML-TEST project that tests the configurable CSV PIP.</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Marry</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Policy PolicyId="urn:com:att:xacml:policy:id:c6791398-7e1f-4564-8f5c-19f406ea9950" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
+ <Description>Checks the subject. </Description>
+ <Target/>
+ <VariableDefinition VariableId="isSubjectFemale">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <Description>sex=Female</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <Description>un-bag</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="isSubjectMale">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <Description>subject sex=Male</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <Description>Un-bag</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="doesSubjectNeedParentalConsent">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
+ <Description>Is the subject a female OR male?</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Description>Is female AND does not need parental consent.</Description>
+ <VariableReference VariableId="isSubjectFemale"/>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+ <Description>age >= consent age</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag attribute.</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag attribute.</Description>
+ <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ </Apply>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Description>Is subject male AND age >= male consent age.</Description>
+ <VariableReference VariableId="isSubjectMale"/>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+ <Description>age >= legal age of consent for male.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag attribute.</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag attribute.</Description>
+ <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ </Apply>
+ </Apply>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="doesSubjectHaveParentalConsent">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <Rule RuleId="urn:com:att:xacml:rule:id:5970b5d2-c0f3-4132-bfa2-268467b21ed7" Effect="Permit">
+ <Description>If the subject does NOT need consent, then PERMIT.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesSubjectNeedParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:04b3e93d-ec4e-4cce-a00e-6a54cf3c4056" Effect="Permit">
+ <Description>If the subject needs consent AND has parental consent, then Permit.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesSubjectNeedParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesSubjectHaveParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+ </Policy>
+ <Policy PolicyId="urn:com:att:xacml:policy:id:32474315-9d06-47a4-bc2d-319e0568742c" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
+ <Description>Check the resource.</Description>
+ <Target/>
+ <VariableDefinition VariableId="isResourceFemale">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <Description>sex=Female</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <Description>un-bag</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="isResourceMale">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <Description>subject sex=Male</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <Description>Un-bag</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="doesResourceNeedParentalConsent">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
+ <Description>Is resource female OR male?</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Description>Is female AND does not need parental consent.</Description>
+ <VariableReference VariableId="isResourceFemale"/>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+ <Description>age >= consent age for female.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag attribute</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>un-bag attribute</Description>
+ <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ </Apply>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Description>Is male and AND does not need parental consent.</Description>
+ <VariableReference VariableId="isResourceMale"/>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+ <Description>age >= consent age for male.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag</Description>
+ <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>
+ </Apply>
+ </Apply>
+ </Apply>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="doesResourceHaveParentalConsent">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <Rule RuleId="urn:com:att:xacml:rule:id:7d1c6802-97f7-44f6-9819-12edc1801fb7" Effect="Permit">
+ <Description>If the resource does NOT need consent, then PERMIT.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesResourceNeedParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:62e07da4-f0e5-46eb-9894-f5e6d2e5868b" Effect="Permit">
+ <Description>The resources needs parental consent and has parental consent then PERMIT.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesResourceNeedParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesResourceHaveParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+ </Policy>
+</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.pip.properties
new file mode 100755
index 0000000..17ec3a2
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.pip.properties
@@ -0,0 +1,227 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=csv1,csv2,hyper1
+
+ATTWebPhone.classname=com.att.research.xacmlatt.pip.webphone.PIPEngineATTWebphone
+CSO.classname=com.att.research.xacmlatt.pip.cso.PIPEngineCSOCookie
+CSO.mode=DEVL
+
+csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv1.name=Master
+csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info
+csv1.issuer=com:att:research:xacml:test:csv
+csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt
+csv1.maxsize=500000
+csv1.delimiter=,
+csv1.quote="
+csv1.skip=0
+
+csv1.resolvers=data
+
+csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv1.resolver.data.name=Player Resolver
+csv1.resolver.data.description=This resolver finds player information in the Master table.
+csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame
+csv1.resolver.data.field.firstname.column=16
+csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname
+csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.lastname.column=17
+csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname
+csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathyear.column=10
+csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear
+csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathmonth.column=11
+csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth
+csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathday.column=12
+csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday
+csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.debut.column=25
+csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut
+csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.finalgame.column=26
+csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame
+csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.parameters=playerid
+csv1.resolver.data.parameter.playerid.column=1
+csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv2.name=Appearances
+csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year.
+#csv2.issuer=
+csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt
+csv2.maxsize=500000
+csv2.delimiter=,
+csv2.quote="
+csv2.skip=0
+
+csv2.resolvers=data
+
+csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv2.resolver.data.name=Appearance Resolver
+csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table.
+csv2.resolver.data.fields=appearance
+csv2.resolver.data.field.appearance.column=0
+csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance
+csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv
+
+csv2.resolver.data.parameters=playerid
+csv2.resolver.data.parameter.playerid.column=3
+csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#csv1.resolver.data.parameter.playerid.issuer=
+
+hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine
+hyper1.name=World Marriage Age Limits
+hyper1.description=Minimum age for female/male marriages with or without their parental consent.
+hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv
+hyper1.target=marriage
+hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20)
+
+hyper1.resolvers=age_consent
+
+hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+hyper1.resolver.age_consent.name=Ages
+hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country.
+hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=?
+hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale
+
+hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female
+hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male
+hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female
+hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male
+hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.parameters=country
+hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name
+hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string
+hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country
+#hyper1.resolver.age_consent.parameter.country.issuer=
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data.
+#
+sql1.type=jdbc
+sql1.jdbc.driver=org.postgresql.Driver
+#sql1.jdbc.url=jdbc:postgresql://localhost:5432/world
+#sql1.jdbc.conn.user=sa
+#sql1.jdbc.conn.password=
+sql1.jdbc.url=jdbc:postgresql://xacml-pip.research.att.com:5432/world
+sql1.jdbc.conn.user=pip
+sql1.jdbc.conn.password=p1pUs3r
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the language for a city.
+sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=?
+sql1.resolver.langer.fields=language
+sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language
+sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=name
+sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine
+ldap1.name=LDAP PIP
+ldap1.description=The LDAP containing the seven seas sample LDIF data.
+ldap1.issuer=com:att:research:xacml:test:ldap
+ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
+#
+# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before
+# this example will work.
+#
+#ldap1.java.naming.provider.url=ldap://localhost:10389
+ldap1.java.naming.provider.url=ldap://xacml-pip.research.att.com:10389
+#ldap.java.naming.security.principal=
+#ldap.java.naming.security.credentials=
+ldap1.scope=subtree
+
+ldap1.resolvers=dn,ship
+
+ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.dn.name=Domain Names
+ldap1.resolver.dn.description=Find all the dn's for the subject id
+ldap1.resolver.dn.base=o=sevenseas
+ldap1.resolver.dn.base.parameters=
+ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid}))
+ldap1.resolver.dn.filter.parameters=uid
+ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.dn.filter.view=dn
+ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap
+
+ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.ship.name=Ship Resolver
+ldap1.resolver.ship.description=This resolves a subject's dn to a ship.
+ldap1.resolver.ship.base=o=sevenseas
+ldap1.resolver.ship.base.parameters=
+ldap1.resolver.ship.filter=uniquemember=${dn}
+ldap1.resolver.ship.filter.parameters=dn
+ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.ship.filter.view=cn
+ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship
+ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.policy.properties
new file mode 100755
index 0000000..6c2cb20
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv-and-hyper/xacml.policy.properties
@@ -0,0 +1,8 @@
+xacml.rootPolicies=CSV-Baseball-Hall-Of-Fame-v1.xml,CSV-Legal-Age-Marriage-v1.xml
+xacml.referencedPolicies=
+
+
+CSV-Baseball-Hall-Of-Fame-v1.xml.url=http://localhost:9090/pap/?id=CSV-Baseball-Hall-Of-Fame-v1.xml
+
+CSV-Legal-Age-Marriage-v1.xml.url=http://localhost:9090/pap/?id=CSV-Legal-Age-Marriage-v1.xml
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/CSV-Legal-Age-Marriage-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/CSV-Legal-Age-Marriage-v1.xml
new file mode 100755
index 0000000..15e25ed
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/CSV-Legal-Age-Marriage-v1.xml
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:98779898-b880-44d7-bee5-ce54e42266eb" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides">
+ <Description>Sample policy for the XACML-TEST project that tests the configurable CSV PIP.</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Marry</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Policy PolicyId="urn:com:att:xacml:policy:id:c6791398-7e1f-4564-8f5c-19f406ea9950" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
+ <Description>Checks the subject. </Description>
+ <Target/>
+ <VariableDefinition VariableId="isSubjectFemale">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <Description>sex=Female</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <Description>un-bag</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="isSubjectMale">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <Description>subject sex=Male</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <Description>Un-bag</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="doesSubjectNeedParentalConsent">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
+ <Description>Is the subject a female OR male?</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Description>Is female AND does not need parental consent.</Description>
+ <VariableReference VariableId="isSubjectFemale"/>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+ <Description>age >= consent age</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag attribute.</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag attribute.</Description>
+ <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ </Apply>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Description>Is subject male AND age >= male consent age.</Description>
+ <VariableReference VariableId="isSubjectMale"/>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+ <Description>age >= legal age of consent for male.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag attribute.</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag attribute.</Description>
+ <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ </Apply>
+ </Apply>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="doesSubjectHaveParentalConsent">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <Rule RuleId="urn:com:att:xacml:rule:id:5970b5d2-c0f3-4132-bfa2-268467b21ed7" Effect="Permit">
+ <Description>If the subject does NOT need consent, then PERMIT.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesSubjectNeedParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:04b3e93d-ec4e-4cce-a00e-6a54cf3c4056" Effect="Permit">
+ <Description>If the subject needs consent AND has parental consent, then Permit.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesSubjectNeedParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesSubjectHaveParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+ </Policy>
+ <Policy PolicyId="urn:com:att:xacml:policy:id:32474315-9d06-47a4-bc2d-319e0568742c" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
+ <Description>Check the resource.</Description>
+ <Target/>
+ <VariableDefinition VariableId="isResourceFemale">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <Description>sex=Female</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <Description>un-bag</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="isResourceMale">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <Description>subject sex=Male</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <Description>Un-bag</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="doesResourceNeedParentalConsent">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
+ <Description>Is resource female OR male?</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Description>Is female AND does not need parental consent.</Description>
+ <VariableReference VariableId="isResourceFemale"/>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+ <Description>age >= consent age for female.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag attribute</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>un-bag attribute</Description>
+ <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ </Apply>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Description>Is male and AND does not need parental consent.</Description>
+ <VariableReference VariableId="isResourceMale"/>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+ <Description>age >= consent age for male.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag</Description>
+ <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>
+ </Apply>
+ </Apply>
+ </Apply>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="doesResourceHaveParentalConsent">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <Rule RuleId="urn:com:att:xacml:rule:id:7d1c6802-97f7-44f6-9819-12edc1801fb7" Effect="Permit">
+ <Description>If the resource does NOT need consent, then PERMIT.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesResourceNeedParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:62e07da4-f0e5-46eb-9894-f5e6d2e5868b" Effect="Permit">
+ <Description>The resources needs parental consent and has parental consent then PERMIT.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesResourceNeedParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesResourceHaveParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+ </Policy>
+</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.pip.properties
new file mode 100755
index 0000000..5f66428
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.pip.properties
@@ -0,0 +1,227 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=hyper1
+
+ATTWebPhone.classname=com.att.research.xacmlatt.pip.webphone.PIPEngineATTWebphone
+CSO.classname=com.att.research.xacmlatt.pip.cso.PIPEngineCSOCookie
+CSO.mode=DEVL
+
+csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv1.name=Master
+csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info
+csv1.issuer=com:att:research:xacml:test:csv
+csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt
+csv1.maxsize=500000
+csv1.delimiter=,
+csv1.quote="
+csv1.skip=0
+
+csv1.resolvers=data
+
+csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv1.resolver.data.name=Player Resolver
+csv1.resolver.data.description=This resolver finds player information in the Master table.
+csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame
+csv1.resolver.data.field.firstname.column=16
+csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname
+csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.lastname.column=17
+csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname
+csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathyear.column=10
+csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear
+csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathmonth.column=11
+csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth
+csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathday.column=12
+csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday
+csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.debut.column=25
+csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut
+csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.finalgame.column=26
+csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame
+csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.parameters=playerid
+csv1.resolver.data.parameter.playerid.column=1
+csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv2.name=Appearances
+csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year.
+#csv2.issuer=
+csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt
+csv2.maxsize=500000
+csv2.delimiter=,
+csv2.quote="
+csv2.skip=0
+
+csv2.resolvers=data
+
+csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv2.resolver.data.name=Appearance Resolver
+csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table.
+csv2.resolver.data.fields=appearance
+csv2.resolver.data.field.appearance.column=0
+csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance
+csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv
+
+csv2.resolver.data.parameters=playerid
+csv2.resolver.data.parameter.playerid.column=3
+csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#csv1.resolver.data.parameter.playerid.issuer=
+
+hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine
+hyper1.name=World Marriage Age Limits
+hyper1.description=Minimum age for female/male marriages with or without their parental consent.
+hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv
+hyper1.target=marriage
+hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20)
+
+hyper1.resolvers=age_consent
+
+hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+hyper1.resolver.age_consent.name=Ages
+hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country.
+hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=?
+hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale
+
+hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female
+hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male
+hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female
+hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male
+hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.parameters=country
+hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name
+hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string
+hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country
+#hyper1.resolver.age_consent.parameter.country.issuer=
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data.
+#
+sql1.type=jdbc
+sql1.jdbc.driver=org.postgresql.Driver
+#sql1.jdbc.url=jdbc:postgresql://localhost:5432/world
+#sql1.jdbc.conn.user=sa
+#sql1.jdbc.conn.password=
+sql1.jdbc.url=jdbc:postgresql://xacml-pip.research.att.com:5432/world
+sql1.jdbc.conn.user=pip
+sql1.jdbc.conn.password=p1pUs3r
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the language for a city.
+sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=?
+sql1.resolver.langer.fields=language
+sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language
+sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=name
+sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine
+ldap1.name=LDAP PIP
+ldap1.description=The LDAP containing the seven seas sample LDIF data.
+ldap1.issuer=com:att:research:xacml:test:ldap
+ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
+#
+# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before
+# this example will work.
+#
+#ldap1.java.naming.provider.url=ldap://localhost:10389
+ldap1.java.naming.provider.url=ldap://xacml-pip.research.att.com:10389
+#ldap.java.naming.security.principal=
+#ldap.java.naming.security.credentials=
+ldap1.scope=subtree
+
+ldap1.resolvers=dn,ship
+
+ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.dn.name=Domain Names
+ldap1.resolver.dn.description=Find all the dn's for the subject id
+ldap1.resolver.dn.base=o=sevenseas
+ldap1.resolver.dn.base.parameters=
+ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid}))
+ldap1.resolver.dn.filter.parameters=uid
+ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.dn.filter.view=dn
+ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap
+
+ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.ship.name=Ship Resolver
+ldap1.resolver.ship.description=This resolves a subject's dn to a ship.
+ldap1.resolver.ship.base=o=sevenseas
+ldap1.resolver.ship.base.parameters=
+ldap1.resolver.ship.filter=uniquemember=${dn}
+ldap1.resolver.ship.filter.parameters=dn
+ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.ship.filter.view=cn
+ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship
+ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.policy.properties
new file mode 100755
index 0000000..273f36d
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv-hyper/xacml.policy.properties
@@ -0,0 +1,6 @@
+xacml.rootPolicies=CSV-Legal-Age-Marriage-v1.xml
+xacml.referencedPolicies=
+
+
+CSV-Legal-Age-Marriage-v1.xml.url=http://localhost:9090/pap/?id=CSV-Legal-Age-Marriage-v1.xml
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv/CSV-Baseball-Hall-Of-Fame-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-csv/CSV-Baseball-Hall-Of-Fame-v1.xml
new file mode 100755
index 0000000..68c7783
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv/CSV-Baseball-Hall-Of-Fame-v1.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:f3047eab-6f97-49b4-8127-a2737a184b35" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides">
+ <Description>This policy enforces the BBWAA rules for baseball Hall of Fame induction.
+
+http://baseballhall.org/hall-famers/rules-election/bbwaa
+</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">eligible</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Match>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">HOF</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Policy PolicyId="urn:com:att:xacml:policy:id:8f295c67-7b6e-4db6-b558-005b36abd970" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>Active Timeframe:
+
+A. A baseball player must have been active as a player in the Major Leagues at some time during a period beginning twenty (20) years before and ending five (5) years prior to election.</Description>
+ <Target/>
+ <Rule RuleId="urn:com:att:xacml:rule:id:f04b2700-1236-4066-81e4-e341b5b2f3b5" Effect="Permit">
+ <Description>Player's debut date >= (today's date - 20 years) AND final date <= (today's date - 5 years).</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Description>debut within 20 years AND final game more than 5 years ago.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal">
+ <Description>Debut date <= (today's date - 20 years)</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+ <Description>UN-bag player's debut date.</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:debut" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration">
+ <Description>Subtract 20 years from today's date.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+<Description>UN-bag today's date.</Description>
+<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P20Y</AttributeValue>
+ </Apply>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal">
+ <Description>Final Game <= (today's date - 5 years)</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+ <Description>UN-bag final game date</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:finalgame" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration">
+ <Description>Subtract 5 years from today's date.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+<Description>UN-bag today's date.</Description>
+<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P5Y</AttributeValue>
+ </Apply>
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:33a42a79-9d82-4aa1-99d3-9fd168363695" Effect="Deny">
+ <Description>DENY - Default</Description>
+ <Target/>
+ </Rule>
+ </Policy>
+ <Policy PolicyId="urn:com:att:xacml:policy:id:1bf74cc4-658f-4e87-be22-5d5cb741f1f5" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>B. Player must have played in each of ten (10) Major League championship seasons, some part of which must have been within the period described in 3 (A).</Description>
+ <Target/>
+ <Rule RuleId="urn:com:att:xacml:rule:id:54405c39-a3f6-4a88-89bd-084f68567acd" Effect="Permit">
+ <Description>There should be >= 10 years of appearance(s) values.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal">
+ <Description>The number of years a player appeared.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-bag-size">
+ <Description>Count the number.</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:appearance" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">10</AttributeValue>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:912dd1a2-1527-4b6f-a95b-6a729ff9caab" Effect="Deny">
+ <Description>DENY - Default</Description>
+ <Target/>
+ </Rule>
+ </Policy>
+</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.pip.properties
new file mode 100755
index 0000000..ebd0904
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.pip.properties
@@ -0,0 +1,227 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=csv1,csv2
+
+ATTWebPhone.classname=com.att.research.xacmlatt.pip.webphone.PIPEngineATTWebphone
+CSO.classname=com.att.research.xacmlatt.pip.cso.PIPEngineCSOCookie
+CSO.mode=DEVL
+
+csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv1.name=Master
+csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info
+csv1.issuer=com:att:research:xacml:test:csv
+csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt
+csv1.maxsize=500000
+csv1.delimiter=,
+csv1.quote="
+csv1.skip=0
+
+csv1.resolvers=data
+
+csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv1.resolver.data.name=Player Resolver
+csv1.resolver.data.description=This resolver finds player information in the Master table.
+csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame
+csv1.resolver.data.field.firstname.column=16
+csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname
+csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.lastname.column=17
+csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname
+csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathyear.column=10
+csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear
+csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathmonth.column=11
+csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth
+csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathday.column=12
+csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday
+csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.debut.column=25
+csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut
+csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.finalgame.column=26
+csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame
+csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.parameters=playerid
+csv1.resolver.data.parameter.playerid.column=1
+csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv2.name=Appearances
+csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year.
+#csv2.issuer=
+csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt
+csv2.maxsize=500000
+csv2.delimiter=,
+csv2.quote="
+csv2.skip=0
+
+csv2.resolvers=data
+
+csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv2.resolver.data.name=Appearance Resolver
+csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table.
+csv2.resolver.data.fields=appearance
+csv2.resolver.data.field.appearance.column=0
+csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance
+csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv
+
+csv2.resolver.data.parameters=playerid
+csv2.resolver.data.parameter.playerid.column=3
+csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#csv1.resolver.data.parameter.playerid.issuer=
+
+hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine
+hyper1.name=World Marriage Age Limits
+hyper1.description=Minimum age for female/male marriages with or without their parental consent.
+hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv
+hyper1.target=marriage
+hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20)
+
+hyper1.resolvers=age_consent
+
+hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+hyper1.resolver.age_consent.name=Ages
+hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country.
+hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=?
+hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale
+
+hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female
+hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male
+hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female
+hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male
+hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.parameters=country
+hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name
+hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string
+hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country
+#hyper1.resolver.age_consent.parameter.country.issuer=
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data.
+#
+sql1.type=jdbc
+sql1.jdbc.driver=org.postgresql.Driver
+#sql1.jdbc.url=jdbc:postgresql://localhost:5432/world
+#sql1.jdbc.conn.user=sa
+#sql1.jdbc.conn.password=
+sql1.jdbc.url=jdbc:postgresql://xacml-pip.research.att.com:5432/world
+sql1.jdbc.conn.user=pip
+sql1.jdbc.conn.password=p1pUs3r
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the language for a city.
+sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=?
+sql1.resolver.langer.fields=language
+sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language
+sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=name
+sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine
+ldap1.name=LDAP PIP
+ldap1.description=The LDAP containing the seven seas sample LDIF data.
+ldap1.issuer=com:att:research:xacml:test:ldap
+ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
+#
+# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before
+# this example will work.
+#
+#ldap1.java.naming.provider.url=ldap://localhost:10389
+ldap1.java.naming.provider.url=ldap://xacml-pip.research.att.com:10389
+#ldap.java.naming.security.principal=
+#ldap.java.naming.security.credentials=
+ldap1.scope=subtree
+
+ldap1.resolvers=dn,ship
+
+ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.dn.name=Domain Names
+ldap1.resolver.dn.description=Find all the dn's for the subject id
+ldap1.resolver.dn.base=o=sevenseas
+ldap1.resolver.dn.base.parameters=
+ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid}))
+ldap1.resolver.dn.filter.parameters=uid
+ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.dn.filter.view=dn
+ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap
+
+ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.ship.name=Ship Resolver
+ldap1.resolver.ship.description=This resolves a subject's dn to a ship.
+ldap1.resolver.ship.base=o=sevenseas
+ldap1.resolver.ship.base.parameters=
+ldap1.resolver.ship.filter=uniquemember=${dn}
+ldap1.resolver.ship.filter.parameters=dn
+ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.ship.filter.view=cn
+ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship
+ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.policy.properties
new file mode 100755
index 0000000..59a8dd7
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-csv/xacml.policy.properties
@@ -0,0 +1,6 @@
+xacml.rootPolicies=CSV-Baseball-Hall-Of-Fame-v1.xml
+xacml.referencedPolicies=
+
+
+CSV-Baseball-Hall-Of-Fame-v1.xml.url=http://localhost:9090/pap/?id=CSV-Baseball-Hall-Of-Fame-v1.xml
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-ldap/LDAP-Seven-Seas-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-ldap/LDAP-Seven-Seas-v1.xml
new file mode 100755
index 0000000..9e36f68
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-ldap/LDAP-Seven-Seas-v1.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:94378f81-6810-408f-a072-a1a8a7585a24" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>Sample policy that demonstrates use of Configurable LDAP Resolver with sample data.
+
+The PEP Request should provide the following attributes:
+action-id=board
+subject-id-qualifer=uid|mail
+subject-id=hnelson|hnelson@royalnavy.mod.uk
+resource-id=HMS Lydia|HMS Victory|HMS Bounty
+ </Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">board</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Rule RuleId="urn:com:att:xacml:rule:id:bf241671-54de-404c-ac59-bb17b919783f" Effect="Permit">
+ <Description>This sailor is a member of the crew for the ship.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:ldap:subject:ship" DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="com:att:research:xacml:test:ldap" MustBePresent="false"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:490228ea-98ee-48d8-84c9-da07334726fd" Effect="Deny">
+ <Description>Default is to DENY.</Description>
+ <Target/>
+ </Rule>
+</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.pip.properties
new file mode 100755
index 0000000..deb58b4
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.pip.properties
@@ -0,0 +1,227 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=ldap1
+
+ATTWebPhone.classname=com.att.research.xacmlatt.pip.webphone.PIPEngineATTWebphone
+CSO.classname=com.att.research.xacmlatt.pip.cso.PIPEngineCSOCookie
+CSO.mode=DEVL
+
+csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv1.name=Master
+csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info
+csv1.issuer=com:att:research:xacml:test:csv
+csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt
+csv1.maxsize=4000000
+csv1.delimiter=,
+csv1.quote="
+csv1.skip=0
+
+csv1.resolvers=data
+
+csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv1.resolver.data.name=Player Resolver
+csv1.resolver.data.description=This resolver finds player information in the Master table.
+csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame
+csv1.resolver.data.field.firstname.column=16
+csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname
+csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.lastname.column=17
+csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname
+csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathyear.column=10
+csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear
+csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathmonth.column=11
+csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth
+csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathday.column=12
+csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday
+csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.debut.column=25
+csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut
+csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.finalgame.column=26
+csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame
+csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.parameters=playerid
+csv1.resolver.data.parameter.playerid.column=1
+csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv2.name=Appearances
+csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year.
+#csv2.issuer=
+csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt
+csv2.maxsize=4000000
+csv2.delimiter=,
+csv2.quote="
+csv2.skip=0
+
+csv2.resolvers=data
+
+csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv2.resolver.data.name=Appearance Resolver
+csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table.
+csv2.resolver.data.fields=appearance
+csv2.resolver.data.field.appearance.column=0
+csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance
+csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv
+
+csv2.resolver.data.parameters=playerid
+csv2.resolver.data.parameter.playerid.column=3
+csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#csv1.resolver.data.parameter.playerid.issuer=
+
+hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine
+hyper1.name=World Marriage Age Limits
+hyper1.description=Minimum age for female/male marriages with or without their parental consent.
+hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv
+hyper1.target=marriage
+hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20)
+
+hyper1.resolvers=age_consent
+
+hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+hyper1.resolver.age_consent.name=Ages
+hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country.
+hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=?
+hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale
+
+hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female
+hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male
+hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female
+hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male
+hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.parameters=country
+hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name
+hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string
+hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country
+#hyper1.resolver.age_consent.parameter.country.issuer=
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data.
+#
+sql1.type=jdbc
+sql1.jdbc.driver=org.postgresql.Driver
+#sql1.jdbc.url=jdbc:postgresql://localhost:5432/world
+#sql1.jdbc.conn.user=sa
+#sql1.jdbc.conn.password=
+sql1.jdbc.url=jdbc:postgresql://xacml-pip.research.att.com:5432/world
+sql1.jdbc.conn.user=pip
+sql1.jdbc.conn.password=p1pUs3r
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the language for a city.
+sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=?
+sql1.resolver.langer.fields=language
+sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language
+sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=name
+sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine
+ldap1.name=LDAP PIP
+ldap1.description=The LDAP containing the seven seas sample LDIF data.
+ldap1.issuer=com:att:research:xacml:test:ldap
+ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
+#
+# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before
+# this example will work.
+#
+#ldap1.java.naming.provider.url=ldap://localhost:10389
+ldap1.java.naming.provider.url=ldap://xacml-pip.research.att.com:10389
+#ldap.java.naming.security.principal=
+#ldap.java.naming.security.credentials=
+ldap1.scope=subtree
+
+ldap1.resolvers=dn,ship
+
+ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.dn.name=Domain Names
+ldap1.resolver.dn.description=Find all the dn's for the subject id
+ldap1.resolver.dn.base=o=sevenseas
+ldap1.resolver.dn.base.parameters=
+ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid}))
+ldap1.resolver.dn.filter.parameters=uid
+ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.dn.filter.view=dn
+ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap
+
+ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.ship.name=Ship Resolver
+ldap1.resolver.ship.description=This resolves a subject's dn to a ship.
+ldap1.resolver.ship.base=o=sevenseas
+ldap1.resolver.ship.base.parameters=
+ldap1.resolver.ship.filter=uniquemember=${dn}
+ldap1.resolver.ship.filter.parameters=dn
+ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.ship.filter.view=cn
+ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship
+ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.policy.properties
new file mode 100755
index 0000000..df57627
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-ldap/xacml.policy.properties
@@ -0,0 +1,5 @@
+xacml.rootPolicies=LDAP-Seven-Seas-v1.xml
+xacml.referencedPolicies=
+
+
+LDAP-Seven-Seas-v1.xml.url=http://localhost:9090/pap/?id=LDAP-Seven-Seas-v1.xml
diff --git a/openaz-xacml-pap-rest/pdps/configurable-sql/SQL-World-Languages-v1.xml b/openaz-xacml-pap-rest/pdps/configurable-sql/SQL-World-Languages-v1.xml
new file mode 100755
index 0000000..85443dc
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-sql/SQL-World-Languages-v1.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:25e12b06-11d5-4895-b2a2-6f6c594de069" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>Policy for speaking a language in a city.</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">speak</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Rule RuleId="urn:com:att:xacml:rule:id:e1e8c5c0-e2ba-47d5-9289-6c015305ed21" Effect="Permit">
+ <Description>PERMIT - People in this city speak my language.</Description>
+ <Target/>
+ <Condition>
+ <VariableReference VariableId="cityLanguage"/>
+ </Condition>
+ </Rule>
+ <VariableDefinition VariableId="cityLanguage">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-is-in">
+ <Description>The city's language must match exactly the subject's language.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:sql:resource:city:language" DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="com:att:research:xacml:test:sql" MustBePresent="false"/>
+ </Apply>
+ </VariableDefinition>
+ <Rule RuleId="urn:com:att:xacml:rule:id:c9a3fb7d-d0b9-48bb-bdca-87eb4957120c" Effect="Deny">
+ <Description>DENY - default.</Description>
+ <Target/>
+ </Rule>
+</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.pip.properties
new file mode 100755
index 0000000..dcfd4c8
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.pip.properties
@@ -0,0 +1,227 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=sql1
+
+ATTWebPhone.classname=com.att.research.xacmlatt.pip.webphone.PIPEngineATTWebphone
+CSO.classname=com.att.research.xacmlatt.pip.cso.PIPEngineCSOCookie
+CSO.mode=DEVL
+
+csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv1.name=Master
+csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info
+csv1.issuer=com:att:research:xacml:test:csv
+csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt
+csv1.maxsize=4000000
+csv1.delimiter=,
+csv1.quote="
+csv1.skip=0
+
+csv1.resolvers=data
+
+csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv1.resolver.data.name=Player Resolver
+csv1.resolver.data.description=This resolver finds player information in the Master table.
+csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame
+csv1.resolver.data.field.firstname.column=16
+csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname
+csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.lastname.column=17
+csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname
+csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathyear.column=10
+csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear
+csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathmonth.column=11
+csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth
+csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathday.column=12
+csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday
+csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.debut.column=25
+csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut
+csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.finalgame.column=26
+csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame
+csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.parameters=playerid
+csv1.resolver.data.parameter.playerid.column=1
+csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv2.name=Appearances
+csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year.
+#csv2.issuer=
+csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt
+csv2.maxsize=4000000
+csv2.delimiter=,
+csv2.quote="
+csv2.skip=0
+
+csv2.resolvers=data
+
+csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv2.resolver.data.name=Appearance Resolver
+csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table.
+csv2.resolver.data.fields=appearance
+csv2.resolver.data.field.appearance.column=0
+csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance
+csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv
+
+csv2.resolver.data.parameters=playerid
+csv2.resolver.data.parameter.playerid.column=3
+csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#csv1.resolver.data.parameter.playerid.issuer=
+
+hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine
+hyper1.name=World Marriage Age Limits
+hyper1.description=Minimum age for female/male marriages with or without their parental consent.
+hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv
+hyper1.target=marriage
+hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20)
+
+hyper1.resolvers=age_consent
+
+hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+hyper1.resolver.age_consent.name=Ages
+hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country.
+hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=?
+hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale
+
+hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female
+hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male
+hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female
+hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male
+hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.parameters=country
+hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name
+hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string
+hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country
+#hyper1.resolver.age_consent.parameter.country.issuer=
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data.
+#
+sql1.type=jdbc
+sql1.jdbc.driver=org.postgresql.Driver
+#sql1.jdbc.url=jdbc:postgresql://localhost:5432/world
+#sql1.jdbc.conn.user=sa
+#sql1.jdbc.conn.password=
+sql1.jdbc.url=jdbc:postgresql://xacml-pip.research.att.com:5432/world
+sql1.jdbc.conn.user=pip
+sql1.jdbc.conn.password=p1pUs3r
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the language for a city.
+sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=?
+sql1.resolver.langer.fields=language
+sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language
+sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=name
+sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine
+ldap1.name=LDAP PIP
+ldap1.description=The LDAP containing the seven seas sample LDIF data.
+ldap1.issuer=com:att:research:xacml:test:ldap
+ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
+#
+# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before
+# this example will work.
+#
+#ldap1.java.naming.provider.url=ldap://localhost:10389
+ldap1.java.naming.provider.url=ldap://xacml-pip.research.att.com:10389
+#ldap.java.naming.security.principal=
+#ldap.java.naming.security.credentials=
+ldap1.scope=subtree
+
+ldap1.resolvers=dn,ship
+
+ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.dn.name=Domain Names
+ldap1.resolver.dn.description=Find all the dn's for the subject id
+ldap1.resolver.dn.base=o=sevenseas
+ldap1.resolver.dn.base.parameters=
+ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid}))
+ldap1.resolver.dn.filter.parameters=uid
+ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.dn.filter.view=dn
+ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap
+
+ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.ship.name=Ship Resolver
+ldap1.resolver.ship.description=This resolves a subject's dn to a ship.
+ldap1.resolver.ship.base=o=sevenseas
+ldap1.resolver.ship.base.parameters=
+ldap1.resolver.ship.filter=uniquemember=${dn}
+ldap1.resolver.ship.filter.parameters=dn
+ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.ship.filter.view=cn
+ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship
+ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap
+
diff --git a/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.policy.properties
new file mode 100755
index 0000000..ed296ed
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/configurable-sql/xacml.policy.properties
@@ -0,0 +1,6 @@
+xacml.rootPolicies=SQL-World-Languages-v1.xml
+xacml.referencedPolicies=
+
+
+SQL-World-Languages-v1.xml.url=http://localhost:9090/pap/?id=SQL-World-Languages-v1.xml
+
diff --git a/openaz-xacml-pap-rest/pdps/default/AnnotationPolicy.v1.xml b/openaz-xacml-pap-rest/pdps/default/AnnotationPolicy.v1.xml
new file mode 100755
index 0000000..ae838f4
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/default/AnnotationPolicy.v1.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:5b82db34-1613-4108-8973-93074182dd94" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>A sample policy to demonstrate use of annotations in a Java class.</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">www.mywebsite.com</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Rule RuleId="urn:com:att:xacml:rule:id:8b257f30-4e06-4c8e-8fb7-691b9534d55c" Effect="Permit">
+ <Description>PERMIT - John can access it</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">John</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ACCESS</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:4fe7c147-7811-4e30-a463-9135afb1cfc2" Effect="Deny">
+ <Description>DENY - Ringo cannot</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Ringo</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ </Rule>
+</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/default/CSV-Baseball-Hall-Of-Fame-v1.xml b/openaz-xacml-pap-rest/pdps/default/CSV-Baseball-Hall-Of-Fame-v1.xml
new file mode 100755
index 0000000..68c7783
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/default/CSV-Baseball-Hall-Of-Fame-v1.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:f3047eab-6f97-49b4-8127-a2737a184b35" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides">
+ <Description>This policy enforces the BBWAA rules for baseball Hall of Fame induction.
+
+http://baseballhall.org/hall-famers/rules-election/bbwaa
+</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">eligible</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Match>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">HOF</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Policy PolicyId="urn:com:att:xacml:policy:id:8f295c67-7b6e-4db6-b558-005b36abd970" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>Active Timeframe:
+
+A. A baseball player must have been active as a player in the Major Leagues at some time during a period beginning twenty (20) years before and ending five (5) years prior to election.</Description>
+ <Target/>
+ <Rule RuleId="urn:com:att:xacml:rule:id:f04b2700-1236-4066-81e4-e341b5b2f3b5" Effect="Permit">
+ <Description>Player's debut date >= (today's date - 20 years) AND final date <= (today's date - 5 years).</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Description>debut within 20 years AND final game more than 5 years ago.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal">
+ <Description>Debut date <= (today's date - 20 years)</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+ <Description>UN-bag player's debut date.</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:debut" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration">
+ <Description>Subtract 20 years from today's date.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+<Description>UN-bag today's date.</Description>
+<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P20Y</AttributeValue>
+ </Apply>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal">
+ <Description>Final Game <= (today's date - 5 years)</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+ <Description>UN-bag final game date</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:finalgame" DataType="http://www.w3.org/2001/XMLSchema#date" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:date-subtract-yearMonthDuration">
+ <Description>Subtract 5 years from today's date.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:date-one-and-only">
+<Description>UN-bag today's date.</Description>
+<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-date" DataType="http://www.w3.org/2001/XMLSchema#date" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#yearMonthDuration">P5Y</AttributeValue>
+ </Apply>
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:33a42a79-9d82-4aa1-99d3-9fd168363695" Effect="Deny">
+ <Description>DENY - Default</Description>
+ <Target/>
+ </Rule>
+ </Policy>
+ <Policy PolicyId="urn:com:att:xacml:policy:id:1bf74cc4-658f-4e87-be22-5d5cb741f1f5" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>B. Player must have played in each of ten (10) Major League championship seasons, some part of which must have been within the period described in 3 (A).</Description>
+ <Target/>
+ <Rule RuleId="urn:com:att:xacml:rule:id:54405c39-a3f6-4a88-89bd-084f68567acd" Effect="Permit">
+ <Description>There should be >= 10 years of appearance(s) values.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal">
+ <Description>The number of years a player appeared.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-bag-size">
+ <Description>Count the number.</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:appearance" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">10</AttributeValue>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:912dd1a2-1527-4b6f-a95b-6a729ff9caab" Effect="Deny">
+ <Description>DENY - Default</Description>
+ <Target/>
+ </Rule>
+ </Policy>
+</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/default/CSV-Legal-Age-Marriage-v1.xml b/openaz-xacml-pap-rest/pdps/default/CSV-Legal-Age-Marriage-v1.xml
new file mode 100755
index 0000000..15e25ed
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/default/CSV-Legal-Age-Marriage-v1.xml
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicySetId="urn:com:att:xacml:policy:id:98779898-b880-44d7-bee5-ce54e42266eb" Version="1" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-overrides">
+ <Description>Sample policy for the XACML-TEST project that tests the configurable CSV PIP.</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Marry</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Policy PolicyId="urn:com:att:xacml:policy:id:c6791398-7e1f-4564-8f5c-19f406ea9950" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
+ <Description>Checks the subject. </Description>
+ <Target/>
+ <VariableDefinition VariableId="isSubjectFemale">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <Description>sex=Female</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <Description>un-bag</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="isSubjectMale">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <Description>subject sex=Male</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <Description>Un-bag</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="doesSubjectNeedParentalConsent">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
+ <Description>Is the subject a female OR male?</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Description>Is female AND does not need parental consent.</Description>
+ <VariableReference VariableId="isSubjectFemale"/>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+ <Description>age >= consent age</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag attribute.</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag attribute.</Description>
+ <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ </Apply>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Description>Is subject male AND age >= male consent age.</Description>
+ <VariableReference VariableId="isSubjectMale"/>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+ <Description>age >= legal age of consent for male.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag attribute.</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag attribute.</Description>
+ <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ </Apply>
+ </Apply>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="doesSubjectHaveParentalConsent">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="com:att:research:xacml:test:csv:subject:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <Rule RuleId="urn:com:att:xacml:rule:id:5970b5d2-c0f3-4132-bfa2-268467b21ed7" Effect="Permit">
+ <Description>If the subject does NOT need consent, then PERMIT.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesSubjectNeedParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:04b3e93d-ec4e-4cce-a00e-6a54cf3c4056" Effect="Permit">
+ <Description>If the subject needs consent AND has parental consent, then Permit.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesSubjectNeedParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesSubjectHaveParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+ </Policy>
+ <Policy PolicyId="urn:com:att:xacml:policy:id:32474315-9d06-47a4-bc2d-319e0568742c" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
+ <Description>Check the resource.</Description>
+ <Target/>
+ <VariableDefinition VariableId="isResourceFemale">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <Description>sex=Female</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <Description>un-bag</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Female</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="isResourceMale">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <Description>subject sex=Male</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <Description>Un-bag</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:sex" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Male</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="doesResourceNeedParentalConsent">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
+ <Description>Is resource female OR male?</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Description>Is female AND does not need parental consent.</Description>
+ <VariableReference VariableId="isResourceFemale"/>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+ <Description>age >= consent age for female.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag attribute</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="true"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>un-bag attribute</Description>
+ <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:female" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:csv" MustBePresent="false"/>
+ </Apply>
+ </Apply>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Description>Is male and AND does not need parental consent.</Description>
+ <VariableReference VariableId="isResourceMale"/>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than">
+ <Description>age >= consent age for male.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag</Description>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:age" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <Description>Un-bag</Description>
+ <AttributeDesignator Category="com:att:research:xacml:test:csv:category:country" AttributeId="com:att:research:xacml:test:csv:country:no-consent:male" DataType="http://www.w3.org/2001/XMLSchema#integer" MustBePresent="false"/>
+ </Apply>
+ </Apply>
+ </Apply>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="doesResourceHaveParentalConsent">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:csv:resource:parental-consent" DataType="http://www.w3.org/2001/XMLSchema#boolean" MustBePresent="true"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <Rule RuleId="urn:com:att:xacml:rule:id:7d1c6802-97f7-44f6-9819-12edc1801fb7" Effect="Permit">
+ <Description>If the resource does NOT need consent, then PERMIT.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesResourceNeedParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">false</AttributeValue>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:62e07da4-f0e5-46eb-9894-f5e6d2e5868b" Effect="Permit">
+ <Description>The resources needs parental consent and has parental consent then PERMIT.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesResourceNeedParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal">
+ <VariableReference VariableId="doesResourceHaveParentalConsent"/>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#boolean">true</AttributeValue>
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+ </Policy>
+</PolicySet>
diff --git a/openaz-xacml-pap-rest/pdps/default/LDAP-Seven-Seas-v1.xml b/openaz-xacml-pap-rest/pdps/default/LDAP-Seven-Seas-v1.xml
new file mode 100755
index 0000000..9e36f68
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/default/LDAP-Seven-Seas-v1.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:94378f81-6810-408f-a072-a1a8a7585a24" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>Sample policy that demonstrates use of Configurable LDAP Resolver with sample data.
+
+The PEP Request should provide the following attributes:
+action-id=board
+subject-id-qualifer=uid|mail
+subject-id=hnelson|hnelson@royalnavy.mod.uk
+resource-id=HMS Lydia|HMS Victory|HMS Bounty
+ </Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">board</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Rule RuleId="urn:com:att:xacml:rule:id:bf241671-54de-404c-ac59-bb17b919783f" Effect="Permit">
+ <Description>This sailor is a member of the crew for the ship.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:ldap:subject:ship" DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="com:att:research:xacml:test:ldap" MustBePresent="false"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ </Apply>
+ </Condition>
+ </Rule>
+ <Rule RuleId="urn:com:att:xacml:rule:id:490228ea-98ee-48d8-84c9-da07334726fd" Effect="Deny">
+ <Description>Default is to DENY.</Description>
+ <Target/>
+ </Rule>
+</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/default/SQL-World-Languages-v1.xml b/openaz-xacml-pap-rest/pdps/default/SQL-World-Languages-v1.xml
new file mode 100755
index 0000000..85443dc
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/default/SQL-World-Languages-v1.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:25e12b06-11d5-4895-b2a2-6f6c594de069" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>Policy for speaking a language in a city.</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">speak</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Rule RuleId="urn:com:att:xacml:rule:id:e1e8c5c0-e2ba-47d5-9289-6c015305ed21" Effect="Permit">
+ <Description>PERMIT - People in this city speak my language.</Description>
+ <Target/>
+ <Condition>
+ <VariableReference VariableId="cityLanguage"/>
+ </Condition>
+ </Rule>
+ <VariableDefinition VariableId="cityLanguage">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-is-in">
+ <Description>The city's language must match exactly the subject's language.</Description>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
+ </Apply>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:sql:resource:city:language" DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="com:att:research:xacml:test:sql" MustBePresent="false"/>
+ </Apply>
+ </VariableDefinition>
+ <Rule RuleId="urn:com:att:xacml:rule:id:c9a3fb7d-d0b9-48bb-bdca-87eb4957120c" Effect="Deny">
+ <Description>DENY - default.</Description>
+ <Target/>
+ </Rule>
+</Policy>
diff --git a/openaz-xacml-pap-rest/pdps/default/xacml.pip.properties b/openaz-xacml-pap-rest/pdps/default/xacml.pip.properties
new file mode 100755
index 0000000..4d49be1
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/default/xacml.pip.properties
@@ -0,0 +1,219 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=csv1,csv2,hyper1,sql1,ldap1
+
+csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv1.name=Master
+csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info
+csv1.issuer=com:att:research:xacml:test:csv
+csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt
+csv1.maxsize=500000
+csv1.delimiter=,
+csv1.quote="
+csv1.skip=0
+
+csv1.resolvers=data
+
+csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv1.resolver.data.name=Player Resolver
+csv1.resolver.data.description=This resolver finds player information in the Master table.
+csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame
+csv1.resolver.data.field.firstname.column=16
+csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname
+csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.lastname.column=17
+csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname
+csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathyear.column=10
+csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear
+csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathmonth.column=11
+csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth
+csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathday.column=12
+csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday
+csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.debut.column=25
+csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut
+csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.finalgame.column=26
+csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame
+csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.parameters=playerid
+csv1.resolver.data.parameter.playerid.column=1
+csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv2.name=Appearances
+csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year.
+#csv2.issuer=
+csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt
+csv2.maxsize=500000
+csv2.delimiter=,
+csv2.quote="
+csv2.skip=0
+
+csv2.resolvers=data
+
+csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv2.resolver.data.name=Appearance Resolver
+csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table.
+csv2.resolver.data.fields=appearance
+csv2.resolver.data.field.appearance.column=0
+csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance
+csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv
+
+csv2.resolver.data.parameters=playerid
+csv2.resolver.data.parameter.playerid.column=3
+csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#csv1.resolver.data.parameter.playerid.issuer=
+
+hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine
+hyper1.name=World Marriage Age Limits
+hyper1.description=Minimum age for female/male marriages with or without their parental consent.
+hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv
+hyper1.target=marriage
+hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20)
+
+hyper1.resolvers=age_consent
+
+hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+hyper1.resolver.age_consent.name=Ages
+hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country.
+hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=?
+hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale
+
+hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female
+hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male
+hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female
+hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male
+hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.parameters=country
+hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name
+hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string
+hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country
+#hyper1.resolver.age_consent.parameter.country.issuer=
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data.
+#
+sql1.type=jdbc
+sql1.jdbc.driver=org.postgresql.Driver
+sql1.jdbc.url=jdbc:postgresql://localhost:5432/world
+sql1.jdbc.conn.user=sa
+sql1.jdbc.conn.password=
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the language for a city.
+sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=?
+sql1.resolver.langer.fields=language
+sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language
+sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=name
+sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine
+ldap1.name=LDAP PIP
+ldap1.description=The LDAP containing the seven seas sample LDIF data.
+ldap1.issuer=com:att:research:xacml:test:ldap
+ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
+#
+# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before
+# this example will work.
+#
+ldap1.java.naming.provider.url=ldap://localhost:10389
+#ldap.java.naming.security.principal=
+#ldap.java.naming.security.credentials=
+ldap1.scope=subtree
+
+ldap1.resolvers=dn,ship
+
+ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.dn.name=Domain Names
+ldap1.resolver.dn.description=Find all the dn's for the subject id
+ldap1.resolver.dn.base=o=sevenseas
+ldap1.resolver.dn.base.parameters=
+ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid}))
+ldap1.resolver.dn.filter.parameters=uid
+ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.dn.filter.view=dn
+ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap
+
+ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.ship.name=Ship Resolver
+ldap1.resolver.ship.description=This resolves a subject's dn to a ship.
+ldap1.resolver.ship.base=o=sevenseas
+ldap1.resolver.ship.base.parameters=
+ldap1.resolver.ship.filter=uniquemember=${dn}
+ldap1.resolver.ship.filter.parameters=dn
+ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.ship.filter.view=cn
+ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship
+ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap
+
diff --git a/openaz-xacml-pap-rest/pdps/default/xacml.policy.properties b/openaz-xacml-pap-rest/pdps/default/xacml.policy.properties
new file mode 100755
index 0000000..78c4a85
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/default/xacml.policy.properties
@@ -0,0 +1,14 @@
+xacml.rootPolicies=AnnotationPolicy.v1.xml,LDAP-Seven-Seas-v1.xml,CSV-Baseball-Hall-Of-Fame-v1.xml,CSV-Legal-Age-Marriage-v1.xml,SQL-World-Languages-v1.xml
+xacml.referencedPolicies=
+
+AnnotationPolicy.v1.xml.url=http://localhost:9090/pap/?id=AnnotationPolicy.v1.xml
+
+LDAP-Seven-Seas-v1.xml.url=http://localhost:9090/pap/?id=LDAP-Seven-Seas-v1.xml
+
+CSV-Baseball-Hall-Of-Fame-v1.xml.url=http://localhost:9090/pap/?id=CSV-Baseball-Hall-Of-Fame-v1.xml
+
+CSV-Legal-Age-Marriage-v1.xml.url=http://localhost:9090/pap/?id=CSV-Legal-Age-Marriage-v1.xml
+
+SQL-World-Languages-v1.xml.url=http://localhost:9090/pap/?id=SQL-World-Languages-v1.xml
+
+
diff --git a/openaz-xacml-pap-rest/pdps/xacml.properties b/openaz-xacml-pap-rest/pdps/xacml.properties
new file mode 100755
index 0000000..8429c20
--- /dev/null
+++ b/openaz-xacml-pap-rest/pdps/xacml.properties
@@ -0,0 +1,27 @@
+#
+#Mon Apr 21 11:22:57 EDT 2014
+xacml.pap.groups=default,configurable-csv,configurable-csv-hyper,configurable-ldap,configurable-sql,configurable-csv-and-hyper
+
+default.description=The default group where new PDP's are put.
+default.name=default
+default.pdps=
+
+configurable-csv.description=A group whose policies only serve configurable-csv requests.
+configurable-csv.name=configurable-csv
+configurable-csv.pdps=
+
+configurable-csv-hyper.description=A group whose policies only serve configurable-csv-hyper requests.
+configurable-csv-hyper.name=configurable-csv-hyper
+configurable-csv-hyper.pdps=
+
+configurable-ldap.description=A group whose policies only serve configurable-ldap requests.
+configurable-ldap.name=configurable-ldap
+configurable-ldap.pdps=
+
+configurable-sql.description=A group whose policies only serve configurable-sql requests.
+configurable-sql.name=configurable-sql
+configurable-sql.pdps=
+
+configurable-csv-and-hyper.description=A group whose policies serve both configurable-csv and configurable-csv-hyper requests but not others.
+configurable-csv-and-hyper.name=configurable-csv-and-hyper
+configurable-csv-and-hyper.pdps=
\ No newline at end of file
diff --git a/openaz-xacml-pap-rest/pom.xml b/openaz-xacml-pap-rest/pom.xml
new file mode 100755
index 0000000..d86600c
--- /dev/null
+++ b/openaz-xacml-pap-rest/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>openaz</artifactId>
+ <groupId>org.openliberty.openaz</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>openaz-xacml-pap-rest</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openliberty.openaz</groupId>
+ <artifactId>openaz-xacml</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.openliberty.openaz</groupId>
+ <artifactId>openaz-xacml-rest</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/openaz-xacml-pap-rest/src/main/java/com/att/research/xacml/rest/XACMLPapServlet.java b/openaz-xacml-pap-rest/src/main/java/com/att/research/xacml/rest/XACMLPapServlet.java
new file mode 100755
index 0000000..e57a36b
--- /dev/null
+++ b/openaz-xacml-pap-rest/src/main/java/com/att/research/xacml/rest/XACMLPapServlet.java
@@ -0,0 +1,1529 @@
+/*
+ * 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.xacml.rest;
+
+
+import com.att.research.xacml.api.pap.*;
+import com.att.research.xacml.std.pap.StdPDP;
+import com.att.research.xacml.std.pap.StdPDPGroup;
+import com.att.research.xacml.std.pap.StdPDPItemSetChangeNotifier.StdItemSetChangeListener;
+import com.att.research.xacml.std.pap.StdPDPStatus;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.XACMLProperties;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.Splitter;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebInitParam;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.*;
+import java.util.*;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Servlet implementation class XacmlPapServlet
+ *
+ *
+ * @author pameladragosh
+ */
+@WebServlet(
+ description = "Implements the XACML PAP RESTful API.",
+ urlPatterns = { "/" },
+ loadOnStartup=1,
+ initParams = {
+ @WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pap.properties", description = "The location of the properties file holding configuration information.")
+ })
+
+public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeListener, Runnable {
+ private static final long serialVersionUID = 1L;
+ private static final Log logger = LogFactory.getLog(XACMLPapServlet.class);
+
+ /*
+ *
+ * papEngine - This is our engine workhorse that manages the PDP Groups and Nodes.
+ */
+ private PAPEngine papEngine = null;
+
+ /*
+ * This PAP instance's own URL.
+ *
+ * Need this when creating URLs to send to the PDPs so they can GET the Policy files from this process.
+ */
+ private static String papURL = null;
+
+ /*
+ * List of Admin Console URLs.
+ * Used to send notifications when configuration changes.
+ *
+ * The CopyOnWriteArrayList *should* protect from concurrency errors.
+ * This list is seldom changed but often read, so the costs of this approach make sense.
+ */
+ private static final CopyOnWriteArrayList<String> adminConsoleURLStringList = new CopyOnWriteArrayList<String>();
+
+ /*
+ * This thread may be invoked upon startup to initiate sending PDP policy/pip configuration when
+ * this servlet starts. Its configurable by the admin.
+ */
+ private Thread initiateThread = null;
+
+ /*
+ // The heartbeat thread.
+ */
+ private static Heartbeat heartbeat = null;
+ private static Thread heartbeatThread = null;
+
+ /**
+ * @see HttpServlet#HttpServlet()
+ */
+ public XACMLPapServlet() {
+ super();
+ }
+
+ /**
+ * @see Servlet#init(ServletConfig)
+ */
+ public void init(ServletConfig config) throws ServletException {
+ try {
+ //
+ // Initialize
+ //
+ XACMLRest.xacmlInit(config);
+ //
+ // Load the properties
+ //
+ XACMLRest.loadXacmlProperties(null, null);
+ //
+ // Load our PAP engine, first create a factory
+ //
+ PAPEngineFactory factory = PAPEngineFactory.newInstance(XACMLProperties.getProperty(XACMLProperties.PROP_PAP_PAPENGINEFACTORY));
+ //
+ // The factory knows how to go about creating a PAP Engine
+ //
+ this.papEngine = factory.newEngine();
+ //
+ // we are about to call the PDPs and give them their configuration.
+ // To do that we need to have the URL of this PAP so we can construct the Policy file URLs
+ //
+ XACMLPapServlet.papURL = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
+ //
+ // Sanity check that a URL was defined somewhere, its essential.
+ //
+ // How to check that its valid? We can validate the form, but since we are in the init() method we
+ // are not fully loaded yet so we really couldn't ping ourself to see if the URL will work. One
+ // will have to look for errors in the PDP logs to determine if they are failing to initiate a
+ // request to this servlet.
+ //
+ if (XACMLPapServlet.papURL == null) {
+ throw new PAPException("The property " + XACMLRestProperties.PROP_PAP_URL + " is not valid: " + XACMLPapServlet.papURL);
+ }
+ //
+ // Configurable - have the PAP servlet initiate sending the latest PDP policy/pip configuration
+ // to all its known PDP nodes.
+ //
+ // Note: parseBoolean will return false if there is no property defined. This is fine for a default.
+ //
+ if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_INITIATE_PDP_CONFIG))) {
+ this.initiateThread = new Thread(this);
+ this.initiateThread.start();
+ }
+ //
+ // After startup, the PAP does Heartbeats to each of the PDPs periodically
+ //
+ XACMLPapServlet.heartbeat = new Heartbeat(this.papEngine);
+ XACMLPapServlet.heartbeatThread = new Thread(XACMLPapServlet.heartbeat);
+ XACMLPapServlet.heartbeatThread.start();
+ } catch (FactoryException | PAPException e) {
+ logger.error("Failed to create engine", e);
+ throw new ServletException ("PAP not initialized; error: "+e);
+ } catch (Exception e) {
+ logger.error("Failed to create engine - unexpected error: ", e);
+ throw new ServletException ("PAP not initialized; unexpected error: "+e); }
+ }
+
+ /**
+ * Thread used only during PAP startup to initiate change messages to all known PDPs.
+ * This must be on a separate thread so that any GET requests from the PDPs during this update can be serviced.
+ */
+ @Override
+ public void run() {
+ //
+ // send the current configuration to all the PDPs that we know about
+ //
+ changed();
+ }
+
+
+ /**
+ * @see Servlet#destroy()
+ *
+ * Depending on how this servlet is run, we may or may not care about cleaning up the resources.
+ * For now we assume that we do care.
+ */
+ public void destroy() {
+ //
+ // Make sure our threads are destroyed
+ //
+ if (XACMLPapServlet.heartbeatThread != null) {
+ //
+ // stop the heartbeat
+ //
+ try {
+ if (XACMLPapServlet.heartbeat != null) {
+ XACMLPapServlet.heartbeat.terminate();
+ }
+ XACMLPapServlet.heartbeatThread.interrupt();
+ XACMLPapServlet.heartbeatThread.join();
+ } catch (InterruptedException e) {
+ logger.error(e);
+ }
+ }
+ if (this.initiateThread != null) {
+ try {
+ this.initiateThread.interrupt();
+ this.initiateThread.join();
+ } catch (InterruptedException e) {
+ logger.error(e);
+ }
+ }
+ }
+
+ /**
+ *
+ * Called by:
+ * - PDP nodes to register themselves with the PAP, and
+ * - Admin Console to make changes in the PDP Groups.
+ *
+ * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
+ */
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ try {
+
+ XACMLRest.dumpRequest(request);
+
+ // since getParameter reads the content string, explicitly get the content before doing that.
+ // Simply getting the inputStream seems to protect it against being consumed by getParameter.
+ request.getInputStream();
+
+ //
+ // Is this from the Admin Console?
+ //
+ String groupId = request.getParameter("groupId");
+ if (groupId != null) {
+ //
+ // this is from the Admin Console, so handle separately
+ //
+ doACPost(request, response, groupId);
+ return;
+ }
+
+ //
+ // Request is from a PDP.
+ // It is coming up and asking for its config
+ //
+
+ //
+ // Get the PDP's ID
+ //
+ String id = this.getPDPID(request);
+ logger.info("doPost from: " + id);
+ //
+ // Get the PDP Object
+ //
+ PDP pdp = this.papEngine.getPDP(id);
+ //
+ // Is it known?
+ //
+ if (pdp == null) {
+ logger.info("Unknown PDP: " + id);
+ try {
+ this.papEngine.newPDP(id, this.papEngine.getDefaultGroup(), id, "Registered on first startup");
+ } catch (NullPointerException | PAPException e) {
+ logger.error("Failed to create new PDP", e);
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+ return;
+ }
+ // get the PDP we just created
+ pdp = this.papEngine.getPDP(id);
+ if (pdp == null) {
+ String message = "Failed to create new PDP for id: " + id;
+ logger.error(message);
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+ return;
+ }
+ }
+ //
+ // Get the PDP's Group
+ //
+ PDPGroup group = this.papEngine.getPDPGroup(pdp);
+ if (group == null) {
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "PDP not associated with any group, even the default");
+ return;
+ }
+ //
+ // Determine what group the PDP node is in and get
+ // its policy/pip properties.
+ //
+ Properties policies = group.getPolicyProperties();
+ Properties pipconfig = group.getPipConfigProperties();
+ //
+ // Get the current policy/pip configuration that the PDP has
+ //
+ Properties pdpProperties = new Properties();
+ pdpProperties.load(request.getInputStream());
+ logger.info("PDP Current Properties: " + pdpProperties.toString());
+ logger.info("Policies: " + (policies != null ? policies.toString() : "null"));
+ logger.info("Pip config: " + (pipconfig != null ? pipconfig.toString() : "null"));
+ //
+ // Validate the node's properties
+ //
+ boolean isCurrent = this.isPDPCurrent(policies, pipconfig, pdpProperties);
+ //
+ // Send back current configuration
+ //
+ if (isCurrent == false) {
+ //
+ // Tell the PDP we are sending back the current policies/pip config
+ //
+ logger.info("PDP configuration NOT current.");
+ if (policies != null) {
+ //
+ // Put URL's into the properties in case the PDP needs to
+ // retrieve them.
+ //
+ this.populatePolicyURL(request.getRequestURL(), policies);
+ //
+ // Copy the properties to the output stream
+ //
+ policies.store(response.getOutputStream(), "");
+ }
+ if (pipconfig != null) {
+ //
+ // Copy the properties to the output stream
+ //
+ pipconfig.store(response.getOutputStream(), "");
+ }
+ //
+ // We are good - and we are sending them information
+ //
+ response.setStatus(HttpServletResponse.SC_OK);
+//TODO - Correct?
+ setPDPSummaryStatus(pdp, PDPStatus.Status.OUT_OF_SYNCH);
+ } else {
+ //
+ // Tell them they are good
+ //
+ response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+
+ //TODO - Correct?
+ setPDPSummaryStatus(pdp, PDPStatus.Status.UP_TO_DATE);
+
+ }
+ //
+ // tell the AC that something changed
+ //
+ notifyAC();
+ } catch (PAPException e) {
+ logger.debug("POST exception: " + e, e);
+ response.sendError(500, e.getMessage());
+ return;
+ }
+ }
+
+
+ /**
+ * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
+ */
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ try {
+ XACMLRest.dumpRequest(request);
+
+ // Is this from the Admin Console?
+ String groupId = request.getParameter("groupId");
+ if (groupId != null) {
+ // this is from the Admin Console, so handle separately
+ doACGet(request, response, groupId);
+ return;
+ }
+ //
+ // Get the PDP's ID
+ //
+ String id = this.getPDPID(request);
+ logger.info("doGet from: " + id);
+ //
+ // Get the PDP Object
+ //
+ PDP pdp = this.papEngine.getPDP(id);
+ //
+ // Is it known?
+ //
+ if (pdp == null) {
+ //
+ // Check if request came from localhost
+ //
+ String message = "Unknown PDP: " + id + " from " + request.getRemoteHost() + " us: " + request.getLocalAddr();
+ logger.info(message);
+ if (request.getRemoteHost().equals("localhost") ||
+ request.getRemoteHost().equals("127.0.0.1") ||
+ request.getRemoteHost().equals(request.getLocalAddr())) {
+ //
+ // Return status information - basically all the groups
+ //
+ Set<PDPGroup> groups = papEngine.getPDPGroups();
+
+ // convert response object to JSON and include in the response
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.writeValue(response.getOutputStream(), groups);
+ response.setHeader("content-type", "application/json");
+ response.setStatus(HttpServletResponse.SC_OK);
+ return;
+ }
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED, message);
+ return;
+ }
+ //
+ // Get the PDP's Group
+ //
+ PDPGroup group = this.papEngine.getPDPGroup(pdp);
+ if (group == null) {
+ String message = "No group associated with pdp " + pdp.getId();
+ logger.warn(message);
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED, message);
+ return;
+ }
+ //
+ // Which policy do they want?
+ //
+ String policyId = request.getParameter("id");
+ if (policyId == null) {
+ String message = "Did not specify an id for the policy";
+ logger.warn(message);
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+ return;
+ }
+ PDPPolicy policy = group.getPolicy(policyId);
+ if (policy == null) {
+ String message = "Unknown policy: " + policyId;
+ logger.warn(message);
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+ return;
+ }
+ //
+ // Get its stream
+ //
+ try (InputStream is = policy.getStream(); OutputStream os = response.getOutputStream()) {
+ //
+ // Send the policy back
+ //
+ IOUtils.copy(is, os);
+
+ response.setStatus(HttpServletResponse.SC_OK);
+ } catch (PAPException e) {
+ String message = "Failed to open policy id " + policyId;
+ logger.error(message);
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+ }
+ } catch (PAPException e) {
+ logger.error("GET exception: " + e, e);
+ response.sendError(500, e.getMessage());
+ return;
+ }
+ }
+
+ protected String getPDPID(HttpServletRequest request) {
+ String pdpURL = request.getHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID);
+ if (pdpURL == null || pdpURL.isEmpty()) {
+ //
+ // Should send back its port for identification
+ //
+ logger.warn("PDP did not send custom header");
+ pdpURL = "";
+ }
+ return pdpURL;
+ }
+
+ private boolean isPDPCurrent(Properties policies, Properties pipconfig, Properties pdpProperties) {
+ String localRootPolicies = policies.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
+ String localReferencedPolicies = policies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
+ if (localRootPolicies == null || localReferencedPolicies == null) {
+ logger.warn("Missing property on PAP server: RootPolicies="+localRootPolicies+" ReferencedPolicies="+localReferencedPolicies);
+ return false;
+ }
+ //
+ // Compare the policies and pipconfig properties to the pdpProperties
+ //
+ try {
+ //
+ // the policy properties includes only xacml.rootPolicies and
+ // xacml.referencedPolicies without any .url entries
+ //
+ Properties pdpPolicies = XACMLProperties.getPolicyProperties(pdpProperties, false);
+ Properties pdpPipConfig = XACMLProperties.getPipProperties(pdpProperties);
+ if (localRootPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_ROOTPOLICIES)) &&
+ localReferencedPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES)) &&
+ pdpPipConfig.equals(pipconfig)) {
+ //
+ // The PDP is current
+ //
+ return true;
+ }
+ } catch (Exception e) {
+ // we get here if the PDP did not include either xacml.rootPolicies or xacml.pip.engines,
+ // or if there are policies that do not have a corresponding ".url" property.
+ // Either of these cases means that the PDP is not up-to-date, so just drop-through to return false.
+ }
+ return false;
+ }
+
+ private void populatePolicyURL(StringBuffer urlPath, Properties policies) {
+ String lists[] = new String[2];
+ lists[0] = policies.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
+ lists[1] = policies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
+ for (String list : lists) {
+ if (list != null && list.isEmpty() == false) {
+ for (String id : Splitter.on(',').trimResults().omitEmptyStrings().split(list)) {
+ String url = urlPath + "?id=" + id;
+ logger.info("Policy URL for " + id + ": " + url);
+ policies.setProperty(id + ".url", url);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response)
+ */
+ protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ XACMLRest.dumpRequest(request);
+ //
+ // since getParameter reads the content string, explicitly get the content before doing that.
+ // Simply getting the inputStream seems to protect it against being consumed by getParameter.
+ //
+ request.getInputStream();
+ //
+ // See if this is Admin Console registering itself with us
+ //
+ String acURLString = request.getParameter("adminConsoleURL");
+ if (acURLString != null) {
+ //
+ // remember this Admin Console for future updates
+ //
+ if ( ! adminConsoleURLStringList.contains(acURLString)) {
+ adminConsoleURLStringList.add(acURLString);
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("Admin Console registering with URL: " + acURLString);
+ }
+ response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+ return;
+ }
+ //
+ // Is this some other operation from the Admin Console?
+ //
+ String groupId = request.getParameter("groupId");
+ if (groupId != null) {
+ //
+ // this is from the Admin Console, so handle separately
+ //
+ doACPut(request, response, groupId);
+ return;
+ }
+ //
+ // We do not expect anything from anywhere else.
+ // This method is here in case we ever need to support other operations.
+ //
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Request does not have groupId");
+ }
+
+ /**
+ * @see HttpServlet#doDelete(HttpServletRequest request, HttpServletResponse response)
+ */
+ protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ XACMLRest.dumpRequest(request);
+ //
+ // Is this from the Admin Console?
+ //
+ String groupId = request.getParameter("groupId");
+ if (groupId != null) {
+ //
+ // this is from the Admin Console, so handle separately
+ //
+ doACDelete(request, response, groupId);
+ return;
+ }
+ //
+ // We do not expect anything from anywhere else.
+ // This method is here in case we ever need to support other operations.
+ //
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Request does not have groupId");
+ }
+ //
+ // Admin Console request handling
+ //
+
+ /**
+ * Requests from the Admin Console to GET info about the Groups and PDPs
+ *
+ * @param request
+ * @param response
+ * @param groupId
+ * @throws ServletException
+ * @throws java.io.IOException
+ */
+ private void doACGet(HttpServletRequest request, HttpServletResponse response, String groupId) throws ServletException, IOException {
+ try {
+ String parameterDefault = request.getParameter("default");
+ String pdpId = request.getParameter("pdpId");
+ String pdpGroup = request.getParameter("getPDPGroup");
+ if ("".equals(groupId)) {
+ // request IS from AC but does not identify a group by name
+ if (parameterDefault != null) {
+ // Request is for the Default group (whatever its id)
+ PDPGroup group = papEngine.getDefaultGroup();
+
+ // convert response object to JSON and include in the response
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.writeValue(response.getOutputStream(), group);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("GET Default group req from '" + request.getRequestURL() + "'");
+ }
+ response.setStatus(HttpServletResponse.SC_OK);
+ response.setHeader("content-type", "application/json");
+ response.getOutputStream().close();
+ return;
+
+ } else if (pdpId != null) {
+ // Request is related to a PDP
+ if (pdpGroup == null) {
+ // Request is for the PDP itself
+ // Request is for the (unspecified) group containing a given PDP
+ PDP pdp = papEngine.getPDP(pdpId);
+
+ // convert response object to JSON and include in the response
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.writeValue(response.getOutputStream(), pdp);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("GET pdp '" + pdpId + "' req from '" + request.getRequestURL() + "'");
+ }
+ response.setStatus(HttpServletResponse.SC_OK);
+ response.setHeader("content-type", "application/json");
+ response.getOutputStream().close();
+ return;
+
+ } else {
+ // Request is for the (unspecified) group containing a given PDP
+ PDP pdp = papEngine.getPDP(pdpId);
+ PDPGroup group = papEngine.getPDPGroup(pdp);
+
+ // convert response object to JSON and include in the response
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.writeValue(response.getOutputStream(), group);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("GET PDP '" + pdpId + "' Group req from '" + request.getRequestURL() + "'");
+ }
+ response.setStatus(HttpServletResponse.SC_OK);
+ response.setHeader("content-type", "application/json");
+ response.getOutputStream().close();
+ return;
+ }
+
+ } else {
+ // request is for top-level properties about all groups
+ Set<PDPGroup> groups = papEngine.getPDPGroups();
+
+ // convert response object to JSON and include in the response
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.writeValue(response.getOutputStream(), groups);
+
+//TODO
+// In "notification" section, ALSO need to tell AC about other changes (made by other ACs)?'
+//TODO add new PDP notification (or just "config changed" notification) in appropriate place
+ if (logger.isDebugEnabled()) {
+ logger.debug("GET All groups req");
+ }
+ response.setStatus(HttpServletResponse.SC_OK);
+ response.setHeader("content-type", "application/json");
+ response.getOutputStream().close();
+ return;
+ }
+ }
+
+ // for all other GET operations the group must exist before the operation can be done
+ PDPGroup group = papEngine.getGroup(groupId);
+ if (group == null) {
+ logger.error("Unknown groupId '" + groupId + "'");
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId +"'");
+ return;
+ }
+
+
+ // Figure out which request this is based on the parameters
+ String policyId = request.getParameter("policyId");
+
+ if (policyId != null) {
+// // retrieve a policy
+// PDPPolicy policy = papEngine.getPDPPolicy(policyId);
+//
+// // convert response object to JSON and include in the response
+// ObjectMapper mapper = new ObjectMapper();
+// mapper.writeValue(response.getOutputStream(), pdp);
+//
+// logger.debug("GET group '" + group.getId() + "' req from '" + request.getRequestURL() + "'");
+// response.setStatus(HttpServletResponse.SC_OK);
+// response.setHeader("content-type", "application/json");
+// response.getOutputStream().close();
+// return;
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "GET Policy not implemented");
+
+ } else {
+ // No other parameters, so return the identified Group
+
+ // convert response object to JSON and include in the response
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.writeValue(response.getOutputStream(), group);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("GET group '" + group.getId() + "' req from '" + request.getRequestURL() + "'");
+ }
+ response.setStatus(HttpServletResponse.SC_OK);
+ response.setHeader("content-type", "application/json");
+ response.getOutputStream().close();
+ return;
+ }
+
+ //
+ // Currently there are no other GET calls from the AC.
+ // The AC uses the "GET All Groups" operation to fill its local cache and uses that cache for all other GETs without calling the PAP.
+ // Other GETs that could be called:
+ // Specific Group (groupId=<groupId>)
+ // A Policy (groupId=<groupId> policyId=<policyId>)
+ // A PDP (groupId=<groupId> pdpId=<pdpId>)
+
+ //TODO - implement other GET operations if needed
+
+ logger.error("UNIMPLEMENTED ");
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
+ } catch (PAPException e) {
+ logger.error("AC Get exception: " + e, e);
+ response.sendError(500, e.getMessage());
+ return;
+ }
+
+ }
+
+
+ /**
+ * Requests from the Admin Console for operations not on single specific objects
+ *
+ * @param request
+ * @param response
+ * @param groupId
+ * @throws ServletException
+ * @throws java.io.IOException
+ */
+ private void doACPost(HttpServletRequest request, HttpServletResponse response, String groupId) throws ServletException, IOException {
+ try {
+ String groupName = request.getParameter("groupName");
+ String groupDescription = request.getParameter("groupDescription");
+ if (groupName != null && groupDescription != null) {
+ // Args: group=<groupId> groupName=<name> groupDescription=<description> <= create a new group
+ String unescapedName = URLDecoder.decode(groupName, "UTF-8");
+ String unescapedDescription = URLDecoder.decode(groupDescription, "UTF-8");
+ try {
+ papEngine.newGroup(unescapedName, unescapedDescription);
+ } catch (Exception e) {
+ logger.error("Unable to create new group: " + e.getLocalizedMessage());
+ response.sendError(500, "Unable to create new group '" + groupId + "'");
+ return;
+ }
+ response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+ if (logger.isDebugEnabled()) {
+ logger.debug("New Group '" + groupId + "' created");
+ }
+ // tell the Admin Consoles there is a change
+ notifyAC();
+ // new group by definition has no PDPs, so no need to notify them of changes
+ return;
+ }
+
+ // for all remaining POST operations the group must exist before the operation can be done
+ PDPGroup group = papEngine.getGroup(groupId);
+ if (group == null) {
+ logger.error("Unknown groupId '" + groupId + "'");
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId +"'");
+ return;
+ }
+
+ // determine the operation needed based on the parameters in the request
+ if (request.getParameter("policyId") != null) {
+ // Args: group=<groupId> policy=<policyId> <= copy file
+ // copy a policy from the request contents into a file in the group's directory on this machine
+ String policyId = request.getParameter("policyId");
+ try {
+ ((StdPDPGroup) group).copyPolicyToFile(policyId, request.getInputStream());
+ } catch (Exception e) {
+ String message = "Policy '" + policyId + "' not copied to group '" + groupId +"': " + e;
+ logger.error(message);
+ response.sendError(500, message);
+ return;
+ }
+ // policy file copied ok
+ response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+ if (logger.isDebugEnabled()) {
+ logger.debug("policy '" + policyId + "' copied to directory for group '" + groupId + "'");
+ }
+ return;
+
+ } else if (request.getParameter("default") != null) {
+ // Args: group=<groupId> default=true <= make default
+ // change the current default group to be the one identified in the request.
+ //
+ // This is a POST operation rather than a PUT "update group" because of the side-effect that the current default group is also changed.
+ // It should never be the case that multiple groups are currently marked as the default, but protect against that anyway.
+ try {
+ papEngine.SetDefaultGroup(group);
+ } catch (Exception e) {
+ logger.error("Unable to set group: " + e.getLocalizedMessage());
+ response.sendError(500, "Unable to set group '" + groupId + "' to default");
+ return;
+ }
+
+ response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Group '" + groupId + "' set to be default");
+ }
+ // Notify the Admin Consoles that something changed
+ // For now the AC cannot handle anything more detailed than the whole set of PDPGroups, so just notify on that
+//TODO - Future: FIGURE OUT WHAT LEVEL TO NOTIFY: 2 groups or entire set - currently notify AC to update whole configuration of all groups
+ notifyAC();
+ // This does not affect any PDPs in the existing groups, so no need to notify them of this change
+ return;
+
+ } else if (request.getParameter("pdpId") != null) {
+ // Args: group=<groupId> pdpId=<pdpId> <= move PDP to group
+ String pdpId = request.getParameter("pdpId");
+ PDP pdp = papEngine.getPDP(pdpId);
+
+ PDPGroup originalGroup = papEngine.getPDPGroup(pdp);
+
+ papEngine.movePDP(pdp, group);
+
+ response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+ if (logger.isDebugEnabled()) {
+ logger.debug("PDP '" + pdp.getId() +"' moved to group '" + group.getId() + "' set to be default");
+ }
+
+ // update the status of both the original group and the new one
+ ((StdPDPGroup)originalGroup).resetStatus();
+ ((StdPDPGroup)group).resetStatus();
+
+ // Notify the Admin Consoles that something changed
+ // For now the AC cannot handle anything more detailed than the whole set of PDPGroups, so just notify on that
+ notifyAC();
+ // Need to notify the PDP that it's config may have changed
+ pdpChanged(pdp);
+ return;
+
+
+ }
+ } catch (PAPException e) {
+ logger.error("AC POST exception: " + e, e);
+ response.sendError(500, e.getMessage());
+ return;
+ }
+ }
+
+ /**
+ * Requests from the Admin Console to create new items or update existing ones
+ *
+ * @param request
+ * @param response
+ * @param groupId
+ * @throws ServletException
+ * @throws java.io.IOException
+ */
+ private void doACPut(HttpServletRequest request, HttpServletResponse response, String groupId) throws ServletException, IOException {
+ try {
+
+
+ // for PUT operations the group may or may not need to exist before the operation can be done
+ PDPGroup group = papEngine.getGroup(groupId);
+
+ // determine the operation needed based on the parameters in the request
+
+ // for remaining operations the group must exist before the operation can be done
+ if (group == null) {
+ logger.error("Unknown groupId '" + groupId + "'");
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId +"'");
+ return;
+ }
+ if (request.getParameter("policy") != null) {
+ // group=<groupId> policy=<policyId> contents=policy file <= Create new policy file in group dir, or replace it if it already exists (do not touch properties)
+ //TODO - currently this is done by the AC, but it should be done here by getting the policy file out of the contents and saving to disk
+ logger.error("PARTIALLY IMPLEMENTED!!! ACTUAL CHANGES SHOULD BE MADE BY PAP SERVLET!!! ");
+ response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+ return;
+ } else if (request.getParameter("pdpId") != null) {
+ // ARGS: group=<groupId> pdpId=<pdpId/URL> <= create a new PDP or Update an Existing one
+
+ String pdpId = request.getParameter("pdpId");
+
+ // get the request content into a String
+ String json = null;
+ // read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
+ java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
+ scanner.useDelimiter("\\A");
+ json = scanner.hasNext() ? scanner.next() : "";
+ scanner.close();
+ logger.info("JSON request from AC: " + json);
+
+ // convert Object sent as JSON into local object
+ ObjectMapper mapper = new ObjectMapper();
+
+ Object objectFromJSON = mapper.readValue(json, StdPDP.class);
+
+ if (pdpId == null ||
+ objectFromJSON == null ||
+ ! (objectFromJSON instanceof StdPDP) ||
+ ((StdPDP)objectFromJSON).getId() == null ||
+ ! ((StdPDP)objectFromJSON).getId().equals(pdpId)) {
+ logger.error("PDP new/update had bad input. pdpId=" + pdpId + " objectFromJSON="+objectFromJSON);
+ response.sendError(500, "Bad input, pdpid="+pdpId+" object="+objectFromJSON);
+ }
+ StdPDP pdp = (StdPDP) objectFromJSON;
+
+ if (papEngine.getPDP(pdpId) == null) {
+ // this is a request to create a new PDP object
+ papEngine.newPDP(pdp.getId(), group, pdp.getName(), pdp.getDescription());
+ } else {
+ // this is a request to update the pdp
+ papEngine.updatePDP(pdp);
+ }
+
+ response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+ if (logger.isDebugEnabled()) {
+ logger.debug("PDP '" + pdpId + "' created/updated");
+ }
+
+ // adjust the group's state including the new PDP
+ ((StdPDPGroup)group).resetStatus();
+
+ // tell the Admin Consoles there is a change
+ notifyAC();
+ // this might affect the PDP, so notify it of the change
+ pdpChanged(pdp);
+ return;
+ } else if (request.getParameter("pipId") != null) {
+ // group=<groupId> pipId=<pipEngineId> contents=pip properties <= add a PIP to pip config, or replace it if it already exists (lenient operation)
+ //TODO
+ logger.error("UNIMPLEMENTED ");
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
+ return;
+ } else {
+ // Assume that this is an update of an existing PDP Group
+ // ARGS: group=<groupId> <= Update an Existing Group
+
+ // get the request content into a String
+ String json = null;
+ // read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
+ java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
+ scanner.useDelimiter("\\A");
+ json = scanner.hasNext() ? scanner.next() : "";
+ scanner.close();
+ logger.info("JSON request from AC: " + json);
+
+ // convert Object sent as JSON into local object
+ ObjectMapper mapper = new ObjectMapper();
+
+ Object objectFromJSON = mapper.readValue(json, StdPDPGroup.class);
+
+ if (objectFromJSON == null ||
+ ! (objectFromJSON instanceof StdPDPGroup) ||
+ ! ((StdPDPGroup)objectFromJSON).getId().equals(group.getId())) {
+ logger.error("Group update had bad input. id=" + group.getId() + " objectFromJSON="+objectFromJSON);
+ response.sendError(500, "Bad input, id="+group.getId() +" object="+objectFromJSON);
+ }
+
+ // The Path on the PAP side is not carried on the RESTful interface with the AC
+ // (because it is local to the PAP)
+ // so we need to fill that in before submitting the group for update
+ ((StdPDPGroup)objectFromJSON).setDirectory(((StdPDPGroup)group).getDirectory());
+
+ papEngine.updateGroup((StdPDPGroup)objectFromJSON);
+
+
+ response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Group '" + group.getId() + "' updated");
+ }
+ // tell the Admin Consoles there is a change
+ notifyAC();
+ // Group changed, which might include changing the policies
+ groupChanged(group);
+ return;
+ }
+ } catch (PAPException e) {
+ logger.error("AC PUT exception: " + e, e);
+ response.sendError(500, e.getMessage());
+ return;
+ }
+ }
+
+ /**
+ * Requests from the Admin Console to delete/remove items
+ *
+ * @param request
+ * @param response
+ * @param groupId
+ * @throws ServletException
+ * @throws java.io.IOException
+ */
+ private void doACDelete(HttpServletRequest request, HttpServletResponse response, String groupId) throws ServletException, IOException {
+ try {
+ // for all DELETE operations the group must exist before the operation can be done
+ PDPGroup group = papEngine.getGroup(groupId);
+ if (group == null) {
+ logger.error("Unknown groupId '" + groupId + "'");
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId +"'");
+ return;
+ }
+ // determine the operation needed based on the parameters in the request
+ if (request.getParameter("policy") != null) {
+ // group=<groupId> policy=<policyId> [delete=<true|false>] <= delete policy file from group
+ //TODO
+ logger.error("UNIMPLEMENTED ");
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
+ return;
+ } else if (request.getParameter("pdpId") != null) {
+ // ARGS: group=<groupId> pdpId=<pdpId> <= delete PDP
+ String pdpId = request.getParameter("pdpId");
+ PDP pdp = papEngine.getPDP(pdpId);
+
+ papEngine.removePDP(pdp);
+
+ // adjust the status of the group, which may have changed when we removed this PDP
+ ((StdPDPGroup)group).resetStatus();
+
+ response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+ notifyAC();
+
+ // update the PDP and tell it that it has NO Policies (which prevents it from serving PEP Requests)
+ pdpChanged(pdp);
+ return;
+ } else if (request.getParameter("pipId") != null) {
+ // group=<groupId> pipId=<pipEngineId> <= delete PIP config for given engine
+ //TODO
+ logger.error("UNIMPLEMENTED ");
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
+ return;
+ } else {
+ // ARGS: group=<groupId> movePDPsToGroupId=<movePDPsToGroupId> <= delete a group and move all its PDPs to the given group
+ String moveToGroupId = request.getParameter("movePDPsToGroupId");
+ PDPGroup moveToGroup = null;
+ if (moveToGroupId != null) {
+ moveToGroup = papEngine.getGroup(moveToGroupId);
+ }
+
+ // get list of PDPs in the group being deleted so we can notify them that they got changed
+ Set<PDP> movedPDPs = new HashSet<PDP>();
+ movedPDPs.addAll(group.getPdps());
+
+ // do the move/remove
+ papEngine.removeGroup(group, moveToGroup);
+
+ response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+ notifyAC();
+ // notify any PDPs in the removed set that their config may have changed
+ for (PDP pdp : movedPDPs) {
+ pdpChanged(pdp);
+ }
+ return;
+ }
+
+ } catch (PAPException e) {
+ logger.error("AC DELETE exception: " + e, e);
+ response.sendError(500, e.getMessage());
+ return;
+ }
+ }
+
+ //
+ // Heartbeat thread - periodically check on PDPs' status
+ //
+
+ /**
+ * Heartbeat with all known PDPs.
+ *
+ * Implementation note:
+ *
+ * The PDPs are contacted Sequentially, not in Parallel.
+ *
+ * If we did this in parallel using multiple threads we would simultaneously use
+ * - 1 thread and
+ * - 1 connection
+ * for EACH PDP.
+ * This could become a resource problem since we already use multiple threads and connections for updating the PDPs
+ * when user changes occur.
+ * Using separate threads can also make it tricky dealing with timeouts on PDPs that are non-responsive.
+ *
+ * The Sequential operation does a heartbeat request to each PDP one at a time.
+ * This has the flaw that any PDPs that do not respond will hold up the entire heartbeat sequence until they timeout.
+ * If there are a lot of non-responsive PDPs and the timeout is large-ish (the default is 20 seconds)
+ * it could take a long time to cycle through all of the PDPs.
+ * That means that this may not notice a PDP being down in a predictable time.
+ *
+ * @author glenngriffin
+ *
+ */
+ private class Heartbeat implements Runnable {
+ private PAPEngine papEngine;
+ private Set<PDP> pdps = new HashSet<PDP>();
+ private int heartbeatInterval;
+ private int heartbeatTimeout;
+
+ public volatile boolean isRunning = false;
+
+ public synchronized boolean isRunning() {
+ return this.isRunning;
+ }
+
+ public synchronized void terminate() {
+ this.isRunning = false;
+ }
+
+ public Heartbeat(PAPEngine engine) {
+ this.papEngine = engine;
+ this.heartbeatInterval = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_HEARTBEAT_INTERVAL, "10000"));
+ this.heartbeatTimeout = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_HEARTBEAT_TIMEOUT, "10000"));
+ }
+
+ @Override
+ public void run() {
+ //
+ // Set ourselves as running
+ //
+ synchronized(this) {
+ this.isRunning = true;
+ }
+ HashMap<String, URL> idToURLMap = new HashMap<String, URL>();
+ try {
+ while (this.isRunning()) {
+ // Wait the given time
+ Thread.sleep(heartbeatInterval);
+
+ // get the list of PDPs (may have changed since last time)
+ pdps.clear();
+ synchronized(papEngine) {
+ try {
+ for (PDPGroup g : papEngine.getPDPGroups()) {
+ for (PDP p : g.getPdps()) {
+ pdps.add(p);
+ }
+ }
+ } catch (PAPException e) {
+ logger.error("Heartbeat unable to read PDPs from PAPEngine: " + e.getMessage(), e);
+ }
+ }
+ //
+ // Check for shutdown
+ //
+ if (this.isRunning() == false) {
+ logger.info("isRunning is false, getting out of loop.");
+ break;
+ }
+
+ // try to get the summary status from each PDP
+ boolean changeSeen = false;
+ for (PDP pdp : pdps) {
+ //
+ // Check for shutdown
+ //
+ if (this.isRunning() == false) {
+ logger.info("isRunning is false, getting out of loop.");
+ break;
+ }
+ // the id of the PDP is its url (though we add a query parameter)
+ URL pdpURL = idToURLMap.get(pdp.getId());
+ if (pdpURL == null) {
+ // haven't seen this PDP before
+ String fullURLString = null;
+ try {
+ fullURLString = pdp.getId() + "?type=hb";
+ pdpURL = new URL(fullURLString);
+ idToURLMap.put(pdp.getId(), pdpURL);
+ } catch (MalformedURLException e) {
+ logger.error("PDP id '" + fullURLString + "' is not a valid URL: " + e, e);
+ continue;
+ }
+ }
+
+ // Do a GET with type HeartBeat
+ String newStatus = "";
+
+ HttpURLConnection connection = null;
+ try {
+
+ //
+ // Open up the connection
+ //
+ connection = (HttpURLConnection)pdpURL.openConnection();
+ //
+ // Setup our method and headers
+ //
+ connection.setRequestMethod("GET");
+ connection.setConnectTimeout(heartbeatTimeout);
+ //
+ // Do the connect
+ //
+ connection.connect();
+ if (connection.getResponseCode() == 204) {
+ newStatus = connection.getHeaderField(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Heartbeat '" + pdp.getId() + "' status='" + newStatus + "'");
+ }
+ } else {
+ // anything else is an unexpected result
+ newStatus = PDPStatus.Status.UNKNOWN.toString();
+ logger.error("Heartbeat connect response code " + connection.getResponseCode() + ": " + pdp.getId());
+ }
+ } catch (UnknownHostException e) {
+ newStatus = PDPStatus.Status.NO_SUCH_HOST.toString();
+ logger.error("Heartbeat '" + pdp.getId() + "' NO_SUCH_HOST");
+ } catch (SocketTimeoutException e) {
+ newStatus = PDPStatus.Status.CANNOT_CONNECT.toString();
+ logger.error("Heartbeat '" + pdp.getId() + "' connection timeout: " + e );
+ } catch (ConnectException e) {
+ newStatus = PDPStatus.Status.CANNOT_CONNECT.toString();
+ logger.error("Heartbeat '" + pdp.getId() + "' cannot connect: " + e );
+ } catch (Exception e) {
+ newStatus = PDPStatus.Status.UNKNOWN.toString();
+ logger.error("Heartbeat '" + pdp.getId() + "' connect exception: " + e, e);
+ } finally {
+ // cleanup the connection
+ connection.disconnect();
+ }
+
+ if ( ! pdp.getStatus().getStatus().toString().equals(newStatus)) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("previous status='" + pdp.getStatus().getStatus()+"' new Status='" + newStatus + "'");
+ }
+ try {
+ setPDPSummaryStatus(pdp, newStatus);
+ } catch (PAPException e) {
+ logger.error("Unable to set state for PDP '" + pdp.getId() + "': " + e, e);
+ }
+ changeSeen = true;
+ }
+
+ }
+ //
+ // Check for shutdown
+ //
+ if (this.isRunning() == false) {
+ logger.info("isRunning is false, getting out of loop.");
+ break;
+ }
+
+ // if any of the PDPs changed state, tell the ACs to update
+ if (changeSeen) {
+ notifyAC();
+ }
+
+ }
+ } catch (InterruptedException e) {
+ logger.error("Heartbeat interrupted. Shutting down");
+ this.terminate();
+ }
+ }
+ }
+
+
+ //
+ // HELPER to change Group status when PDP status is changed
+ //
+ // (Must NOT be called from a method that is synchronized on the papEngine or it may deadlock)
+ //
+
+ private void setPDPSummaryStatus(PDP pdp, PDPStatus.Status newStatus) throws PAPException {
+ setPDPSummaryStatus(pdp, newStatus.toString());
+ }
+
+ private void setPDPSummaryStatus(PDP pdp, String newStatus) throws PAPException {
+ synchronized(papEngine) {
+ StdPDPStatus status = (StdPDPStatus)pdp.getStatus();
+ status.setStatus(PDPStatus.Status.valueOf(newStatus));
+ ((StdPDP)pdp).setStatus(status);
+
+ // now adjust the group
+ StdPDPGroup group = (StdPDPGroup)papEngine.getPDPGroup(pdp);
+ // if the PDP was just deleted it may transiently exist but not be in a group
+ if (group != null) {
+ group.resetStatus();
+ }
+ }
+ }
+
+
+ //
+ // Callback methods telling this servlet to notify PDPs of changes made by the PAP StdEngine
+ // in the PDP group directories
+ //
+
+ @Override
+ public void changed() {
+ // all PDPs in all groups need to be updated/sync'd
+ Set<PDPGroup> groups;
+ try {
+ groups = papEngine.getPDPGroups();
+ } catch (PAPException e) {
+ logger.error("getPDPGroups failed: " + e.getLocalizedMessage());
+ throw new RuntimeException("Unable to get Groups: " + e);
+ }
+ for (PDPGroup group : groups) {
+ groupChanged(group);
+ }
+ }
+
+ @Override
+ public void groupChanged(PDPGroup group) {
+ // all PDPs within one group need to be updated/sync'd
+ for (PDP pdp : group.getPdps()) {
+ pdpChanged(pdp);
+ }
+ }
+
+ @Override
+ public void pdpChanged(PDP pdp) {
+ // kick off a thread to do an event notification for each PDP.
+ // This needs to be on a separate thread so that PDPs that do not respond (down, non-existent, etc)
+ // do not block the PSP response to the AC, which would freeze the GUI until all PDPs sequentially respond or time-out.
+ Thread t = new Thread(new UpdatePDPThread(pdp));
+ t.start();
+ }
+
+ private class UpdatePDPThread implements Runnable {
+ private PDP pdp;
+
+ // remember which PDP to notify
+ public UpdatePDPThread(PDP pdp) {
+ this.pdp = pdp;
+ }
+
+ public void run() {
+ // send the current configuration to one PDP
+ HttpURLConnection connection = null;
+ try {
+
+ //
+ // the Id of the PDP is its URL
+ //
+ if (logger.isDebugEnabled()) {
+ logger.debug("creating url for id '" + pdp.getId() + "'");
+ }
+ //TODO - currently always send both policies and pips. Do we care enough to add code to allow sending just one or the other?
+ //TODO (need to change "cache=", implying getting some input saying which to change)
+ URL url = new URL(pdp.getId() + "?cache=all");
+
+ //
+ // Open up the connection
+ //
+ connection = (HttpURLConnection)url.openConnection();
+ //
+ // Setup our method and headers
+ //
+ connection.setRequestMethod("PUT");
+ // connection.setRequestProperty("Accept", "text/x-java-properties");
+ connection.setRequestProperty("Content-Type", "text/x-java-properties");
+ // connection.setUseCaches(false);
+ //
+ // Adding this in. It seems the HttpUrlConnection class does NOT
+ // properly forward our headers for POST re-direction. It does so
+ // for a GET re-direction.
+ //
+ // So we need to handle this ourselves.
+ //
+ //TODO - is this needed for a PUT? seems better to leave in for now?
+// connection.setInstanceFollowRedirects(false);
+ //
+ // PLD - MUST be able to handle re-directs.
+ //
+ connection.setInstanceFollowRedirects(true);
+ connection.setDoOutput(true);
+ // connection.setDoInput(true);
+ try (OutputStream os = connection.getOutputStream()) {
+
+ PDPGroup group = papEngine.getPDPGroup(pdp);
+ // if the PDP was just deleted, there is no group, but we want to send an update anyway
+ if (group == null) {
+ // create blank properties files
+ Properties policyProperties = new Properties();
+ policyProperties.put(XACMLProperties.PROP_ROOTPOLICIES, "");
+ policyProperties.put(XACMLProperties.PROP_REFERENCEDPOLICIES, "");
+ policyProperties.store(os, "");
+
+ Properties pipProps = new Properties();
+ pipProps.setProperty(XACMLProperties.PROP_PIP_ENGINES, "");
+ pipProps.store(os, "");
+
+ } else {
+ // send properties from the current group
+ group.getPolicyProperties().store(os, "");
+ Properties policyLocations = new Properties();
+ for (PDPPolicy policy : group.getPolicies()) {
+ policyLocations.put(policy.getId() + ".url", XACMLPapServlet.papURL + "?id=" + policy.getId());
+ }
+ policyLocations.store(os, "");
+ group.getPipConfigProperties().store(os, "");
+ }
+
+ } catch (Exception e) {
+ logger.error("Failed to send property file to " + pdp.getId(), e);
+ // Since this is a server-side error, it probably does not reflect a problem on the client,
+ // so do not change the PDP status.
+ return;
+ }
+ //
+ // Do the connect
+ //
+ connection.connect();
+ if (connection.getResponseCode() == 204) {
+ logger.info("Success. We are configured correctly.");
+ setPDPSummaryStatus(pdp, PDPStatus.Status.UP_TO_DATE);
+ } else if (connection.getResponseCode() == 200) {
+ logger.info("Success. PDP needs to update its configuration.");
+ setPDPSummaryStatus(pdp, PDPStatus.Status.OUT_OF_SYNCH);
+ } else {
+ logger.warn("Failed: " + connection.getResponseCode() + " message: " + connection.getResponseMessage());
+ setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN);
+ }
+ } catch (Exception e) {
+ logger.error("Unable to sync config with PDP '" + pdp.getId() + "': " + e, e);
+ try {
+ setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN);
+ } catch (PAPException e1) {
+ logger.error("Unable to set status of PDP '" + pdp.getId() + "' to UNKNOWN: " + e, e);
+ }
+ } finally {
+ // cleanup the connection
+ connection.disconnect();
+
+ // tell the AC to update it's status info
+ notifyAC();
+ }
+
+ }
+ }
+
+ //
+ // RESTful Interface from PAP to ACs notifying them of changes
+ //
+
+ private void notifyAC() {
+ // kick off a thread to do one event notification for all registered ACs
+ // This needs to be on a separate thread so that ACs can make calls back to PAP to get the updated Group data
+ // as part of processing this message on their end.
+ Thread t = new Thread(new NotifyACThread());
+ t.start();
+ }
+
+ private class NotifyACThread implements Runnable {
+
+ public void run() {
+ List<String> disconnectedACs = new ArrayList<String>();
+// logger.debug("LIST SIZE="+adminConsoleURLStringList.size());
+
+ // There should be no Concurrent exception here because the list is a CopyOnWriteArrayList.
+ // The "for each" loop uses the collection's iterator under the covers, so it should be correct.
+ for (String acURL : adminConsoleURLStringList) {
+ HttpURLConnection connection = null;
+ try {
+
+ acURL += "?PAPNotification=true";
+
+//TODO - Currently we just tell AC that "Something changed" without being specific. Do we want to tell it which group/pdp changed?
+//TODO - If so, put correct parameters into the Query string here
+ acURL += "&objectType=all" + "&action=update";
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("creating url for id '" + acURL + "'");
+ }
+//TODO - currently always send both policies and pips. Do we care enough to add code to allow sending just one or the other?
+//TODO (need to change "cache=", implying getting some input saying which to change)
+
+ URL url = new URL(acURL );
+
+ //
+ // Open up the connection
+ //
+ connection = (HttpURLConnection)url.openConnection();
+ //
+ // Setup our method and headers
+ //
+ connection.setRequestMethod("PUT");
+ connection.setRequestProperty("Content-Type", "text/x-java-properties");
+ //
+ // Adding this in. It seems the HttpUrlConnection class does NOT
+ // properly forward our headers for POST re-direction. It does so
+ // for a GET re-direction.
+ //
+ // So we need to handle this ourselves.
+ //
+ //TODO - is this needed for a PUT? seems better to leave in for now?
+ connection.setInstanceFollowRedirects(false);
+ //
+ // Do not include any data in the PUT because this is just a
+ // notification to the AC.
+ // The AC will use GETs back to the PAP to get what it needs
+ // to fill in the screens.
+ //
+
+ //
+ // Do the connect
+ //
+ connection.connect();
+ if (connection.getResponseCode() == 204) {
+ logger.info("Success. We updated correctly.");
+ } else {
+ logger.warn("Failed: " + connection.getResponseCode() + " message: " + connection.getResponseMessage());
+ }
+
+ } catch (Exception e) {
+ logger.error("Unable to sync config AC '" + acURL + "': " + e, e);
+ disconnectedACs.add(acURL);
+ } finally {
+ // cleanup the connection
+ connection.disconnect();
+ }
+ }
+
+ // remove any ACs that are no longer connected
+ if (disconnectedACs.size() > 0) {
+ adminConsoleURLStringList.removeAll(disconnectedACs);
+ }
+
+ }
+ }
+
+}
diff --git a/openaz-xacml-pap-rest/src/main/resources/log4j.properties b/openaz-xacml-pap-rest/src/main/resources/log4j.properties
new file mode 100755
index 0000000..b45fa2f
--- /dev/null
+++ b/openaz-xacml-pap-rest/src/main/resources/log4j.properties
@@ -0,0 +1,22 @@
+#
+# Use this properties for debugging and development.
+#
+#
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=DEBUG, MAIN_LOG
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.MAIN_LOG=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.MAIN_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.MAIN_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n
+
+#
+# This is specifically for Xacml request/response logging
+#
+log4j.logger.xacml.request=INFO, REQUEST_LOG
+
+log4j.appender.REQUEST_LOG=org.apache.log4j.ConsoleAppender
+log4j.appender.REQUEST_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.REQUEST_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} %m%n
\ No newline at end of file
diff --git a/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$1.class b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$1.class
new file mode 100644
index 0000000..352e4c6
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$1.class
Binary files differ
diff --git a/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$Heartbeat.class b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$Heartbeat.class
new file mode 100644
index 0000000..aac4b91
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$Heartbeat.class
Binary files differ
diff --git a/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$NotifyACThread.class b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$NotifyACThread.class
new file mode 100644
index 0000000..3d756fd
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$NotifyACThread.class
Binary files differ
diff --git a/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$UpdatePDPThread.class b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$UpdatePDPThread.class
new file mode 100644
index 0000000..ffd1592
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet$UpdatePDPThread.class
Binary files differ
diff --git a/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet.class b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet.class
new file mode 100644
index 0000000..d8d63b5
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/classes/com/att/research/xacml/rest/XACMLPapServlet.class
Binary files differ
diff --git a/openaz-xacml-pap-rest/target/classes/log4j.properties b/openaz-xacml-pap-rest/target/classes/log4j.properties
new file mode 100644
index 0000000..b45fa2f
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/classes/log4j.properties
@@ -0,0 +1,22 @@
+#
+# Use this properties for debugging and development.
+#
+#
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=DEBUG, MAIN_LOG
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.MAIN_LOG=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.MAIN_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.MAIN_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n
+
+#
+# This is specifically for Xacml request/response logging
+#
+log4j.logger.xacml.request=INFO, REQUEST_LOG
+
+log4j.appender.REQUEST_LOG=org.apache.log4j.ConsoleAppender
+log4j.appender.REQUEST_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.REQUEST_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} %m%n
\ No newline at end of file
diff --git a/openaz-xacml-pap-rest/target/maven-archiver/pom.properties b/openaz-xacml-pap-rest/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..022f696
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Tue Apr 07 07:42:37 EDT 2015
+version=0.0.1-SNAPSHOT
+groupId=org.openliberty.openaz
+artifactId=openaz-xacml-pap-rest
diff --git a/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..4cfb3ef
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,5 @@
+com/att/research/xacml/rest/XACMLPapServlet$Heartbeat.class
+com/att/research/xacml/rest/XACMLPapServlet$1.class
+com/att/research/xacml/rest/XACMLPapServlet.class
+com/att/research/xacml/rest/XACMLPapServlet$UpdatePDPThread.class
+com/att/research/xacml/rest/XACMLPapServlet$NotifyACThread.class
diff --git a/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..9a51391
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1 @@
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pap-rest/src/main/java/com/att/research/xacml/rest/XACMLPapServlet.java
diff --git a/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
diff --git a/openaz-xacml-pap-rest/target/openaz-xacml-pap-rest-0.0.1-SNAPSHOT.jar b/openaz-xacml-pap-rest/target/openaz-xacml-pap-rest-0.0.1-SNAPSHOT.jar
new file mode 100644
index 0000000..d8cdce7
--- /dev/null
+++ b/openaz-xacml-pap-rest/target/openaz-xacml-pap-rest-0.0.1-SNAPSHOT.jar
Binary files differ
diff --git a/openaz-xacml-pap-rest/xacml.pap.properties b/openaz-xacml-pap-rest/xacml.pap.properties
new file mode 100755
index 0000000..05fc0c5
--- /dev/null
+++ b/openaz-xacml-pap-rest/xacml.pap.properties
@@ -0,0 +1,35 @@
+#
+# This is our factory that will create our engine
+#
+xacml.PAP.papEngineFactory=com.att.research.xacml.std.pap.StdEngineFactory
+
+#
+# Where we store our PAP PDP Group/Node information
+#
+xacml.pap.pdps=pdps
+#
+# Need the PAP's url (how PDPs will reach it) configured here
+# because we need it to generate the URLs of the Policy Files
+# sent to the PDPs in the configuration when the PAP is first brought up.
+# (In other cases, such as the PDP calling the PAP, we could generate this URL,
+# but for startup there is no other way to get it.)
+#
+#
+xacml.rest.pap.url=http://localhost:9090/pap/
+
+#
+# Upon startup, have the PAP servlet send latest configuration information to all
+# the PDP nodes it knows about.
+#
+xacml.rest.pap.initiate.pdp=true
+#
+# Heartbeat from PAP to PDPs
+#
+# How much time (in milliseconds) between heartbeats
+# (i.e. the time between completing the heartbeat with all PDPs and starting the next cycle)
+#
+xacml.rest.pap.heartbeat.interval=10000
+#
+# Heartbeat connection timeout (in milliseconds)
+#
+xacml.rest.pap.heartbeat.timeout=10000
\ No newline at end of file
diff --git a/openaz-xacml-pdp-rest/WebContent/META-INF/MANIFEST.MF b/openaz-xacml-pdp-rest/WebContent/META-INF/MANIFEST.MF
new file mode 100755
index 0000000..58630c0
--- /dev/null
+++ b/openaz-xacml-pdp-rest/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/openaz-xacml-pdp-rest/WebContent/WEB-INF/lib/sqljdbc4.jar b/openaz-xacml-pdp-rest/WebContent/WEB-INF/lib/sqljdbc4.jar
new file mode 100755
index 0000000..d6b7f6d
--- /dev/null
+++ b/openaz-xacml-pdp-rest/WebContent/WEB-INF/lib/sqljdbc4.jar
Binary files differ
diff --git a/openaz-xacml-pdp-rest/config/xacml.pip.properties b/openaz-xacml-pdp-rest/config/xacml.pip.properties
new file mode 100755
index 0000000..0c16eb3
--- /dev/null
+++ b/openaz-xacml-pdp-rest/config/xacml.pip.properties
@@ -0,0 +1,219 @@
+# PIP Engine Definition
+#
+xacml.pip.engines=csv1,csv2,hyper1,sql1,ldap1
+
+csv1.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv1.name=Master
+csv1.description=Sean Lahman Basebase stats - Player names, DOB, and biographical info
+csv1.issuer=com:att:research:xacml:test:csv
+csv1.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Master.txt
+csv1.maxsize=4000000
+csv1.delimiter=,
+csv1.quote="
+csv1.skip=0
+
+csv1.resolvers=data
+
+csv1.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv1.resolver.data.name=Player Resolver
+csv1.resolver.data.description=This resolver finds player information in the Master table.
+csv1.resolver.data.fields=firstname,lastname,deathyear,deathmonth,deathday,debut,finalgame
+csv1.resolver.data.field.firstname.column=16
+csv1.resolver.data.field.firstname.id=com:att:research:xacml:test:csv:subject:firstname
+csv1.resolver.data.field.firstname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.firstname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.lastname.column=17
+csv1.resolver.data.field.lastname.id=com:att:research:xacml:test:csv:subject:lastname
+csv1.resolver.data.field.lastname.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.field.lastname.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathyear.column=10
+csv1.resolver.data.field.deathyear.id=com:att:research:xacml:test:csv:subject:deathyear
+csv1.resolver.data.field.deathyear.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathyear.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathmonth.column=11
+csv1.resolver.data.field.deathmonth.id=com:att:research:xacml:test:csv:subject:deathmonth
+csv1.resolver.data.field.deathmonth.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathmonth.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.deathday.column=12
+csv1.resolver.data.field.deathday.id=com:att:research:xacml:test:csv:subject:deathday
+csv1.resolver.data.field.deathday.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv1.resolver.data.field.deathday.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.debut.column=25
+csv1.resolver.data.field.debut.id=com:att:research:xacml:test:csv:subject:debut
+csv1.resolver.data.field.debut.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.debut.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.field.finalgame.column=26
+csv1.resolver.data.field.finalgame.id=com:att:research:xacml:test:csv:subject:finalgame
+csv1.resolver.data.field.finalgame.datatype=http://www.w3.org/2001/XMLSchema#date
+csv1.resolver.data.field.finalgame.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv1.resolver.data.parameters=playerid
+csv1.resolver.data.parameter.playerid.column=1
+csv1.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv1.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv1.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+csv2.classname=com.att.research.xacml.std.pip.engines.csv.CSVEngine
+csv2.name=Appearances
+csv2.description=Sean Lahman Basebase stats - Player appearances for a team in a given year.
+#csv2.issuer=
+csv2.source=../XACML-TEST/testsets/pip/configurable-csv/adminDB/Appearances.txt
+csv2.maxsize=4000000
+csv2.delimiter=,
+csv2.quote="
+csv2.skip=0
+
+csv2.resolvers=data
+
+csv2.resolver.data.classname=com.att.research.xacml.std.pip.engines.csv.ConfigurableCSVResolver
+csv2.resolver.data.name=Appearance Resolver
+csv2.resolver.data.description=This resolver returns all the appearances for a player from the appearance table.
+csv2.resolver.data.fields=appearance
+csv2.resolver.data.field.appearance.column=0
+csv2.resolver.data.field.appearance.id=com:att:research:xacml:test:csv:subject:appearance
+csv2.resolver.data.field.appearance.datatype=http://www.w3.org/2001/XMLSchema#integer
+csv2.resolver.data.field.appearance.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+csv2.resolver.data.field.appearance.issuer=com:att:research:xacml:test:csv
+
+csv2.resolver.data.parameters=playerid
+csv2.resolver.data.parameter.playerid.column=3
+csv2.resolver.data.parameter.playerid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+csv2.resolver.data.parameter.playerid.datatype=http://www.w3.org/2001/XMLSchema#string
+csv2.resolver.data.parameter.playerid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#csv1.resolver.data.parameter.playerid.issuer=
+
+hyper1.classname=com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine
+hyper1.name=World Marriage Age Limits
+hyper1.description=Minimum age for female/male marriages with or without their parental consent.
+hyper1.source=../XACML-TEST/testsets/pip/configurable-csv-hyper/marriage.csv
+hyper1.target=marriage
+hyper1.definition=country VARCHAR(80) PRIMARY KEY, wofemale INT, womale INT, wfemale INT, wmale INT, year INT, source VARCHAR(20)
+
+hyper1.resolvers=age_consent
+
+hyper1.resolver.age_consent.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+hyper1.resolver.age_consent.name=Ages
+hyper1.resolver.age_consent.description=This returns all the age's for consent or no consent for a country.
+hyper1.resolver.age_consent.select=SELECT wofemale,womale,wfemale,wmale FROM marriage WHERE country=?
+hyper1.resolver.age_consent.fields=wofemale,womale,wfemale,wmale
+
+hyper1.resolver.age_consent.field.wofemale.id=com:att:research:xacml:test:csv:country:no-consent:female
+hyper1.resolver.age_consent.field.wofemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wofemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wofemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.womale.id=com:att:research:xacml:test:csv:country:no-consent:male
+hyper1.resolver.age_consent.field.womale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.womale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.womale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wfemale.id=com:att:research:xacml:test:csv:country:consent:female
+hyper1.resolver.age_consent.field.wfemale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wfemale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wfemale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.field.wmale.id=com:att:research:xacml:test:csv:country:consent:male
+hyper1.resolver.age_consent.field.wmale.datatype=http://www.w3.org/2001/XMLSchema#integer
+hyper1.resolver.age_consent.field.wmale.category=com:att:research:xacml:test:csv:category:country
+hyper1.resolver.age_consent.field.wmale.issuer=com:att:research:xacml:test:csv
+
+hyper1.resolver.age_consent.parameters=country
+hyper1.resolver.age_consent.parameter.country.id=com:att:research:xacml:test:csv:country:name
+hyper1.resolver.age_consent.parameter.country.datatype=http://www.w3.org/2001/XMLSchema#string
+hyper1.resolver.age_consent.parameter.country.category=com:att:research:xacml:test:csv:category:country
+#hyper1.resolver.age_consent.parameter.country.issuer=
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data.
+#
+sql1.type=jdbc
+sql1.jdbc.driver=org.postgresql.Driver
+sql1.jdbc.url=jdbc:postgresql://localhost:5432/world
+sql1.jdbc.conn.user=sa
+sql1.jdbc.conn.password=
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the language for a city.
+sql1.resolver.langer.select=SELECT language FROM city INNER JOIN countrylanguage ON city.countrycode = countrylanguage.countrycode WHERE name=?
+sql1.resolver.langer.fields=language
+sql1.resolver.langer.field.language.id=com:att:research:xacml:test:sql:resource:city:language
+sql1.resolver.langer.field.language.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.field.language.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=name
+sql1.resolver.langer.parameter.name.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+sql1.resolver.langer.parameter.name.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.name.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+ldap1.classname=com.att.research.xacml.std.pip.engines.ldap.LDAPEngine
+ldap1.name=LDAP PIP
+ldap1.description=The LDAP containing the seven seas sample LDIF data.
+ldap1.issuer=com:att:research:xacml:test:ldap
+ldap1.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
+#
+# NOTE: You will have to setup a local LDAP server and load the data\apache-ds-tutorial.ldif before
+# this example will work.
+#
+ldap1.java.naming.provider.url=ldap://localhost:10389
+#ldap.java.naming.security.principal=
+#ldap.java.naming.security.credentials=
+ldap1.scope=subtree
+
+ldap1.resolvers=dn,ship
+
+ldap1.resolver.dn.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.dn.name=Domain Names
+ldap1.resolver.dn.description=Find all the dn's for the subject id
+ldap1.resolver.dn.base=o=sevenseas
+ldap1.resolver.dn.base.parameters=
+ldap1.resolver.dn.filter=(|(uid=${uid})(mail=${uid}))
+ldap1.resolver.dn.filter.parameters=uid
+ldap1.resolver.dn.filter.parameters.uid.id=urn:oasis:names:tc:xacml:1.0:subject:subject-id
+ldap1.resolver.dn.filter.parameters.uid.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.parameters.uid.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+#ldap1.resolver.dn.filter.parameters.uid.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.dn.filter.view=dn
+ldap1.resolver.dn.filter.view.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.dn.filter.view.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.dn.filter.view.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.dn.filter.view.dn.issuer=com:att:research:xacml:test:ldap
+
+ldap1.resolver.ship.classname=com.att.research.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver
+ldap1.resolver.ship.name=Ship Resolver
+ldap1.resolver.ship.description=This resolves a subject's dn to a ship.
+ldap1.resolver.ship.base=o=sevenseas
+ldap1.resolver.ship.base.parameters=
+ldap1.resolver.ship.filter=uniquemember=${dn}
+ldap1.resolver.ship.filter.parameters=dn
+ldap1.resolver.ship.filter.parameters.dn.id=com:att:research:xacml:test:ldap:subject:dn
+ldap1.resolver.ship.filter.parameters.dn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.parameters.dn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.parameters.dn.issuer=com:att:research:xacml:test:ldap
+ldap1.resolver.ship.filter.view=cn
+ldap1.resolver.ship.filter.view.cn.id=com:att:research:xacml:test:ldap:subject:ship
+ldap1.resolver.ship.filter.view.cn.datatype=http://www.w3.org/2001/XMLSchema#string
+ldap1.resolver.ship.filter.view.cn.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+ldap1.resolver.ship.filter.view.cn.issuer=com:att:research:xacml:test:ldap
+
diff --git a/openaz-xacml-pdp-rest/config/xacml.policy.properties b/openaz-xacml-pdp-rest/config/xacml.policy.properties
new file mode 100755
index 0000000..d42c84c
--- /dev/null
+++ b/openaz-xacml-pdp-rest/config/xacml.policy.properties
@@ -0,0 +1,8 @@
+xacml.rootPolicies=annotation,ldap,csv,csvhyper,sql
+xacml.referencedPolicies=
+
+annotation.file=../XACML-TEST/testsets/annotation/AnnotationPolicy.v1.xml
+ldap.file=../XACML-TEST/testsets/pip/configurable-ldap/LDAP-Seven-Seas-v1.xml
+csv.file=../XACML-TEST/testsets/pip/configurable-csv/CSV-Baseball-Hall-Of-Fame-v1.xml
+csvhyper.file=../XACML-TEST/testsets/pip/configurable-csv-hyper/CSV-Legal-Age-Marriage-v1.xml
+sql.file=../XACML-TEST/testsets/pip/configurable-sql/SQL-World-Languages-v1.xml
diff --git a/openaz-xacml-pdp-rest/pom.xml b/openaz-xacml-pdp-rest/pom.xml
new file mode 100755
index 0000000..edb97b4
--- /dev/null
+++ b/openaz-xacml-pdp-rest/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>openaz</artifactId>
+ <groupId>org.openliberty.openaz</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>openaz-xacml-pdp-rest</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openliberty.openaz</groupId>
+ <artifactId>openaz-xacml</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.openliberty.openaz</groupId>
+ <artifactId>openaz-xacml-rest</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.openliberty.openaz</groupId>
+ <artifactId>openaz-xacml-pdp</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>postgresql</groupId>
+ <artifactId>postgresql</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java
new file mode 100755
index 0000000..6b44cda
--- /dev/null
+++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java
@@ -0,0 +1,470 @@
+/*
+ * 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) 2014 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacml.rest;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.pap.PAPException;
+import com.att.research.xacml.api.pap.PDPStatus;
+import com.att.research.xacml.api.pap.PDPStatus.Status;
+import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.api.pdp.PDPEngineFactory;
+import com.att.research.xacml.api.pip.PIPEngine;
+import com.att.research.xacml.api.pip.PIPException;
+import com.att.research.xacml.api.pip.PIPFinder;
+import com.att.research.xacml.api.pip.PIPFinderFactory;
+import com.att.research.xacml.std.pap.StdPDPPIPConfig;
+import com.att.research.xacml.std.pap.StdPDPPolicy;
+import com.att.research.xacml.std.pap.StdPDPStatus;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.XACMLProperties;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef;
+import com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory;
+import com.google.common.base.Splitter;
+
+/**
+ * Does the work for loading policy and PIP configurations sent from the PAP servlet.
+ *
+ *
+ * @author pameladragosh
+ *
+ */
+public class XACMLPdpLoader {
+ private static final Log logger = LogFactory.getLog(XACMLPdpLoader.class);
+
+ public static synchronized PDPEngine loadEngine(StdPDPStatus status, Properties policyProperties, Properties pipProperties) {
+ logger.info("loadEngine: " + policyProperties + " "+ pipProperties);
+ //
+ // First load our policies
+ //
+ try {
+ //
+ // Were we given some properties?
+ //
+ if (policyProperties == null) {
+ //
+ // On init we have no incoming configuration, so just
+ // Load our current saved configuration
+ //
+ policyProperties = new Properties();
+ try (InputStream is = Files.newInputStream(getPDPPolicyCache())) {
+ policyProperties.load(is);
+ }
+ }
+
+ //
+ // Get our policy cache up-to-date
+ //
+ // Side effects of this include:
+ // - downloading of policies from remote locations, and
+ // - creating new "<PolicyId>.file" properties for files existing local
+ //
+ XACMLPdpLoader.cachePolicies(policyProperties);
+ //
+ // Validate the policies
+ //
+ XACMLPdpLoader.validatePolicies(policyProperties, status);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Status: " + status);
+ }
+ } catch (Exception e) {
+ String error = "Failed to load Policy Cache properties file: " + e.getMessage();
+ logger.error(error, e);
+ status.addLoadError(error);
+ status.setStatus(PDPStatus.Status.LOAD_ERRORS);
+ }
+ //
+ // Load our PIP configuration
+ //
+ try {
+ //
+ // Were we given some properties to use?
+ //
+ if (pipProperties == null) {
+ //
+ // Load our current saved configuration
+ //
+ pipProperties = new Properties();
+ try (InputStream is = Files.newInputStream(getPIPConfig())) {
+ pipProperties.load(is);
+ }
+ }
+ //
+ // Validate our PIP configurations
+ //
+ XACMLPdpLoader.validatePipConfiguration(pipProperties, status);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Status: " + status);
+ }
+ } catch (Exception e) {
+ String error = "Failed to load/validate Pip Config properties file: " + e.getMessage();
+ logger.error(error, e);
+ status.addLoadError(error);
+ status.setStatus(PDPStatus.Status.LOAD_ERRORS);
+ }
+ //
+ // Were they validated?
+ //
+ if (status.getStatus() == Status.LOAD_ERRORS) {
+ logger.error("there were load errors");
+ return null;
+ }
+ //
+ // Reset our official properties the PDP factory
+ // uses to configure the PDP engine.
+ //
+ XACMLRest.loadXacmlProperties(policyProperties, pipProperties);
+ //
+ // Dump ALL our properties that we are trying to load
+ //
+ try {
+ logger.info(XACMLProperties.getProperties().toString());
+ } catch (IOException e) {
+ logger.error("Failed to get XACML Properties", e);
+ }
+ //
+ // Now load the PDP engine
+ //
+ PDPEngineFactory factory = null;
+ PDPEngine engine = null;
+ try {
+ factory = PDPEngineFactory.newInstance();
+ engine = factory.newEngine();
+ logger.info("Loaded new PDP engine.");
+ status.setStatus(Status.UP_TO_DATE);
+ } catch (FactoryException e) {
+ String error = "Failed to create new PDP Engine";
+ logger.error(error, e);
+ status.addLoadError(error);
+ }
+ return engine;
+ }
+
+ public static synchronized void validatePolicies(Properties properties, StdPDPStatus status) throws PAPException {
+ Set<String> rootPolicies = XACMLProperties.getRootPolicyIDs(properties);
+ Set<String> refPolicies = XACMLProperties.getReferencedPolicyIDs(properties);
+
+ for (String id : rootPolicies) {
+ loadPolicy(properties, status, id, true);
+ }
+ // remember which policies were root policies
+ status.addAllLoadedRootPolicies(status.getLoadedPolicies());
+
+ for (String id : refPolicies) {
+ loadPolicy(properties, status, id, false);
+ }
+
+ logger.info("Loaded " + status.getLoadedPolicies().size() + " policies, failed to load " + status.getFailedPolicies().size() + " policies, " +
+ status.getLoadedRootPolicies().size() + " root policies");
+ if (status.getLoadedRootPolicies().size() == 0) {
+ logger.warn("NO ROOT POLICIES LOADED!!! Cannot serve PEP Requests.");
+ status.addLoadWarning("NO ROOT POLICIES LOADED!!! Cannot serve PEP Requests.");
+ }
+ }
+
+ public static synchronized void loadPolicy(Properties properties, StdPDPStatus status, String id, boolean isRoot) throws PAPException {
+ PolicyDef policy = null;
+ String location = null;
+ URI locationURI = null;
+ boolean isFile = false;
+ try {
+ location = properties.getProperty(id + ".file");
+ if (location == null) {
+ location = properties.getProperty(id + ".url");
+ if (location != null) {
+ //
+ // Construct the URL
+ //
+ locationURI = URI.create(location);
+ URL url = locationURI.toURL();
+ URLConnection urlConnection = url.openConnection();
+ urlConnection.setRequestProperty(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID, XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID));
+ //
+ // Now construct the output file name
+ //
+ Path outFile = Paths.get(getPDPConfig().toAbsolutePath().toString(), id);
+ //
+ // Copy it to disk
+ //
+ try (FileOutputStream fos = new FileOutputStream(outFile.toFile())) {
+ IOUtils.copy(urlConnection.getInputStream(), fos);
+ }
+ //
+ // Now try to load
+ //
+ isFile = true;
+ try (InputStream fis = Files.newInputStream(outFile)) {
+ policy = DOMPolicyDef.load(fis);
+ }
+ //
+ // Save it
+ //
+ properties.setProperty(id + ".file", outFile.toAbsolutePath().toString());
+ }
+ } else {
+ isFile = true;
+ locationURI = Paths.get(location).toUri();
+ try (InputStream is = Files.newInputStream(Paths.get(location))) {
+ policy = DOMPolicyDef.load(is);
+ }
+ }
+ if (policy != null) {
+ status.addLoadedPolicy(new StdPDPPolicy(id, isRoot, locationURI, properties));
+ logger.info("Loaded policy: " + policy.getIdentifier() + " version: " + policy.getVersion().stringValue());
+ } else {
+ String error = "Failed to load policy " + location;
+ logger.error(error);
+ status.setStatus(PDPStatus.Status.LOAD_ERRORS);
+ status.addLoadError(error);
+ status.addFailedPolicy(new StdPDPPolicy(id, isRoot));
+ }
+ } catch (Exception e) {
+ logger.error("Failed to load policy '" + id + "' from location '" + location + "'", e);
+ status.setStatus(PDPStatus.Status.LOAD_ERRORS);
+ status.addFailedPolicy(new StdPDPPolicy(id, isRoot));
+ //
+ // Is it a file?
+ //
+ if (isFile) {
+ //
+ // Let's remove it
+ //
+ try {
+ logger.error("Corrupted policy file, deleting: " + location);
+ Files.delete(Paths.get(location));
+ } catch (IOException e1) {
+ logger.error(e1);
+ }
+ }
+ throw new PAPException("Failed to load policy '" + id + "' from location '" + location + "'");
+ }
+ }
+
+ public static synchronized void validatePipConfiguration(Properties properties, StdPDPStatus status) throws PAPException {
+ try {
+ PIPFinderFactory factory = PIPFinderFactory.newInstance(properties);
+ if (factory == null) {
+ throw new FactoryException("Could not create PIP Finder Factory: " + properties.getProperty(XACMLProperties.PROP_PIPFINDERFACTORY));
+ }
+ PIPFinder finder = factory.getFinder(properties);
+ //
+ // Check for this, although it should always return something
+ //
+ if (finder == null) {
+ logger.error("pip finder factory returned a null engine.");
+ throw new PIPException("Could not create PIP Finder");
+ } else {
+ logger.info("Loaded PIP finder");
+ }
+ for (PIPEngine engine : finder.getPIPEngines()) {
+ logger.info("Configured PIP Engine: " + engine.getName());
+ StdPDPPIPConfig config = new StdPDPPIPConfig();
+ config.setName(engine.getName());
+ status.addLoadedPipConfig(config);
+ }
+ } catch (FactoryException | PIPException e) {
+ logger.error("validate PIP configuration failed: " + e.getLocalizedMessage());
+ status.addLoadError(e.getLocalizedMessage());
+ status.setStatus(Status.LOAD_ERRORS);
+ throw new PAPException(e);
+ }
+ }
+
+ /**
+ * Iterates the policies defined in the props object to ensure they are loaded locally.
+ * Policies are searched for in the following order:
+ * - see if the current properties has a "<PolicyID>.file" entry and that file exists in the local directory
+ * - if not, see if the file exists in the local directory; if so create a ".file" property for it.
+ * - if not, get the "<PolicyID>.url" property and try to GET the policy from that location (and set the ".file" property)
+ *
+ * If the ".file" property is created, then true is returned to tell the caller that the props object changed.
+ *
+ * @param props
+ * @return true/false if anything was changed in the props object
+ * @throws PAPException
+ */
+ public static synchronized boolean cachePolicies(Properties props) throws PAPException {
+ boolean changed = false;
+ String[] lists = new String[2];
+ lists[0] = props.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
+ lists[1] = props.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
+ for (String list : lists) {
+ //
+ // Check for a null or empty parameter
+ //
+ if (list == null || list.length() == 0) {
+ continue;
+ }
+ Iterable<String> policies = Splitter.on(',').trimResults().omitEmptyStrings().split(list);
+ for (String policy : policies) {
+ boolean policyExists = false;
+
+ // First look for ".file" property and verify the file exists
+ String propLocation = props.getProperty(policy + StdPolicyFinderFactory.PROP_FILE);
+ if (propLocation != null) {
+ //
+ // Does it exist?
+ //
+ policyExists = Files.exists(Paths.get(propLocation));
+ if (policyExists == false) {
+ logger.warn("Policy file " + policy + " expected at " + propLocation + " does NOT exist.");
+ }
+ }
+
+ // If ".file" property does not exist, try looking for the local file anyway
+ // (it might exist without having a ".file" property set for it)
+ if (policyExists == false) {
+ //
+ // Now construct the output file name
+ //
+ Path outFile = Paths.get(getPDPConfig().toAbsolutePath().toString(), policy);
+ //
+ // Double check to see if we pulled it at some point
+ //
+ policyExists = Files.exists(outFile);
+ if (policyExists) {
+ //
+ // Set the property so the PDP engine doesn't have
+ // to pull it from the URL but rather the FILE.
+ //
+ logger.info("Policy does exist: " + outFile.toAbsolutePath().toString());
+ props.setProperty(policy + StdPolicyFinderFactory.PROP_FILE, outFile.toAbsolutePath().toString());
+ //
+ // Indicate that there were changes made to the properties
+ //
+ changed = true;
+ } else {
+
+ // File does not exist locally, so we need to get it from the location given in the ".url" property (which MUST exist)
+
+ //
+ // There better be a URL to retrieve it
+ //
+ propLocation = props.getProperty(policy + StdPolicyFinderFactory.PROP_URL);
+ if (propLocation != null) {
+ //
+ // Get it
+ //
+ URL url = null;
+ try {
+ //
+ // Create the URL
+ //
+ url = new URL(propLocation);
+ logger.info("Pulling " + url.toString());
+ //
+ // Open the connection
+ //
+ URLConnection urlConnection = url.openConnection();
+ urlConnection.setRequestProperty(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID, XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID));
+ //
+ // Copy it to disk
+ //
+ try (InputStream is = urlConnection.getInputStream(); OutputStream os = new FileOutputStream(outFile.toFile())) {
+ IOUtils.copy(is, os);
+ }
+ //
+ // Now save it in the properties as a .file
+ //
+ logger.info("Pulled policy: " + outFile.toAbsolutePath().toString());
+ props.setProperty(policy + StdPolicyFinderFactory.PROP_FILE, outFile.toAbsolutePath().toString());
+ //
+ // Indicate that there were changes made to the properties
+ //
+ changed = true;
+ } catch (Exception e) {
+ if (e instanceof MalformedURLException) {
+ logger.error("Policy '" + policy + "' had bad URL in new configuration, URL='" + propLocation + "'");
+ } else {
+ logger.error("Error while retrieving policy " + policy + " from URL " + url.toString() + ", e="+e);
+ }
+ }
+ } else {
+ logger.error("Policy " + policy + " does NOT exist and does NOT have a URL");
+ }
+ }
+ }
+ }
+ }
+ return changed;
+ }
+
+ public static synchronized Path getPDPPolicyCache() throws PAPException {
+ Path config = getPDPConfig();
+ Path policyProperties = Paths.get(config.toAbsolutePath().toString(), "xacml.policy.properties");
+ if (Files.notExists(policyProperties)) {
+ logger.warn(policyProperties.toAbsolutePath().toString() + " does NOT exist.");
+ //
+ // Try to create the file
+ //
+ try {
+ Files.createFile(policyProperties);
+ } catch (IOException e) {
+ logger.error("Failed to create policy properties file: " + policyProperties.toAbsolutePath().toString());
+ throw new PAPException("Failed to create policy properties file: " + policyProperties.toAbsolutePath().toString());
+ }
+ }
+ return policyProperties;
+ }
+
+ public static synchronized Path getPIPConfig() throws PAPException {
+ Path config = getPDPConfig();
+ Path pipConfigProperties = Paths.get(config.toAbsolutePath().toString(), "xacml.pip.properties");
+ if (Files.notExists(pipConfigProperties)) {
+ logger.warn(pipConfigProperties.toAbsolutePath().toString() + " does NOT exist.");
+ //
+ // Try to create the file
+ //
+ try {
+ Files.createFile(pipConfigProperties);
+ } catch (IOException e) {
+ logger.error("Failed to create pip properties file: " + pipConfigProperties.toAbsolutePath().toString());
+ throw new PAPException("Failed to create pip properties file: " + pipConfigProperties.toAbsolutePath().toString());
+ }
+ }
+ return pipConfigProperties;
+ }
+
+ public static synchronized Path getPDPConfig() throws PAPException {
+ Path config = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_CONFIG));
+ if (Files.notExists(config)) {
+ logger.warn(config.toAbsolutePath().toString() + " does NOT exist.");
+ //
+ // Try to create the directory
+ //
+ try {
+ Files.createDirectories(config);
+ } catch (IOException e) {
+ logger.error("Failed to create config directory: " + config.toAbsolutePath().toString(), e);
+ throw new PAPException("Failed to create config directory: " + config.toAbsolutePath().toString());
+ }
+ }
+ return config;
+ }
+
+}
diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java
new file mode 100755
index 0000000..3d232cf
--- /dev/null
+++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java
@@ -0,0 +1,210 @@
+/*
+ * 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) 2014 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacml.rest;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.file.Files;
+import java.util.Properties;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.rest.XACMLPdpServlet.PutRequest;
+import com.att.research.xacml.util.XACMLProperties;
+
+public class XACMLPdpRegisterThread implements Runnable {
+ private static final Log logger = LogFactory.getLog(XACMLPdpRegisterThread.class);
+
+ public volatile boolean isRunning = false;
+
+ public synchronized boolean isRunning() {
+ return this.isRunning;
+ }
+
+ public synchronized void terminate() {
+ this.isRunning = false;
+ }
+
+ /**
+ *
+ * This is our thread that runs on startup to tell the PAP server we are up-and-running.
+ *
+ */
+ @Override
+ public void run() {
+ synchronized(this) {
+ this.isRunning = true;
+ }
+ boolean registered = false;
+ boolean interrupted = false;
+ int seconds;
+ try {
+ seconds = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER_SLEEP));
+ } catch (NumberFormatException e) {
+ logger.error("REGISTER_SLEEP: ", e);
+ seconds = 5;
+ }
+ if (seconds < 5) {
+ seconds = 5;
+ }
+ int retries;
+ try {
+ retries = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER_RETRIES));
+ } catch (NumberFormatException e) {
+ logger.error("REGISTER_SLEEP: ", e);
+ retries = -1;
+ }
+ while (! registered && ! interrupted && this.isRunning()) {
+ HttpURLConnection connection = null;
+ try {
+ //
+ // Get the PAP Servlet URL
+ //
+ URL url = new URL(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL));
+ logger.info("Registering with " + url.toString());
+ boolean finished = false;
+ while (! finished) {
+ //
+ // Open up the connection
+ //
+ connection = (HttpURLConnection)url.openConnection();
+ //
+ // Setup our method and headers
+ //
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Accept", "text/x-java-properties");
+ connection.setRequestProperty("Content-Type", "text/x-java-properties");
+ connection.setRequestProperty(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID, XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID));
+ connection.setUseCaches(false);
+ //
+ // Adding this in. It seems the HttpUrlConnection class does NOT
+ // properly forward our headers for POST re-direction. It does so
+ // for a GET re-direction.
+ //
+ // So we need to handle this ourselves.
+ //
+ connection.setInstanceFollowRedirects(false);
+ connection.setDoOutput(true);
+ connection.setDoInput(true);
+ try {
+ //
+ // Send our current policy configuration
+ //
+ String lists = XACMLProperties.PROP_ROOTPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
+ lists = lists + "\n" + XACMLProperties.PROP_REFERENCEDPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES) + "\n";
+ try (InputStream listsInputStream = new ByteArrayInputStream(lists.getBytes());
+ InputStream pipInputStream = Files.newInputStream(XACMLPdpLoader.getPIPConfig());
+ OutputStream os = connection.getOutputStream()) {
+ IOUtils.copy(listsInputStream, os);
+
+ //
+ // Send our current PIP configuration
+ //
+ IOUtils.copy(pipInputStream, os);
+ }
+ } catch (Exception e) {
+ logger.error("Failed to send property file", e);
+ }
+ //
+ // Do the connect
+ //
+ connection.connect();
+ if (connection.getResponseCode() == 204) {
+ logger.info("Success. We are configured correctly.");
+ finished = true;
+ registered = true;
+ } else if (connection.getResponseCode() == 200) {
+ logger.info("Success. We have a new configuration.");
+ Properties properties = new Properties();
+ properties.load(connection.getInputStream());
+ logger.info("New properties: " + properties.toString());
+ //
+ // Queue it
+ //
+ // The incoming properties does NOT include urls
+ PutRequest req = new PutRequest(XACMLProperties.getPolicyProperties(properties, false), XACMLProperties.getPipProperties(properties));
+ XACMLPdpServlet.queue.offer(req);
+ //
+ // We are now registered
+ //
+ finished = true;
+ registered=true;
+ } else if (connection.getResponseCode() >= 300 && connection.getResponseCode() <= 399) {
+ //
+ // Re-direction
+ //
+ String newLocation = connection.getHeaderField("Location");
+ if (newLocation == null || newLocation.isEmpty()) {
+ logger.warn("Did not receive a valid re-direction location");
+ finished = true;
+ } else {
+ logger.info("New Location: " + newLocation);
+ url = new URL(newLocation);
+ }
+ } else {
+ logger.warn("Failed: " + connection.getResponseCode() + " message: " + connection.getResponseMessage());
+ finished = true;
+ }
+ }
+ } catch (Exception e) {
+ logger.error(e);
+ } finally {
+ // cleanup the connection
+ if (connection != null) {
+ try {
+ // For some reason trying to get the inputStream from the connection
+ // throws an exception rather than returning null when the InputStream does not exist.
+ InputStream is = null;
+ try {
+ is = connection.getInputStream();
+ } catch (Exception e1) {
+ // ignore this
+ }
+ if (is != null) {
+ is.close();
+ }
+
+ } catch (IOException ex) {
+ logger.error("Failed to close connection: " + ex, ex);
+ }
+ connection.disconnect();
+ }
+ }
+ //
+ // Wait a little while to try again
+ //
+ try {
+ if (registered == false) {
+ if (retries > 0) {
+ retries--;
+ } else if (retries == 0) {
+ break;
+ }
+ Thread.sleep(seconds * 1000);
+ }
+ } catch (InterruptedException e) {
+ interrupted = true;
+ this.terminate();
+ }
+ }
+ synchronized(this) {
+ this.isRunning = false;
+ }
+ logger.info("Thread exiting...(registered=" + registered + ", interrupted=" + interrupted + ", isRunning=" + this.isRunning() + ", retries=" + retries + ")");
+ }
+
+}
diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java
new file mode 100755
index 0000000..f670579
--- /dev/null
+++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java
@@ -0,0 +1,690 @@
+/*
+ * 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.xacml.rest;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.util.Properties;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebInitParam;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.entity.ContentType;
+
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.Response;
+import com.att.research.xacml.api.pap.PDPStatus.Status;
+import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.api.pdp.PDPException;
+import com.att.research.xacml.std.dom.DOMRequest;
+import com.att.research.xacml.std.dom.DOMResponse;
+import com.att.research.xacml.std.json.JSONRequest;
+import com.att.research.xacml.std.json.JSONResponse;
+import com.att.research.xacml.std.pap.StdPDPStatus;
+import com.att.research.xacml.util.XACMLProperties;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * Servlet implementation class XacmlPdpServlet
+ *
+ * This is an implementation of the XACML 3.0 RESTful Interface with added features to support
+ * simple PAP RESTful API for policy publishing and PIP configuration changes.
+ *
+ * If you are running this the first time, then we recommend you look at the xacml.pdp.properties file.
+ * This properties file has all the default parameter settings. If you are running the servlet as is,
+ * then we recommend setting up you're container to run it on port 8080 with context "/pdp". Wherever
+ * the default working directory is set to, a "config" directory will be created that holds the policy
+ * and pip cache. This setting is located in the xacml.pdp.properties file.
+ *
+ * When you are ready to customize, you can create a separate xacml.pdp.properties on you're local file
+ * system and setup the parameters as you wish. Just set the Java VM System variable to point to that file:
+ *
+ * -Dxacml.properties=/opt/app/xacml/etc/xacml.pdp.properties
+ *
+ * Or if you only want to change one or two properties, simply set the Java VM System variable for that property.
+ *
+ * -Dxacml.rest.pdp.register=false
+ *
+ * @author pameladragosh
+ *
+ */
+@WebServlet(
+ description = "Implements the XACML PDP RESTful API and client PAP API.",
+ urlPatterns = { "/" },
+ loadOnStartup=1,
+ initParams = {
+ @WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pdp.properties", description = "The location of the PDP xacml.pdp.properties file holding configuration information.")
+ })
+public class XACMLPdpServlet extends HttpServlet implements Runnable {
+ private static final long serialVersionUID = 1L;
+ //
+ // Our application debug log
+ //
+ private static final Log logger = LogFactory.getLog(XACMLPdpServlet.class);
+ //
+ // This logger is specifically only for Xacml requests and their corresponding response.
+ // It's output ideally should be sent to a separate file from the application logger.
+ //
+ private static final Log requestLogger = LogFactory.getLog("xacml.request");
+ //
+ // This thread may getting invoked on startup, to let the PAP know
+ // that we are up and running.
+ //
+ private Thread registerThread = null;
+ private XACMLPdpRegisterThread registerRunnable = null;
+ //
+ // This is our PDP engine pointer. There is a synchronized lock used
+ // for access to the pointer. In case we are servicing PEP requests while
+ // an update is occurring from the PAP.
+ //
+ private PDPEngine pdpEngine = null;
+ private static final Object pdpEngineLock = new Object();
+ //
+ // This is our PDP's status. What policies are loaded (or not) and
+ // what PIP configurations are loaded (or not).
+ // There is a synchronized lock used for access to the object.
+ //
+ private static volatile StdPDPStatus status = new StdPDPStatus();
+ private static final Object pdpStatusLock = new Object();
+ //
+ // Queue of PUT requests
+ //
+ public static class PutRequest {
+ public Properties policyProperties = null;
+ public Properties pipConfigProperties = null;
+
+ PutRequest(Properties policies, Properties pips) {
+ this.policyProperties = policies;
+ this.pipConfigProperties = pips;
+ }
+ }
+ public static volatile BlockingQueue<PutRequest> queue = new LinkedBlockingQueue<PutRequest>(2);
+ //
+ // This is our configuration thread that attempts to load
+ // a new configuration request.
+ //
+ private Thread configThread = null;
+ private volatile boolean configThreadTerminate = false;
+
+ /**
+ * Default constructor.
+ */
+ public XACMLPdpServlet() {
+ }
+
+ /**
+ * @see Servlet#init(ServletConfig)
+ */
+ public void init(ServletConfig config) throws ServletException {
+ //
+ // Initialize
+ //
+ XACMLRest.xacmlInit(config);
+ //
+ // Load our engine - this will use the latest configuration
+ // that was saved to disk and set our initial status object.
+ //
+ PDPEngine engine = XACMLPdpLoader.loadEngine(XACMLPdpServlet.status, null, null);
+ if (engine != null) {
+ synchronized(pdpEngineLock) {
+ pdpEngine = engine;
+ }
+ }
+ //
+ // Kick off our thread to register with the PAP servlet.
+ //
+ if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER))) {
+ this.registerRunnable = new XACMLPdpRegisterThread();
+ this.registerThread = new Thread(this.registerRunnable);
+ this.registerThread.start();
+ }
+ //
+ // This is our thread that manages incoming configuration
+ // changes.
+ //
+ this.configThread = new Thread(this);
+ this.configThread.start();
+ }
+
+ /**
+ * @see Servlet#destroy()
+ */
+ public void destroy() {
+ super.destroy();
+ logger.info("Destroying....");
+ //
+ // Make sure the register thread is not running
+ //
+ if (this.registerRunnable != null) {
+ try {
+ this.registerRunnable.terminate();
+ if (this.registerThread != null) {
+ this.registerThread.interrupt();
+ this.registerThread.join();
+ }
+ } catch (InterruptedException e) {
+ logger.error(e);
+ }
+ }
+ //
+ // Make sure the configure thread is not running
+ //
+ this.configThreadTerminate = true;
+ try {
+ this.configThread.interrupt();
+ this.configThread.join();
+ } catch (InterruptedException e) {
+ logger.error(e);
+ }
+ logger.info("Destroyed.");
+ }
+
+ /**
+ * PUT - The PAP engine sends configuration information using HTTP PUT request.
+ *
+ * One parameter is expected:
+ *
+ * config=[policy|pip|all]
+ *
+ * policy - Expect a properties file that contains updated lists of the root and referenced policies that the PDP should
+ * be using for PEP requests.
+ *
+ * Specifically should AT LEAST contain the following properties:
+ * xacml.rootPolicies
+ * xacml.referencedPolicies
+ *
+ * In addition, any relevant information needed by the PDP to load or retrieve the policies to store in its cache.
+ *
+ * EXAMPLE:
+ * xacml.rootPolicies=PolicyA.1, PolicyB.1
+ *
+ * PolicyA.1.url=http://localhost:9090/PAP?id=b2d7b86d-d8f1-4adf-ba9d-b68b2a90bee1&version=1
+ * PolicyB.1.url=http://localhost:9090/PAP/id=be962404-27f6-41d8-9521-5acb7f0238be&version=1
+ *
+ * xacml.referencedPolicies=RefPolicyC.1, RefPolicyD.1
+ *
+ * RefPolicyC.1.url=http://localhost:9090/PAP?id=foobar&version=1
+ * RefPolicyD.1.url=http://localhost:9090/PAP/id=example&version=1
+ *
+ * pip - Expect a properties file that contain PIP engine configuration properties.
+ *
+ * Specifically should AT LEAST the following property:
+ * xacml.pip.engines
+ *
+ * In addition, any relevant information needed by the PDP to load and configure the PIPs.
+ *
+ * EXAMPLE:
+ * xacml.pip.engines=foo,bar
+ *
+ * foo.classname=com.foo
+ * foo.sample=abc
+ * foo.example=xyz
+ * ......
+ *
+ * bar.classname=com.bar
+ * ......
+ *
+ * all - Expect ALL new configuration properties for the PDP
+ *
+ * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response)
+ */
+ protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ //
+ // Dump our request out
+ //
+ if (logger.isDebugEnabled()) {
+ XACMLRest.dumpRequest(request);
+ }
+ //
+ // What is being PUT?
+ //
+ String cache = request.getParameter("cache");
+ //
+ // Should be a list of policy and pip configurations in Java properties format
+ //
+ if (cache != null && request.getContentType().equals("text/x-java-properties")) {
+ if (request.getContentLength() > Integer.parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", "32767"))) {
+ String message = "Content-Length larger than server will accept.";
+ logger.info(message);
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+ return;
+ }
+ this.doPutConfig(cache, request, response);
+ } else {
+ String message = "Invalid cache: '" + cache + "' or content-type: '" + request.getContentType() + "'";
+ logger.error(message);
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+ return;
+ }
+ }
+
+ protected void doPutConfig(String config, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ try {
+ // prevent multiple configuration changes from stacking up
+ if (XACMLPdpServlet.queue.remainingCapacity() <= 0) {
+ logger.error("Queue capacity reached");
+ response.sendError(HttpServletResponse.SC_CONFLICT, "Multiple configuration changes waiting processing.");
+ return;
+ }
+ //
+ // Read the properties data into an object.
+ //
+ Properties newProperties = new Properties();
+ newProperties.load(request.getInputStream());
+ // should have something in the request
+ if (newProperties.size() == 0) {
+ logger.error("No properties in PUT");
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT must contain at least one property");
+ return;
+ }
+ //
+ // Which set of properties are they sending us? Whatever they send gets
+ // put on the queue (if there is room).
+ //
+ if (config.equals("policies")) {
+ newProperties = XACMLProperties.getPolicyProperties(newProperties, true);
+ if (newProperties.size() == 0) {
+ logger.error("No policy properties in PUT");
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=policies must contain at least one policy property");
+ return;
+ }
+ XACMLPdpServlet.queue.offer(new PutRequest(newProperties, null));
+ } else if (config.equals("pips")) {
+ newProperties = XACMLProperties.getPipProperties(newProperties);
+ if (newProperties.size() == 0) {
+ logger.error("No pips properties in PUT");
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=pips must contain at least one pip property");
+ return;
+ }
+ XACMLPdpServlet.queue.offer(new PutRequest(null, newProperties));
+ } else if (config.equals("all")) {
+ Properties newPolicyProperties = XACMLProperties.getPolicyProperties(newProperties, true);
+ if (newPolicyProperties.size() == 0) {
+ logger.error("No policy properties in PUT");
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=all must contain at least one policy property");
+ return;
+ }
+ Properties newPipProperties = XACMLProperties.getPipProperties(newProperties);
+ if (newPipProperties.size() == 0) {
+ logger.error("No pips properties in PUT");
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=all must contain at least one pip property");
+ return;
+ }
+ XACMLPdpServlet.queue.offer(new PutRequest(newPolicyProperties, newPipProperties));
+ } else {
+ //
+ // Invalid value
+ //
+ logger.error("Invalid config value: " + config);
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Config must be one of 'policies', 'pips', 'all'");
+ return;
+ }
+ } catch (Exception e) {
+ logger.error("Failed to process new configuration.", e);
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+ return;
+ }
+ }
+
+ /**
+ * Parameters: type=hb|config|Status
+ *
+ * 1. HeartBeat Status
+ * HeartBeat
+ * OK - All Policies are Loaded, All PIPs are Loaded
+ * LOADING_IN_PROGRESS - Currently loading a new policy set/pip configuration
+ * LAST_UPDATE_FAILED - Need to track the items that failed during last update
+ * LOAD_FAILURE - ??? Need to determine what information is sent and how
+ * 2. Configuration
+ * 3. Status
+ * return the StdPDPStatus object in the Response content
+ *
+ *
+ * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
+ */
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ XACMLRest.dumpRequest(request);
+ //
+ // What are they requesting?
+ //
+ boolean returnHB = false;
+ response.setHeader("Cache-Control", "no-cache");
+ String type = request.getParameter("type");
+ // type might be null, so use equals on string constants
+ if ("config".equals(type)) {
+ response.setContentType("text/x-java-properties");
+ try {
+ String lists = XACMLProperties.PROP_ROOTPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES, "");
+ lists = lists + "\n" + XACMLProperties.PROP_REFERENCEDPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, "") + "\n";
+ try (InputStream listInputStream = new ByteArrayInputStream(lists.getBytes());
+ InputStream pipInputStream = Files.newInputStream(XACMLPdpLoader.getPIPConfig());
+ OutputStream os = response.getOutputStream()) {
+ IOUtils.copy(listInputStream, os);
+ IOUtils.copy(pipInputStream, os);
+ }
+ response.setStatus(HttpServletResponse.SC_OK);
+ } catch (Exception e) {
+ logger.error("Failed to copy property file", e);
+ response.sendError(400, "Failed to copy Property file");
+ }
+
+ } else if ("hb".equals(type)) {
+ returnHB = true;
+ response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+
+ } else if ("Status".equals(type)) {
+ // convert response object to JSON and include in the response
+ synchronized(pdpStatusLock) {
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.writeValue(response.getOutputStream(), status);
+ }
+ response.setStatus(HttpServletResponse.SC_OK);
+
+ } else {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "type not 'config' or 'hb'");
+ }
+ if (returnHB) {
+ synchronized(pdpStatusLock) {
+ response.addHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB, status.getStatus().toString());
+ }
+ }
+ }
+
+ /**
+ * POST - We expect XACML requests to be posted by PEP applications. They can be in the form of XML or JSON according
+ * to the XACML 3.0 Specifications for both.
+ *
+ *
+ * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
+ */
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ //
+ // no point in doing any work if we know from the get-go that we cannot do anything with the request
+ //
+ if (status.getLoadedRootPolicies().size() == 0) {
+ logger.warn("Request from PEP at " + request.getRequestURI() + " for service when PDP has No Root Policies loaded");
+ response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+ return;
+ }
+
+ XACMLRest.dumpRequest(request);
+ //
+ // Set our no-cache header
+ //
+ response.setHeader("Cache-Control", "no-cache");
+ //
+ // They must send a Content-Type
+ //
+ if (request.getContentType() == null) {
+ logger.warn("Must specify a Content-Type");
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "no content-type given");
+ return;
+ }
+ //
+ // Limit the Content-Length to something reasonable
+ //
+ if (request.getContentLength() > Integer.parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", "32767"))) {
+ String message = "Content-Length larger than server will accept.";
+ logger.info(message);
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+ return;
+ }
+ if (request.getContentLength() <= 0) {
+ String message = "Content-Length is negative";
+ logger.info(message);
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+ return;
+ }
+ ContentType contentType = null;
+ try {
+ contentType = ContentType.parse(request.getContentType());
+ }
+ catch (Exception e) {
+ String message = "Parsing Content-Type: " + request.getContentType() + ", error=" + e.getMessage();
+ logger.error(message, e);
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+ return;
+ }
+ //
+ // What exactly did they send us?
+ //
+ String incomingRequestString = null;
+ Request pdpRequest = null;
+ if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType()) ||
+ contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) ||
+ contentType.getMimeType().equalsIgnoreCase("application/xacml+xml") ) {
+ //
+ // Read in the string
+ //
+ StringBuilder buffer = new StringBuilder();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
+ String line;
+ while((line = reader.readLine()) != null){
+ buffer.append(line);
+ }
+ incomingRequestString = buffer.toString();
+ logger.info(incomingRequestString);
+ //
+ // Parse into a request
+ //
+ try {
+ if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
+ pdpRequest = JSONRequest.load(incomingRequestString);
+ } else if ( contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) ||
+ contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
+ pdpRequest = DOMRequest.load(incomingRequestString);
+ }
+ }
+ catch(Exception e) {
+ logger.error("Could not parse request", e);
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+ return;
+ }
+ } else {
+ String message = "unsupported content type" + request.getContentType();
+ logger.error(message);
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+ return;
+ }
+ //
+ // Did we successfully get and parse a request?
+ //
+ if (pdpRequest == null || pdpRequest.getRequestAttributes() == null || pdpRequest.getRequestAttributes().size() <= 0) {
+ String message = "Zero Attributes found in the request";
+ logger.error(message);
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+ return;
+ }
+ //
+ // Run it
+ //
+ try {
+ //
+ // Get the pointer to the PDP Engine
+ //
+ PDPEngine myEngine = null;
+ synchronized(pdpEngineLock) {
+ myEngine = this.pdpEngine;
+ }
+ if (myEngine == null) {
+ String message = "No engine loaded.";
+ logger.error(message);
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+ return;
+ }
+ //
+ // Send the request and save the response
+ //
+ long lTimeStart, lTimeEnd;
+ Response pdpResponse = null;
+
+//TODO - Make this unnecessary
+//TODO It seems that the PDP Engine is not thread-safe, so when a configuration change occurs in the middle of processing
+//TODO a PEP Request, that Request fails (it throws a NullPointerException in the decide() method).
+//TODO Using synchronize will slow down processing of PEP requests, possibly by a significant amount.
+//TODO Since configuration changes are rare, it would be A Very Good Thing if we could eliminate this sychronized block.
+//TODO
+//TODO This problem was found by starting one PDP then
+//TODO RestLoadTest switching between 2 configurations, 1 second apart
+//TODO both configurations contain the datarouter policy
+//TODO both configurations already have all policies cached in the PDPs config directory
+//TODO RestLoadTest started with the Datarouter test requests, 5 threads, no interval
+//TODO With that configuration this code (without the synchronized) throws a NullPointerException
+//TODO within a few seconds.
+//
+synchronized(pdpEngineLock) {
+ myEngine = this.pdpEngine;
+ try {
+ lTimeStart = System.currentTimeMillis();
+ pdpResponse = myEngine.decide(pdpRequest);
+ lTimeEnd = System.currentTimeMillis();
+ } catch (PDPException e) {
+ String message = "Exception during decide: " + e.getMessage();
+ logger.error(message);
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+ return;
+ }
+}
+ requestLogger.info(lTimeStart + "=" + incomingRequestString);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Request time: " + (lTimeEnd - lTimeStart) + "ms");
+ }
+ //
+ // Convert Response to appropriate Content-Type
+ //
+ if (pdpResponse == null) {
+ requestLogger.info(lTimeStart + "=" + "{}");
+ throw new Exception("Failed to get response from PDP engine.");
+ }
+ //
+ // Set our content-type
+ //
+ response.setContentType(contentType.getMimeType());
+ //
+ // Convert the PDP response object to a String to
+ // return to our caller as well as dump to our loggers.
+ //
+ String outgoingResponseString = "";
+ if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
+ //
+ // Get it as a String. This is not very efficient but we need to log our
+ // results for auditing.
+ //
+ outgoingResponseString = JSONResponse.toString(pdpResponse, logger.isDebugEnabled());
+ if (logger.isDebugEnabled()) {
+ logger.debug(outgoingResponseString);
+ //
+ // Get rid of whitespace
+ //
+ outgoingResponseString = JSONResponse.toString(pdpResponse, false);
+ }
+ } else if ( contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) ||
+ contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
+ //
+ // Get it as a String. This is not very efficient but we need to log our
+ // results for auditing.
+ //
+ outgoingResponseString = DOMResponse.toString(pdpResponse, logger.isDebugEnabled());
+ if (logger.isDebugEnabled()) {
+ logger.debug(outgoingResponseString);
+ //
+ // Get rid of whitespace
+ //
+ outgoingResponseString = DOMResponse.toString(pdpResponse, false);
+ }
+ }
+ //
+ // lTimeStart is used as an ID within the requestLogger to match up
+ // request's with responses.
+ //
+ requestLogger.info(lTimeStart + "=" + outgoingResponseString);
+ response.getWriter().print(outgoingResponseString);
+ }
+ catch (Exception e) {
+ String message = "Exception executing request: " + e;
+ logger.error(message, e);
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+ return;
+ }
+ response.setStatus(HttpServletResponse.SC_OK);
+ }
+
+ @Override
+ public void run() {
+ //
+ // Keep running until we are told to terminate
+ //
+ try {
+ while (! this.configThreadTerminate) {
+ PutRequest request = XACMLPdpServlet.queue.take();
+ StdPDPStatus newStatus = new StdPDPStatus();
+
+//TODO - This is related to the problem discussed in the doPost() method about the PDPEngine not being thread-safe.
+//TODO See that discussion, and when the PDPEngine is made thread-safe it should be ok to move the loadEngine out of
+//TODO the synchronized block.
+//TODO However, since configuration changes should be rare we may not care about changing this.
+PDPEngine newEngine = null;
+ synchronized(pdpStatusLock) {
+ XACMLPdpServlet.status.setStatus(Status.UPDATING_CONFIGURATION);
+newEngine = XACMLPdpLoader.loadEngine(newStatus, request.policyProperties, request.pipConfigProperties);
+ }
+// PDPEngine newEngine = XACMLPdpLoader.loadEngine(newStatus, request.policyProperties, request.pipConfigProperties);
+ if (newEngine != null) {
+ synchronized(XACMLPdpServlet.pdpEngineLock) {
+ this.pdpEngine = newEngine;
+ try {
+ logger.info("Saving configuration.");
+ if (request.policyProperties != null) {
+ try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPDPPolicyCache())) {
+ request.policyProperties.store(os, "");
+ }
+ }
+ if (request.pipConfigProperties != null) {
+ try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPIPConfig())) {
+ request.pipConfigProperties.store(os, "");
+ }
+ }
+ newStatus.setStatus(Status.UP_TO_DATE);
+
+ } catch (Exception e) {
+ logger.error("Failed to store new properties.");
+ newStatus.setStatus(Status.LOAD_ERRORS);
+ newStatus.addLoadWarning("Unable to save configuration: " + e.getMessage());
+ }
+ }
+ } else {
+ newStatus.setStatus(Status.LAST_UPDATE_FAILED);
+ }
+ synchronized(pdpStatusLock) {
+ XACMLPdpServlet.status.set(newStatus);
+ }
+ }
+ } catch (InterruptedException e) {
+ logger.error("interrupted");
+ }
+ }
+}
diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java
new file mode 100755
index 0000000..550d1b2
--- /dev/null
+++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java
@@ -0,0 +1,75 @@
+/*
+ * 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) 2014 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacml.rest.impl;
+
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.pip.PIPException;
+import com.att.research.xacml.api.pip.PIPFinder;
+import com.att.research.xacml.api.pip.PIPFinderFactory;
+import com.att.research.xacml.std.pip.finders.ConfigurableEngineFinder;
+import com.att.research.xacml.util.XACMLProperties;
+
+public class XACMLPdpPIPFinderFactory extends PIPFinderFactory {
+ private ConfigurableEngineFinder pipFinder;
+
+ private static Log logger = LogFactory.getLog(XACMLPdpPIPFinderFactory.class);
+
+ public XACMLPdpPIPFinderFactory() {
+ }
+
+ public XACMLPdpPIPFinderFactory(Properties properties) {
+ }
+
+ @Override
+ public PIPFinder getFinder() throws PIPException {
+ if (pipFinder == null) {
+ synchronized(this) {
+ if (pipFinder == null) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Creating default configurable engine finder");
+ }
+ pipFinder = new ConfigurableEngineFinder();
+ Properties xacmlProperties = null;
+ try {
+ xacmlProperties = XACMLProperties.getProperties();
+ } catch (Exception ex) {
+ logger.error("Exception getting XACML properties: " + ex.getMessage(), ex);
+ return null;
+ }
+ if (xacmlProperties != null) {
+ ((ConfigurableEngineFinder)pipFinder).configure(xacmlProperties);
+ }
+ }
+ }
+ }
+ return pipFinder;
+ }
+
+ @Override
+ public PIPFinder getFinder(Properties properties) throws PIPException {
+ if (pipFinder == null) {
+ synchronized(this) {
+ if (pipFinder == null) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Creating configurable engine finder using: " + properties);
+ }
+ pipFinder = new ConfigurableEngineFinder();
+ ((ConfigurableEngineFinder)pipFinder).configure(properties);
+ }
+ }
+ }
+ return this.pipFinder;
+ }
+}
diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java
new file mode 100755
index 0000000..421839a
--- /dev/null
+++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java
@@ -0,0 +1,197 @@
+/*
+ * 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) 2014 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacml.rest.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.XACMLProperties;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinder;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory;
+import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef;
+import com.att.research.xacmlatt.pdp.std.StdPolicyFinder;
+import com.google.common.base.Splitter;
+
+public class XACMLPdpPolicyFinderFactory extends PolicyFinderFactory {
+ public static final String PROP_FILE = ".file";
+ public static final String PROP_URL = ".url";
+
+ private static Log logger = LogFactory.getLog(XACMLPdpPolicyFinderFactory.class);
+ private List<PolicyDef> rootPolicies;
+ private List<PolicyDef> referencedPolicies;
+ private boolean needsInit = true;
+
+ private Properties properties = null;
+
+ public XACMLPdpPolicyFinderFactory() {
+ //
+ // Here we differ from the StdPolicyFinderFactory in that we initialize right away.
+ // We do not wait for a policy request to happen to look for and load policies.
+ //
+ this.init();
+ }
+
+ public XACMLPdpPolicyFinderFactory(Properties properties) {
+ //
+ // Save our properties
+ //
+ this.properties = properties;
+ //
+ // Here we differ from the StdPolicyFinderFactory in that we initialize right away.
+ // We do not wait for a policy request to happen to look for and load policies.
+ //
+ this.init();
+ }
+
+ /**
+ * Loads the <code>PolicyDef</code> for the given <code>String</code> identifier by looking first
+ * for a ".file" property associated with the ID and using that to load from a <code>File</code> and
+ * looking for a ".url" property associated with the ID and using that to load from a <code>URL</code>.
+ *
+ * @param policyId the <code>String</code> identifier for the policy
+ * @return a <code>PolicyDef</code> loaded from the given identifier
+ */
+ protected PolicyDef loadPolicyDef(String policyId) {
+ String propLocation = null;
+ if (this.properties == null) {
+ propLocation = XACMLProperties.getProperty(policyId + PROP_FILE);
+ } else {
+ propLocation = this.properties.getProperty(policyId + PROP_FILE);
+ }
+ if (propLocation != null) {
+ File fileLocation = new File(propLocation);
+ if (!fileLocation.exists()) {
+ XACMLPdpPolicyFinderFactory.logger.error("Policy file " + fileLocation.getAbsolutePath() + " does not exist.");
+ } else if (!fileLocation.canRead()) {
+ XACMLPdpPolicyFinderFactory.logger.error("Policy file " + fileLocation.getAbsolutePath() + " cannot be read.");
+ } else {
+ try {
+ XACMLPdpPolicyFinderFactory.logger.info("Loading policy file " + fileLocation);
+ PolicyDef policyDef = DOMPolicyDef.load(fileLocation);
+ if (policyDef != null) {
+ return policyDef;
+ }
+ } catch (DOMStructureException ex) {
+ XACMLPdpPolicyFinderFactory.logger.error("Error loading policy file " + fileLocation.getAbsolutePath() + ": " + ex.getMessage(), ex);
+ return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ }
+ }
+ }
+ if (this.properties == null) {
+ propLocation = XACMLProperties.getProperty(policyId + PROP_URL);
+ } else {
+ propLocation = this.properties.getProperty(policyId + PROP_URL);
+ }
+ if (propLocation != null) {
+ InputStream is = null;
+ try {
+ URL url = new URL(propLocation);
+ URLConnection urlConnection = url.openConnection();
+ XACMLPdpPolicyFinderFactory.logger.info("Loading policy file " + url.toString());
+ is = urlConnection.getInputStream();
+ PolicyDef policyDef = DOMPolicyDef.load(is);
+ if (policyDef != null) {
+ return policyDef;
+ }
+ } catch (MalformedURLException ex) {
+ XACMLPdpPolicyFinderFactory.logger.error("Invalid URL " + propLocation + ": " + ex.getMessage(), ex);
+ } catch (IOException ex) {
+ XACMLPdpPolicyFinderFactory.logger.error("IOException opening URL " + propLocation + ": " + ex.getMessage(), ex);
+ } catch (DOMStructureException ex) {
+ XACMLPdpPolicyFinderFactory.logger.error("Invalid Policy " + propLocation + ": " + ex.getMessage(), ex);
+ return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ XACMLPdpPolicyFinderFactory.logger.error("Exception closing InputStream for GET of url " + propLocation + " : " + e.getMessage() + " (May be memory leak)", e);
+ }
+ }
+ }
+ }
+
+ XACMLPdpPolicyFinderFactory.logger.error("No known location for Policy " + policyId);
+ return null;
+ }
+
+ /**
+ * Finds the identifiers for all of the policies referenced by the given property name in the
+ * <code>XACMLProperties</code> and loads them using the requested loading method.
+ *
+ * @param propertyName the <code>String</code> name of the property containing the list of policy identifiers
+ * @return a <code>List</code> of <code>PolicyDef</code>s loaded from the given property name
+ */
+ protected List<PolicyDef> getPolicyDefs(String propertyName) {
+ String policyIds = XACMLProperties.getProperty(propertyName);
+ if (policyIds == null || policyIds.length() == 0) {
+ return null;
+ }
+
+ Iterable<String> policyIdArray = Splitter.on(',').trimResults().omitEmptyStrings().split(policyIds);
+ if (policyIdArray == null) {
+ return null;
+ }
+
+ List<PolicyDef> listPolicyDefs = new ArrayList<PolicyDef>();
+ for (String policyId : policyIdArray) {
+ PolicyDef policyDef = this.loadPolicyDef(policyId);
+ if (policyDef != null) {
+ listPolicyDefs.add(policyDef);
+ }
+ }
+ return listPolicyDefs;
+ }
+
+ protected synchronized void init() {
+ if (this.needsInit) {
+ if (XACMLPdpPolicyFinderFactory.logger.isDebugEnabled()) {
+ XACMLPdpPolicyFinderFactory.logger.debug("Initializing");
+ }
+ this.rootPolicies = this.getPolicyDefs(XACMLProperties.PROP_ROOTPOLICIES);
+ this.referencedPolicies = this.getPolicyDefs(XACMLProperties.PROP_REFERENCEDPOLICIES);
+ if (XACMLPdpPolicyFinderFactory.logger.isDebugEnabled()) {
+ XACMLPdpPolicyFinderFactory.logger.debug("Root Policies: " + this.rootPolicies);
+ XACMLPdpPolicyFinderFactory.logger.debug("Referenced Policies: " + this.referencedPolicies);
+ }
+ this.needsInit = false;
+ }
+ }
+
+ @Override
+ public PolicyFinder getPolicyFinder() throws FactoryException {
+ //
+ // Force using any properties that were passed upon construction
+ //
+ return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies, this.properties);
+ }
+
+ @Override
+ public PolicyFinder getPolicyFinder(Properties properties) throws FactoryException {
+ return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies, properties);
+ }
+
+}
diff --git a/openaz-xacml-pdp-rest/src/main/resources/log4j.properties b/openaz-xacml-pdp-rest/src/main/resources/log4j.properties
new file mode 100755
index 0000000..b45fa2f
--- /dev/null
+++ b/openaz-xacml-pdp-rest/src/main/resources/log4j.properties
@@ -0,0 +1,22 @@
+#
+# Use this properties for debugging and development.
+#
+#
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=DEBUG, MAIN_LOG
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.MAIN_LOG=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.MAIN_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.MAIN_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n
+
+#
+# This is specifically for Xacml request/response logging
+#
+log4j.logger.xacml.request=INFO, REQUEST_LOG
+
+log4j.appender.REQUEST_LOG=org.apache.log4j.ConsoleAppender
+log4j.appender.REQUEST_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.REQUEST_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} %m%n
\ No newline at end of file
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpLoader.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpLoader.class
new file mode 100644
index 0000000..43eeb50
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpLoader.class
Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpRegisterThread.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpRegisterThread.class
new file mode 100644
index 0000000..b43d395
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpRegisterThread.class
Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class
new file mode 100644
index 0000000..9809046
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class
Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet.class
new file mode 100644
index 0000000..59e6daa
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet.class
Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class
new file mode 100644
index 0000000..54de986
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class
new file mode 100644
index 0000000..f9825d8
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp-rest/target/classes/log4j.properties b/openaz-xacml-pdp-rest/target/classes/log4j.properties
new file mode 100644
index 0000000..b45fa2f
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/classes/log4j.properties
@@ -0,0 +1,22 @@
+#
+# Use this properties for debugging and development.
+#
+#
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=DEBUG, MAIN_LOG
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.MAIN_LOG=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.MAIN_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.MAIN_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n
+
+#
+# This is specifically for Xacml request/response logging
+#
+log4j.logger.xacml.request=INFO, REQUEST_LOG
+
+log4j.appender.REQUEST_LOG=org.apache.log4j.ConsoleAppender
+log4j.appender.REQUEST_LOG.layout=org.apache.log4j.PatternLayout
+log4j.appender.REQUEST_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} %m%n
\ No newline at end of file
diff --git a/openaz-xacml-pdp-rest/target/maven-archiver/pom.properties b/openaz-xacml-pdp-rest/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..5eebb03
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Tue Apr 07 07:42:37 EDT 2015
+version=0.0.1-SNAPSHOT
+groupId=org.openliberty.openaz
+artifactId=openaz-xacml-pdp-rest
diff --git a/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..667efe3
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,6 @@
+com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class
+com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class
+com/att/research/xacml/rest/XACMLPdpServlet.class
+com/att/research/xacml/rest/XACMLPdpLoader.class
+com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class
+com/att/research/xacml/rest/XACMLPdpRegisterThread.class
diff --git a/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..12a596f
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,5 @@
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java
diff --git a/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
diff --git a/openaz-xacml-pdp-rest/target/openaz-xacml-pdp-rest-0.0.1-SNAPSHOT.jar b/openaz-xacml-pdp-rest/target/openaz-xacml-pdp-rest-0.0.1-SNAPSHOT.jar
new file mode 100644
index 0000000..8eca8bd
--- /dev/null
+++ b/openaz-xacml-pdp-rest/target/openaz-xacml-pdp-rest-0.0.1-SNAPSHOT.jar
Binary files differ
diff --git a/openaz-xacml-pdp-rest/xacml.pdp.properties b/openaz-xacml-pdp-rest/xacml.pdp.properties
new file mode 100755
index 0000000..34e6b77
--- /dev/null
+++ b/openaz-xacml-pdp-rest/xacml.pdp.properties
@@ -0,0 +1,53 @@
+# Default XACML Properties File for PDP RESTful servlet
+#
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+# NOT USED SEE BELOW xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory
+#
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+# NOT USED SEE BELOW xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+#
+# AT&T RESTful PDP Implementation Factories
+#
+xacml.pipFinderFactory=com.att.research.xacml.rest.impl.XACMLPdpPIPFinderFactory
+xacml.att.policyFinderFactory=com.att.research.xacml.rest.XACMLPdpPolicyFinderFactory
+#
+# PDP RESTful API properties
+#
+# Set this to the address where the XACML-PAP-REST servlet is running
+#
+xacml.rest.pap.url=http://localhost:9090/pap/
+#
+# Give the running PDP an ID for the PAP. The url that its running as is a good choice.
+# The PAP identifies PDP's using the URL of the PDP.
+#
+xacml.rest.pdp.id=http://localhost:8080/pdp/
+#
+# Set the directory where the PDP holds its Policy Cache and PIP Configuration
+#
+xacml.rest.pdp.config=config
+#
+# Initialize register with PAP servlet
+#
+xacml.rest.pdp.register=true
+#
+# Sleep period in seconds between register attempts
+#
+xacml.rest.pdp.register.sleep=15
+#
+# number of attempts to register. -1 means keep trying forever.
+#
+xacml.rest.pdp.register.retries=-1
+#
+# max number of bytes in a POST of a XML/JSON request
+#
+xacml.rest.pdp.maxcontent=32767
\ No newline at end of file
diff --git a/openaz-xacml-pdp/logging.properties b/openaz-xacml-pdp/logging.properties
new file mode 100755
index 0000000..ef56def
--- /dev/null
+++ b/openaz-xacml-pdp/logging.properties
@@ -0,0 +1,9 @@
+handlers = java.util.logging.ConsoleHandler, java.util.logging.FileHandler
+
+.level = ALL
+
+java.util.logging.ConsoleHandler.level = INFO
+java.util.logging.FileHandler.level = INFO
+java.util.logging.FileHandler.pattern=%h/xacml_log%u.log
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
diff --git a/openaz-xacml-pdp/pom.xml b/openaz-xacml-pdp/pom.xml
new file mode 100755
index 0000000..e55bdf4
--- /dev/null
+++ b/openaz-xacml-pdp/pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>openaz</artifactId>
+ <groupId>org.openliberty.openaz</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>openaz-xacml-pdp</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>openaz-xacml</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngine.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngine.java
new file mode 100755
index 0000000..c3c0bfb
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngine.java
@@ -0,0 +1,255 @@
+/*
+ * 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;
+
+import java.net.URI;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.AttributeCategory;
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.Response;
+import com.att.research.xacml.api.Result;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.api.pdp.PDPException;
+import com.att.research.xacml.api.pdp.ScopeResolver;
+import com.att.research.xacml.api.trace.TraceEngine;
+import com.att.research.xacml.api.trace.TraceEngineFactory;
+import com.att.research.xacml.api.trace.Traceable;
+import com.att.research.xacml.std.StdIndividualDecisionRequestGenerator;
+import com.att.research.xacml.std.StdMutableResponse;
+import com.att.research.xacml.std.StdMutableResult;
+import com.att.research.xacml.std.StdResult;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.trace.StdTraceEvent;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContextFactory;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinderResult;
+
+/**
+ * ATTPDPEngine implements the {@link com.att.research.xacml.api.pdp.PDPEngine} interface using the XACML 3.0 specification.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class ATTPDPEngine implements PDPEngine, Traceable {
+ private static final Status STATUS_ADVICE_NA = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Advice not allowed in combined decision");
+ private static final Status STATUS_OBLIGATIONS_NA = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Obligations not allowed in combined decision");
+ private static final Status STATUS_COMBINE_FAILED = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Individual decisions do not match");
+ private static final Result RESULT_ECTX_NULL = new StdMutableResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Null EvaluationContext"));
+
+ /*
+ * These are the profiles that this reference implementation of the PDP engine supports
+ */
+ private static final Set<URI> PROFILES = new HashSet<URI>();
+ static {
+ PROFILES.add(XACML3.ID_PROFILE_MULTIPLE_COMBINED_DECISION.getUri());
+ PROFILES.add(XACML3.ID_PROFILE_MULTIPLE_REFERENCE.getUri());
+ PROFILES.add(XACML3.ID_PROFILE_MULTIPLE_REPEATED_ATTRIBUTE_CATEGORIES.getUri());
+ PROFILES.add(XACML3.ID_PROFILE_MULTIPLE_SCOPE.getUri());
+ PROFILES.add(XACML3.ID_PROFILE_MULTIPLE_XPATH_EXPRESSION.getUri());
+ }
+
+ private EvaluationContextFactory evaluationContextFactory;
+ private Decision defaultDecision = Decision.INDETERMINATE;
+ private ScopeResolver scopeResolver;
+ private TraceEngine traceEngine;
+ private Log logger = LogFactory.getLog(this.getClass());
+
+ protected TraceEngine getTraceEngine() {
+ if (this.traceEngine == null) {
+ synchronized(this) {
+ if (this.traceEngine == null) {
+ try {
+ this.traceEngine = TraceEngineFactory.newInstance().getTraceEngine();
+ } catch (FactoryException ex) {
+ this.logger.error("FactoryException creating TraceEngine instance: " + ex.toString(), ex);
+ throw new IllegalStateException("FactoryException creating TraceEngine instance", ex);
+ }
+ }
+ }
+ }
+ return this.traceEngine;
+ }
+
+ public ATTPDPEngine(EvaluationContextFactory evaluationContextFactoryIn, ScopeResolver scopeResolverIn) {
+ this.evaluationContextFactory = evaluationContextFactoryIn;
+ this.scopeResolver = scopeResolverIn;
+ }
+
+ public ATTPDPEngine(EvaluationContextFactory evaluationContextFactoryIn, Decision defaultDecisionIn, ScopeResolver scopeResolverIn) {
+ this(evaluationContextFactoryIn, scopeResolverIn);
+ this.defaultDecision = defaultDecisionIn;
+ }
+
+ public ATTPDPEngine(EvaluationContextFactory evaluationContextFactoryIn, Decision defaultDecisionIn, ScopeResolver scopeResolverIn, Properties properties) {
+ this(evaluationContextFactoryIn, defaultDecisionIn, scopeResolverIn);
+ }
+
+ protected Result processRequest(EvaluationContext evaluationContext) {
+ try {
+ PolicyFinderResult<PolicyDef> policyFinderResult = evaluationContext.getRootPolicyDef();
+ if (policyFinderResult.getStatus() != null && !policyFinderResult.getStatus().isOk()) {
+ return new StdMutableResult(policyFinderResult.getStatus());
+ }
+ PolicyDef policyDefRoot = policyFinderResult.getPolicyDef();
+ if (policyDefRoot == null) {
+ switch(this.defaultDecision) {
+ case DENY:
+ case NOTAPPLICABLE:
+ case PERMIT:
+ return new StdMutableResult(this.defaultDecision, new StdStatus(StdStatusCode.STATUS_CODE_OK, "No applicable policy"));
+ case INDETERMINATE:
+ case INDETERMINATE_DENY:
+ case INDETERMINATE_DENYPERMIT:
+ case INDETERMINATE_PERMIT:
+ return new StdMutableResult(this.defaultDecision, new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No applicable policy"));
+ }
+ }
+ Result result = policyDefRoot.evaluate(evaluationContext);
+ if (result.getStatus().isOk()) {
+ Collection<AttributeCategory> listRequestAttributesIncludeInResult = evaluationContext.getRequest().getRequestAttributesIncludedInResult();
+ if (listRequestAttributesIncludeInResult != null && listRequestAttributesIncludeInResult.size() > 0) {
+ StdMutableResult stdMutableResult = new StdMutableResult(result);
+ stdMutableResult.addAttributeCategories(listRequestAttributesIncludeInResult);
+ result = new StdResult(stdMutableResult);
+ }
+ }
+ return result;
+ } catch (EvaluationException ex) {
+ return new StdMutableResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage()));
+ }
+ }
+
+ @Override
+ public Response decide(Request pepRequest) throws PDPException {
+ /*
+ * Validate the request
+ */
+ TraceEngine traceEngineThis = this.getTraceEngine();
+ if (traceEngineThis.isTracing()) {
+ traceEngineThis.trace(new StdTraceEvent<Request>("Input Request", this, pepRequest));
+ }
+ Status statusRequest = pepRequest.getStatus();
+ if (statusRequest != null && !statusRequest.isOk()) {
+ return new StdMutableResponse(statusRequest);
+ }
+
+ /*
+ * Split the original request up into individual decision requests
+ */
+ StdIndividualDecisionRequestGenerator stdIndividualDecisionRequestGenerator = new StdIndividualDecisionRequestGenerator(this.scopeResolver, pepRequest);
+ /*
+ * Determine if we are combining multiple results into a single result
+ */
+ boolean bCombineResults = pepRequest.getCombinedDecision();
+ StdMutableResult stdResultCombined = null;
+
+ /*
+ * Iterate over all of the individual decision requests and process them, combining them into the final response
+ */
+ StdMutableResponse stdResponse = new StdMutableResponse();
+ Iterator<Request> iterRequestsIndividualDecision = stdIndividualDecisionRequestGenerator.getIndividualDecisionRequests();
+ if (iterRequestsIndividualDecision == null || !iterRequestsIndividualDecision.hasNext()) {
+ return new StdMutableResponse(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No individual decision requests"));
+ }
+
+ while (iterRequestsIndividualDecision.hasNext()) {
+ Request requestIndividualDecision = iterRequestsIndividualDecision.next();
+ if (traceEngineThis.isTracing()) {
+ traceEngineThis.trace(new StdTraceEvent<Request>("Individual Request", this, requestIndividualDecision));
+ }
+ Result resultIndividualDecision = null;
+ if (requestIndividualDecision.getStatus() != null && !requestIndividualDecision.getStatus().isOk()) {
+ resultIndividualDecision = new StdMutableResult(requestIndividualDecision.getStatus());
+ } else {
+ EvaluationContext evaluationContext = this.evaluationContextFactory.getEvaluationContext(requestIndividualDecision);
+ if (evaluationContext == null) {
+ resultIndividualDecision = RESULT_ECTX_NULL;
+ } else {
+ resultIndividualDecision = this.processRequest(evaluationContext);
+ }
+ }
+
+ assert(resultIndividualDecision != null);
+ if (traceEngineThis.isTracing()) {
+ traceEngineThis.trace(new StdTraceEvent<Result>("Individual Result", this, resultIndividualDecision));
+ }
+ if (bCombineResults) {
+ Decision decision = resultIndividualDecision.getDecision();
+ Status status = resultIndividualDecision.getStatus();
+ if (resultIndividualDecision.getAssociatedAdvice().size() > 0) {
+ decision = Decision.INDETERMINATE;
+ status = STATUS_ADVICE_NA;
+ } else if (resultIndividualDecision.getObligations().size() > 0) {
+ decision = Decision.INDETERMINATE;
+ status = STATUS_OBLIGATIONS_NA;
+ }
+
+ if (stdResultCombined == null) {
+ stdResultCombined = new StdMutableResult(decision, status);
+ } else {
+ if (stdResultCombined.getDecision() != resultIndividualDecision.getDecision()) {
+ stdResultCombined.setDecision(Decision.INDETERMINATE);
+ stdResultCombined.setStatus(STATUS_COMBINE_FAILED);
+ }
+ }
+ stdResultCombined.addPolicyIdentifiers(resultIndividualDecision.getPolicyIdentifiers());
+ stdResultCombined.addPolicySetIdentifiers(resultIndividualDecision.getPolicySetIdentifiers());
+ stdResultCombined.addAttributeCategories(resultIndividualDecision.getAttributes());
+ if (traceEngineThis.isTracing()) {
+ traceEngineThis.trace(new StdTraceEvent<Result>("Combined result", this, stdResultCombined));
+ }
+ } else {
+ stdResponse.add(resultIndividualDecision);
+ }
+ }
+
+ if (bCombineResults) {
+ stdResponse.add(stdResultCombined);
+ }
+ return stdResponse;
+ }
+
+ @Override
+ public Collection<URI> getProfiles() {
+ return Collections.unmodifiableCollection(PROFILES);
+ }
+
+ @Override
+ public boolean hasProfile(URI uriProfile) {
+ return PROFILES.contains(uriProfile);
+ }
+
+ @Override
+ public String getTraceId() {
+ return this.getClass().getCanonicalName();
+ }
+
+ @Override
+ public Traceable getCause() {
+ return null;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.java
new file mode 100755
index 0000000..7bd165a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.api.pdp.PDPEngineFactory;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContextFactory;
+
+/**
+ * ATTPDPEngineFactory extends {@link com.att.research.xacml.api.pdp.PDPEngineFactory} by implementing the abstract
+ * <code>newEngine</code> method to create a {@link ATTPDPEngine} instance and initialize it
+ * with policies and PIP instances based on configuration information provided to the factory.
+ *
+ * @author car
+ * @version $Revision: 1.4 $
+ */
+public class ATTPDPEngineFactory extends PDPEngineFactory {
+ private Log logger = LogFactory.getLog(this.getClass());
+
+ public ATTPDPEngineFactory() {
+ }
+
+ @Override
+ public PDPEngine newEngine() throws FactoryException {
+ EvaluationContextFactory evaluationContextFactory = EvaluationContextFactory.newInstance();
+ if (evaluationContextFactory == null) {
+ this.logger.error("Null EvaluationContextFactory");
+ throw new FactoryException("Null EvaluationContextFactory");
+ }
+ return new ATTPDPEngine(evaluationContextFactory, this.getDefaultBehavior(), this.getScopeResolver());
+ }
+
+ @Override
+ public PDPEngine newEngine(Properties properties) throws FactoryException {
+ EvaluationContextFactory evaluationContextFactory = EvaluationContextFactory.newInstance(properties);
+ if (evaluationContextFactory == null) {
+ this.logger.error("Null EvaluationContextFactory");
+ throw new FactoryException("Null EvaluationContextFactory");
+ }
+ return new ATTPDPEngine(evaluationContextFactory, this.getDefaultBehavior(), this.getScopeResolver(), properties);
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Evaluatable.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Evaluatable.java
new file mode 100755
index 0000000..24adb1d
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Evaluatable.java
@@ -0,0 +1,23 @@
+/*
+ * 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.eval;
+
+/**
+ * Evaluatable is the interface objects implement to indicate they can be evaluated with an {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}
+ * and return an {@link com.att.research.xacmlatt.pdp.eval.EvaluationResult}.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public interface Evaluatable {
+ public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException;
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContext.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContext.java
new file mode 100755
index 0000000..321fff1
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContext.java
@@ -0,0 +1,73 @@
+/*
+ * 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.eval;
+
+import com.att.research.xacml.api.IdReferenceMatch;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.pip.PIPException;
+import com.att.research.xacml.api.pip.PIPFinder;
+import com.att.research.xacml.api.pip.PIPRequest;
+import com.att.research.xacml.api.pip.PIPResponse;
+import com.att.research.xacml.api.trace.TraceEngine;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinderResult;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+
+/**
+ * EvaluationContext provides the interface that the PDP uses to evaluate its set of Policies and PolicySets against
+ * a {@link com.att.research.xacml.api.Request}.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public interface EvaluationContext extends PIPFinder, TraceEngine {
+ /**
+ * Gets the original <code>Request</code> provided to the <code>ATTPDPEngine</code>'s <code>decide</code> method.
+ *
+ * @return the <code>Request</code> provided to the <code>ATTPDPEngine</code>'s <code>decide</code> method.
+ */
+ public Request getRequest();
+
+ /**
+ * Gets the root {@link com.att.research.xacmlatt.pdp.policy.PolicyDef} from the policy store
+ * configured by the particular implementation of the <code>PolicyFinderFactory</code> class.
+ *
+ * @return a <code>PolicyFinderResult</code> with the root <code>PolicyDef</code>
+ */
+ public abstract PolicyFinderResult<PolicyDef> getRootPolicyDef();
+
+ /**
+ * Gets the {@link com.att.research.xacmlatt.pdp.policy.Policy} that matches the given {@link com.att.research.xacml.api.IdReferenceMatch}.
+ *
+ * @param idReferenceMatch the <code>IdReferenceMatch</code> to search for
+ * @return a <code>PolicyFinderResult</code> with the <code>Policy</code> matching the given <code>IdReferenceMatch</code>
+ */
+ public abstract PolicyFinderResult<Policy> getPolicy(IdReferenceMatch idReferenceMatch);
+
+ /**
+ * Gets the {@link com.att.research.xacmlatt.pdp.policy.PolicySet} that matches the given {@link com.att.research.xacml.api.IdReferenceMatch}.
+ *
+ * @param idReferenceMatch the <code>IdReferenceMatch</code> to search for
+ * @return a <code>PolicyFinderResult</code> with the <code>PolicySet</code> matching the given <code>IdReferenceMatch</code>.
+ */
+ public abstract PolicyFinderResult<PolicySet> getPolicySet(IdReferenceMatch idReferenceMatch);
+
+ /**
+ * Gets the {@link com.att.research.xacml.api.pip.PIPResponse} containing {@link com.att.research.xacml.api.Attribute}s that
+ * match the given {@link com.att.research.xacml.api.pip.PIPRequest} from this <code>EvaluationContext</code>.
+ *
+ * @param pipRequest the <code>PIPRequest</code> specifying which <code>Attribute</code>s to retrieve
+ * @return the <code>PIPResponse</code> containing the {@link com.att.research.xacml.api.Status} and <code>Attribute</code>s
+ * @throws EvaluationException if there is an error retrieving the <code>Attribute</code>s
+ */
+ public PIPResponse getAttributes(PIPRequest pipRequest) throws PIPException;
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.java
new file mode 100755
index 0000000..d814961
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.java
@@ -0,0 +1,42 @@
+/*
+ * 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.eval;
+
+/**
+ * EvaluationContextException extends <code>Exception</code> to represent errors thrown by
+ * methods in the {@link EvaluationContext} and {@link EvaluationContextFactory}.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class EvaluationContextException extends Exception {
+ private static final long serialVersionUID = -8270506903118536839L;
+
+ public EvaluationContextException() {
+ }
+
+ public EvaluationContextException(String message) {
+ super(message);
+ }
+
+ public EvaluationContextException(Throwable cause) {
+ super(cause);
+ }
+
+ public EvaluationContextException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public EvaluationContextException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.java
new file mode 100755
index 0000000..4f54deb
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.java
@@ -0,0 +1,79 @@
+/*
+ * 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.eval;
+
+import java.util.Properties;
+
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.pip.PIPFinder;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.FactoryFinder;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinder;
+import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
+
+/**
+ * EvaluationContextFactory provides methods for creating {@link EvaluationContext} objects
+ * based on configuration information found in standard places. (TODO: Detail what these are)
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public abstract class EvaluationContextFactory {
+ private static final String FACTORYID = ATTPDPProperties.PROP_EVALUATIONCONTEXTFACTORY;
+ private static final String DEFAULT_FACTORY_CLASSNAME = "com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory";
+
+ protected EvaluationContextFactory() {
+ }
+
+ protected EvaluationContextFactory(Properties properties) {
+ }
+
+ public static EvaluationContextFactory newInstance() throws FactoryException {
+ return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, EvaluationContextFactory.class);
+ }
+
+ public static EvaluationContextFactory newInstance(Properties properties) throws FactoryException {
+ return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, EvaluationContextFactory.class, properties);
+ }
+
+ public static EvaluationContextFactory newInstance(String className, ClassLoader classLoader) throws FactoryException {
+ return FactoryFinder.newInstance(className, EvaluationContextFactory.class, classLoader, false);
+ }
+
+ public static EvaluationContextFactory newInstance(String className) throws FactoryException {
+ return FactoryFinder.newInstance(className, EvaluationContextFactory.class, null, true);
+ }
+
+ /**
+ * Gets a new {@link com.att.research.xacml.pdp.eval.EvaluationContext} for the given {@link com.att.research.xacml.api.Request}.
+ *
+ * @param request the <code>Request</code> for the new <code>EvaluationContext</code>
+ * @return a new <code>EvaluationContext</code> for the given <code>Request</code>
+ */
+ public abstract EvaluationContext getEvaluationContext(Request request);
+
+ /**
+ * Sets the {@link com.att.research.xacmlatt.pdp.policy.PolicyFinder} for this <code>EvaluationContextFactory</code> to an
+ * explicit instance instead of the default or configured value.
+ *
+ * @param policyFinder the <code>PolicyFinder</code> to use in creating new <code>EvaluationContext</code>s.
+ */
+ public abstract void setPolicyFinder(PolicyFinder policyFinder);
+
+ /**
+ * Sets the {@link com.att.research.xacml.api.pip.PIPFinder} for this <code>EvaluationContextFactory</code> to an
+ * explicit instance instaed of the default or configured value.
+ *
+ * @param pipFinder the <code>PIPFinder</code> to use in creating new <code>EvaluationContext</code>s.
+ */
+ public abstract void setPIPFinder(PIPFinder pipFinder);
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationException.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationException.java
new file mode 100755
index 0000000..0a0b49a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationException.java
@@ -0,0 +1,43 @@
+/*
+ * 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.eval;
+
+/**
+ * EvaluationException extends <code>Exception</code> to represent errors returned by methods of the
+ * {@link Evaluatable} interface and the {@link Matchable} interface.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class EvaluationException extends Exception {
+ private static final long serialVersionUID = 302250127793947492L;
+
+ public EvaluationException() {
+ }
+
+ public EvaluationException(String message) {
+ super(message);
+ }
+
+ public EvaluationException(Throwable cause) {
+ super(cause);
+ }
+
+ public EvaluationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public EvaluationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationResult.java
new file mode 100755
index 0000000..78828e5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationResult.java
@@ -0,0 +1,80 @@
+/*
+ * 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.eval;
+
+import java.util.Collection;
+
+import com.att.research.xacml.api.Advice;
+import com.att.research.xacml.api.AttributeCategory;
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.IdReference;
+import com.att.research.xacml.api.Obligation;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdMutableResult;
+
+/**
+ * EvaluationResult extends {@link com.att.research.xacml.std.StdMutableResult} with methods useful within a PDP implementation
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class EvaluationResult extends StdMutableResult {
+ public EvaluationResult() {
+ super();
+ }
+
+ public EvaluationResult(Decision decisionIn, Status statusIn) {
+ super(decisionIn, statusIn);
+ }
+
+ public EvaluationResult(Status statusIn) {
+ super(statusIn);
+ }
+
+ public EvaluationResult(Decision decisionIn) {
+ super(decisionIn);
+ }
+
+ public EvaluationResult(Decision decisionIn,
+ Collection<Obligation> obligationsIn,
+ Collection<Advice> adviceIn,
+ Collection<AttributeCategory> attributesIn,
+ Collection<IdReference> policyIdentifiersIn,
+ Collection<IdReference> policySetIdentifiersIn) {
+ super(decisionIn, obligationsIn, adviceIn, attributesIn, policyIdentifiersIn, policySetIdentifiersIn);
+ }
+
+ /**
+ * Creates an <code>EvaluationResult</code> generally from a {@link com.att.research.xacmlatt.pdp.policy.Rule} <code>evaluation</code>
+ * call.
+ *
+ * @param decisionIn the <code>Decision</code>
+ * @param obligationsIn the <code>Collection</code> of <code>Obligation</code>s
+ * @param adviceIn the <code>Collection</code> of <code>Advice</code> objects
+ */
+ public EvaluationResult(Decision decisionIn, Collection<Obligation> obligationsIn, Collection<Advice> adviceIn) {
+ super(decisionIn, obligationsIn, adviceIn, null, null, null);
+ }
+
+ public void merge(EvaluationResult evaluationResult) {
+ if (this.getStatus() == null) {
+ this.setStatus(evaluationResult.getStatus());
+ } else {
+ this.getStatus().merge(evaluationResult.getStatus());
+ }
+ this.addObligations(evaluationResult.getObligations());
+ this.addAdvice(evaluationResult.getAssociatedAdvice());
+ this.addAttributeCategories(evaluationResult.getAttributes());
+ this.addPolicyIdentifiers(evaluationResult.getPolicyIdentifiers());
+ this.addPolicySetIdentifiers(evaluationResult.getPolicySetIdentifiers());
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/MatchResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/MatchResult.java
new file mode 100755
index 0000000..4398b79
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/MatchResult.java
@@ -0,0 +1,71 @@
+/*
+ * 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.eval;
+
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+
+/**
+ * MatchResult is the value returned by the {@link Matchable} interface.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class MatchResult {
+ public static enum MatchCode {
+ INDETERMINATE,
+ MATCH,
+ NOMATCH
+ }
+
+ public static MatchResult MM_MATCH = new MatchResult(MatchCode.MATCH);
+ public static MatchResult MM_NOMATCH = new MatchResult(MatchCode.NOMATCH);
+
+ private MatchCode matchCode;
+ private Status status;
+
+ public MatchResult(MatchCode matchCodeIn, Status statusIn) {
+ this.matchCode = matchCodeIn;
+ this.status = statusIn;
+ }
+
+ public MatchResult(MatchCode matchCodeIn) {
+ this(matchCodeIn, StdStatus.STATUS_OK);
+ }
+
+ public MatchResult(Status statusIn) {
+ this(MatchCode.INDETERMINATE, statusIn);
+ }
+
+ public MatchCode getMatchCode() {
+ return this.matchCode;
+ }
+
+ public Status getStatus() {
+ return this.status;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+
+ stringBuilder.append("matchCode=");
+ stringBuilder.append(this.getMatchCode());
+ Status thisStatus = this.getStatus();
+ if (thisStatus != null) {
+ stringBuilder.append(", status=");
+ stringBuilder.append(thisStatus.toString());
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Matchable.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Matchable.java
new file mode 100755
index 0000000..0550b07
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Matchable.java
@@ -0,0 +1,30 @@
+/*
+ * 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.eval;
+
+/**
+ * Matchable is the interface objects implement to indicate they are part of a XACML Target matching tree.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public interface Matchable {
+ /**
+ * Matches this <code>Matchable</code> in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} and
+ * returns a {@link com.att.research.xacmlatt.pdp.eval.MatchResult}.
+ *
+ * @param evaluationContext the <code>EvaluationContext</code> to use in matching
+ * @return a <code>MatchResult</code> indicating whether this <code>Matchable</code> matches against the given <code>EvaluationContext</code>.
+ * @throws EvaluationException if there is an error testing the match.
+ */
+ public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException;
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/package-info.java
new file mode 100755
index 0000000..eb01ff5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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.eval;
+
+/**
+ * com.att.research.xacmlatt.pdp.eval contains interfaces and classes used in evaluating and matching XACML policy components.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/package-info.java
new file mode 100755
index 0000000..b6c251b
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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;
+
+/**
+ * com.att.research.xacmlatt.pdp contains a reference implementation of the {@link com.att.research.xacml.pdp.PDPEngine} interface
+ * developed at AT&T Laboratories.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AdviceExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AdviceExpression.java
new file mode 100755
index 0000000..9ef9adc
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AdviceExpression.java
@@ -0,0 +1,201 @@
+/*
+ * 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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Advice;
+import com.att.research.xacml.api.AttributeAssignment;
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdMutableAdvice;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+
+/**
+ * AdviceExpression extends {@link PolicyComponent} to implement the XACML AdviceExpression element.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class AdviceExpression extends PolicyComponent {
+ private List<AttributeAssignmentExpression> listAttributeAssignmentExpressions = new ArrayList<AttributeAssignmentExpression>();
+ private Identifier adviceId;
+ private RuleEffect appliesTo;
+
+ protected List<AttributeAssignmentExpression> getAttributeAssignmentExpressionList() {
+ return this.listAttributeAssignmentExpressions;
+ }
+
+ protected void clearAttributeAssignmentExpressionList() {
+ this.getAttributeAssignmentExpressionList().clear();
+ }
+
+ public AdviceExpression(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public AdviceExpression(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public AdviceExpression() {
+ }
+
+ public AdviceExpression(Identifier adviceIdIn, RuleEffect ruleEffectIn, Collection<AttributeAssignmentExpression> attributeAssignmentExpressions) {
+ this.adviceId = adviceIdIn;
+ this.appliesTo = ruleEffectIn;
+ if (attributeAssignmentExpressions != null) {
+ this.listAttributeAssignmentExpressions.addAll(attributeAssignmentExpressions);
+ }
+ }
+
+ public Identifier getAdviceId() {
+ return this.adviceId;
+ }
+
+ public void setAdviceId(Identifier identifier) {
+ this.adviceId = identifier;
+ }
+
+ public RuleEffect getAppliesTo() {
+ return this.appliesTo;
+ }
+
+ public void setAppliesTo(RuleEffect ruleEffect) {
+ this.appliesTo = ruleEffect;
+ }
+
+ public Iterator<AttributeAssignmentExpression> getAttributeAssignmentExpressions() {
+ return this.getAttributeAssignmentExpressionList().iterator();
+ }
+
+ public void setAttributeAssignmentExpressions(Collection<AttributeAssignmentExpression> attributeAssignmentExpressions) {
+ this.clearAttributeAssignmentExpressionList();
+ if (attributeAssignmentExpressions != null) {
+
+ }
+ }
+
+ public void addAttributeAssignmentExpression(AttributeAssignmentExpression attributeAssignmentExpression) {
+ this.getAttributeAssignmentExpressionList().add(attributeAssignmentExpression);
+ }
+
+ public void addAttributeAssignmentExpressions(Collection<AttributeAssignmentExpression> attributeAssignmentExpressions) {
+ this.getAttributeAssignmentExpressionList().addAll(attributeAssignmentExpressions);
+ }
+
+ /**
+ * Evaluates the <code>AttributeAssignmentExpression</code>s in this <code>AdviceExpression</code> to generate an
+ * {@link com.att.research.xacml.api.Advice} object.
+ *
+ * @param evaluationContext the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} in which to evaluate the <code>AttributeAssignmentExpression</code>s
+ * @param policyDefaults the {@link PolicyDefaults} for the evaluation
+ * @return a new <code>Advice</code> evaluated from this <code>AdviceExpression</code>
+ * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException if there is an error in the evaluation
+ */
+ public Advice evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+ if (!this.validate()) {
+ return null;
+ }
+
+ List<AttributeAssignment> attributeAssignments = new ArrayList<AttributeAssignment>();
+ Iterator<AttributeAssignmentExpression> iterAttributeAssignmentExpressions = this.getAttributeAssignmentExpressions();
+ if (iterAttributeAssignmentExpressions != null) {
+ while (iterAttributeAssignmentExpressions.hasNext()) {
+ AttributeAssignmentResult attributeAssignmentResult = iterAttributeAssignmentExpressions.next().evaluate(evaluationContext, policyDefaults);
+ if (attributeAssignmentResult.isOk() && attributeAssignmentResult.getNumAttributeAssignments() > 0) {
+ Iterator<AttributeAssignment> iterAttributeAssignments = attributeAssignmentResult.getAttributeAssignments();
+ while (iterAttributeAssignments.hasNext()) {
+ attributeAssignments.add(iterAttributeAssignments.next());
+ }
+ }
+ }
+ }
+
+ return new StdMutableAdvice(this.getAdviceId(), attributeAssignments);
+ }
+
+ /**
+ * Evaluates a <code>Collection</code> of <code>AdviceExpression</code>s in the given <code>EvaluationContext</code> and returns
+ * a <code>List</code> of <code>Advice</code>s.
+ *
+ * @param evaluationContext
+ * @param policyDefaults
+ * @param listAdviceExpressions
+ * @return
+ * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException
+ */
+ public static List<Advice> evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults, Decision decision, Collection<AdviceExpression> listAdviceExpressions) throws EvaluationException {
+ List<Advice> listAdvices = new ArrayList<Advice>();
+ Iterator<AdviceExpression> iterAdviceExpressions = listAdviceExpressions.iterator();
+ while (iterAdviceExpressions.hasNext()) {
+ AdviceExpression adviceExpression = iterAdviceExpressions.next();
+ adviceExpression.validateComponent();
+ if ( ! adviceExpression.isOk()) {
+ throw new EvaluationException(adviceExpression.getStatusMessage());
+ }
+ if (decision == null || adviceExpression.getAppliesTo().getDecision().equals(decision)) {
+ Advice advice = adviceExpression.evaluate(evaluationContext, policyDefaults);
+ if (advice != null) {
+ listAdvices.add(advice);
+ }
+ }
+ }
+ return listAdvices;
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (this.getAdviceId() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AdviceId");
+ return false;
+ } else if (this.getAppliesTo() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AppliesTo");
+ return false;
+ } else {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ Object objectToDump;
+ if ((objectToDump = this.getAdviceId()) != null) {
+ stringBuilder.append(",adviceId=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ if ((objectToDump = this.getAppliesTo()) != null) {
+ stringBuilder.append(",appliesTo=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ if ((objectToDump = StringUtils.toString(this.getAttributeAssignmentExpressions())) != null) {
+ stringBuilder.append(",attributeAssignmentExpressions=");
+ stringBuilder.append((String)objectToDump);
+ }
+
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AllOf.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AllOf.java
new file mode 100755
index 0000000..721750a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AllOf.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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+import com.att.research.xacmlatt.pdp.eval.Matchable;
+
+/**
+ * AnyOf extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} and implements the {@link com.att.research.xacmlatt.pdp.policy.Matchable}
+ * interface to represent XACML AllOf elements in a XACML Target.
+ *
+ * @author car
+ * @version $Revision
+ */
+public class AllOf extends PolicyComponent implements Matchable {
+ private List<Match> matches;
+
+ protected List<Match> getMatchList(boolean bNoNulls) {
+ if (this.matches == null && bNoNulls) {
+ this.matches = new ArrayList<Match>();
+ }
+ return this.matches;
+ }
+
+ protected void clearMatchList() {
+ if (this.matches != null) {
+ this.matches.clear();
+ }
+ }
+
+ public AllOf(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public AllOf(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public AllOf() {
+ }
+
+ public Iterator<Match> getMatches() {
+ return (this.matches == null ? null : this.matches.iterator());
+ }
+
+ public void setMatches(Collection<Match> matchesIn) {
+ this.clearMatchList();
+ if (matchesIn != null) {
+ this.addMatches(matchesIn);
+ }
+ }
+
+ public void addMatch(Match match) {
+ List<Match> matchList = this.getMatchList(true);
+ matchList.add(match);
+ }
+
+ public void addMatches(Collection<Match> matchesIn) {
+ List<Match> matchList = this.getMatchList(true);
+ matchList.addAll(matchesIn);
+ }
+
+ @Override
+ public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException {
+ if (!this.validate()) {
+ return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+ Iterator<Match> iterMatches = this.getMatches();
+ assert(iterMatches != null && iterMatches.hasNext());
+
+ MatchResult matchResultFallThrough = MatchResult.MM_MATCH;
+ while (iterMatches.hasNext()) {
+ MatchResult matchResultMatch = iterMatches.next().match(evaluationContext);
+ assert(matchResultMatch != null);
+ switch(matchResultMatch.getMatchCode()) {
+ case INDETERMINATE:
+ if (matchResultFallThrough.getMatchCode() != MatchResult.MatchCode.INDETERMINATE) {
+ matchResultFallThrough = matchResultMatch;
+ }
+ break;
+ case MATCH:
+ break;
+ case NOMATCH:
+ return matchResultMatch;
+ }
+ }
+ return matchResultFallThrough;
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ Iterator<Match> iterMatches = this.getMatches();
+ if (iterMatches == null || !iterMatches.hasNext()) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing matches");
+ return false;
+ } else {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ String stringMatches = StringUtils.toString(this.getMatches());
+ if (stringMatches != null) {
+ stringBuilder.append(",matches=");
+ stringBuilder.append(stringMatches);
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AnyOf.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AnyOf.java
new file mode 100755
index 0000000..749904f
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AnyOf.java
@@ -0,0 +1,150 @@
+/*
+ * 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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+import com.att.research.xacmlatt.pdp.eval.Matchable;
+
+/**
+ * AnyOf extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} and implements the {@link com.att.research.xacmlatt.pdp.policy.Matchable}
+ * interface to represent XACML AnyOf elements in a XACML Target.
+ *
+ * @author car
+ * @version $Revision
+ */
+public class AnyOf extends PolicyComponent implements Matchable {
+ private List<AllOf> allOfs;
+
+ protected List<AllOf> getAllOfList(boolean bNoNull) {
+ if (this.allOfs == null && bNoNull) {
+ this.allOfs = new ArrayList<AllOf>();
+ }
+ return this.allOfs;
+ }
+
+ protected void clearAllOfList() {
+ if (this.allOfs != null) {
+ this.allOfs.clear();
+ }
+ }
+
+ public AnyOf(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public AnyOf(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public AnyOf() {
+ }
+
+ public AnyOf(Collection<AllOf> allOfsIn) {
+ if (allOfsIn != null) {
+ this.addAllOfs(allOfsIn);
+ }
+ }
+
+ public Iterator<AllOf> getAllOfs() {
+ return (this.allOfs == null ? null : this.allOfs.iterator());
+ }
+
+ public void setAllOfs(Collection<AllOf> allOfsIn) {
+ this.clearAllOfList();
+ if (allOfsIn != null) {
+ this.addAllOfs(allOfsIn);
+ }
+ }
+
+ public void addAllOf(AllOf allOf) {
+ List<AllOf> listAllOfs = this.getAllOfList(true);
+ listAllOfs.add(allOf);
+ }
+
+ public void addAllOfs(Collection<AllOf> allOfs) {
+ List<AllOf> listAllOfs = this.getAllOfList(true);
+ listAllOfs.addAll(allOfs);
+ }
+
+ @Override
+ public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException {
+ if (!this.validate()) {
+ return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+ Iterator<AllOf> iterAllOfs = this.getAllOfs();
+ if (iterAllOfs == null || !iterAllOfs.hasNext()) {
+ return MatchResult.MM_NOMATCH;
+ }
+
+ /*
+ * Assume "No Match" until we find a match or an indeterminate result
+ */
+ MatchResult matchResultFallThrough = MatchResult.MM_NOMATCH;
+ while (iterAllOfs.hasNext()) {
+ MatchResult matchResultAllOf = iterAllOfs.next().match(evaluationContext);
+ assert(matchResultAllOf != null);
+ switch(matchResultAllOf.getMatchCode()) {
+ case INDETERMINATE:
+ /*
+ * Keep the first indeterminate value to return if no other match is found
+ */
+ if (matchResultFallThrough.getMatchCode() != MatchResult.MatchCode.INDETERMINATE) {
+ matchResultFallThrough = matchResultAllOf;
+ }
+ break;
+ case MATCH:
+ return matchResultAllOf;
+ case NOMATCH:
+ break;
+ }
+ }
+ return matchResultFallThrough;
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ Iterator<AllOf> iterAllOfs = this.getAllOfs();
+ if (iterAllOfs == null || !iterAllOfs.hasNext()) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AllOf elements in AnyOf");
+ return false;
+ } else {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ String iterToDump = StringUtils.toString(this.getAllOfs());
+ if (iterToDump != null) {
+ stringBuilder.append(",allOfs=");
+ stringBuilder.append(iterToDump);
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.java
new file mode 100755
index 0000000..047fff8
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.java
@@ -0,0 +1,166 @@
+/*
+ * 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.policy;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.AttributeAssignment;
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdMutableAttributeAssignment;
+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.eval.EvaluationException;
+
+/**
+ * AttributeAssignmentExpression extends {@link PolicyComponent} to represent a
+ * XACML AttributeAssignmentExpression element.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class AttributeAssignmentExpression extends PolicyComponent {
+ private static final AttributeAssignmentResult AAR_NULL_EXPRESSION = new AttributeAssignmentResult(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Null expression"));
+ private static final AttributeAssignmentResult AAR_NULL_EXPRESSION_RESULT = new AttributeAssignmentResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Null expression result"));
+
+ private Expression expression;
+ private Identifier attributeId;
+ private Identifier category;
+ private String issuer;
+
+ public AttributeAssignmentExpression(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public AttributeAssignmentExpression(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public AttributeAssignmentExpression() {
+ }
+
+ public AttributeAssignmentExpression(Identifier categoryIn, Identifier attributeIdIn, String issuerIn, Expression expressionIn) {
+ this.category = categoryIn;
+ this.attributeId = attributeIdIn;
+ this.issuer = issuerIn;
+ this.expression = expressionIn;
+ }
+
+ public Identifier getCategory() {
+ return this.category;
+ }
+
+ public void setCategory(Identifier identifier) {
+ this.category = identifier;
+ }
+
+ public Identifier getAttributeId() {
+ return this.attributeId;
+ }
+
+ public void setAttributeId(Identifier identifier) {
+ this.attributeId = identifier;
+ }
+
+ public String getIssuer() {
+ return this.issuer;
+ }
+
+ public void setIssuer(String string) {
+ this.issuer = string;
+ }
+
+ public Expression getExpression() {
+ return this.expression;
+ }
+
+ public void setExpression(Expression expressionIn) {
+ this.expression = expressionIn;
+ }
+
+ public AttributeAssignmentResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+ if (!this.validate()) {
+ return new AttributeAssignmentResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+
+ Expression thisExpression = this.getExpression();
+ if (thisExpression == null) {
+ return AAR_NULL_EXPRESSION;
+ }
+
+ ExpressionResult thisExpressionResult = thisExpression.evaluate(evaluationContext, policyDefaults);
+ if (thisExpressionResult == null) {
+ return AAR_NULL_EXPRESSION_RESULT;
+ } else if (!thisExpressionResult.isOk()) {
+ return new AttributeAssignmentResult(thisExpressionResult.getStatus());
+ } else {
+ List<AttributeAssignment> listAttributeAssignments = new ArrayList<AttributeAssignment>();
+ if (thisExpressionResult.isBag()) {
+ Bag bagValues = thisExpressionResult.getBag();
+ if (bagValues == null || bagValues.size() == 0) {
+ listAttributeAssignments.add(new StdMutableAttributeAssignment(this.getCategory(), this.getAttributeId(), this.getIssuer(), null));
+ } else {
+ Iterator<AttributeValue<?>> iterBagValues = bagValues.getAttributeValues();
+ while (iterBagValues.hasNext()) {
+ AttributeValue<?> attributeValue = iterBagValues.next();
+ listAttributeAssignments.add(new StdMutableAttributeAssignment(this.getCategory(), this.getAttributeId(), this.getIssuer(), attributeValue));
+ }
+ }
+ } else {
+ listAttributeAssignments.add(new StdMutableAttributeAssignment(this.getCategory(), this.getAttributeId(), this.getIssuer(), thisExpressionResult.getValue()));
+ }
+ return new AttributeAssignmentResult(listAttributeAssignments);
+ }
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (this.getAttributeId() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AttributeId");
+ return false;
+ } else if (this.getExpression() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Expression");
+ return false;
+ } else {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ Object objectToDump;
+ if ((objectToDump = this.getCategory()) != null) {
+ stringBuilder.append(",category=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ if ((objectToDump = this.getAttributeId()) != null) {
+ stringBuilder.append(",attributeId=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ if ((objectToDump = this.getExpression()) != null) {
+ stringBuilder.append(",expression=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.java
new file mode 100755
index 0000000..cc6c549
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.java
@@ -0,0 +1,95 @@
+/*
+ * 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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.AttributeAssignment;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.util.StringUtils;
+
+/**
+ * AttributeAssignmentResult is the object returned by the <code>evaluate</code> method of an {@link com.att.research.xacmlatt.pdp.policy.AttributeAssignmentExpression}.
+ * It contains a {@link com.att.research.xacml.api.Status} and an optional collection of {@link com.att.research.xacml.api.AttributeAssignment}
+ * elements.
+ *
+ * @author car
+ * @version $Revision$
+ */
+public class AttributeAssignmentResult {
+ private Status status;
+ private List<AttributeAssignment> listAttributeAssignments;
+
+ protected List<AttributeAssignment> getListAttributeAssignments() {
+ return this.listAttributeAssignments;
+ }
+
+ public AttributeAssignmentResult(Status statusIn, Collection<AttributeAssignment> listAttributeAssignmentsIn) {
+ this.status = statusIn;
+ if (listAttributeAssignmentsIn != null && listAttributeAssignmentsIn.size() > 0) {
+ this.listAttributeAssignments = new ArrayList<AttributeAssignment>();
+ this.listAttributeAssignments.addAll(listAttributeAssignmentsIn);
+ }
+ }
+
+ public AttributeAssignmentResult(Status statusIn) {
+ this(statusIn, null);
+ }
+
+ public AttributeAssignmentResult(Collection<AttributeAssignment> listAttributeAssignmentsIn) {
+ this(StdStatus.STATUS_OK, listAttributeAssignmentsIn);
+ }
+
+ public Status getStatus() {
+ return this.status;
+ }
+
+ public boolean isOk() {
+ return (this.getStatus() == null || this.getStatus().isOk());
+ }
+
+ public Iterator<AttributeAssignment> getAttributeAssignments() {
+ List<AttributeAssignment> thisListAttributeAssignments = this.getListAttributeAssignments();
+ return (thisListAttributeAssignments == null ? null : thisListAttributeAssignments.iterator());
+ }
+
+ public int getNumAttributeAssignments() {
+ List<AttributeAssignment> thisListAttributeAssignments = this.getListAttributeAssignments();
+ return (thisListAttributeAssignments == null ? 0 : thisListAttributeAssignments.size());
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+ boolean needsComma = false;
+
+ Object objectToDump;
+ if ((objectToDump = this.getStatus()) != null) {
+ stringBuilder.append("status=");
+ stringBuilder.append(objectToDump.toString());
+ needsComma = true;
+ }
+
+ Iterator<?> iterToDump;
+ if ((iterToDump = this.getAttributeAssignments()) != null) {
+ if (needsComma) {
+ stringBuilder.append(',');
+ }
+ stringBuilder.append(StringUtils.toString(iterToDump));
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Bag.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Bag.java
new file mode 100755
index 0000000..47b7773
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Bag.java
@@ -0,0 +1,93 @@
+/*
+ * 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.policy;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.AttributeValue;
+
+/**
+ * Bag represents a collection of XACML attribute values for the same attribute.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class Bag {
+ public static final Bag EMPTY = new Bag();
+
+ private List<AttributeValue<?>> attributeValues = new ArrayList<AttributeValue<?>>();
+
+ /**
+ * Gets the <code>List</code> of <code>AttributeValue</code>s for this <code>Bag</code>.
+ *
+ * @return the <code>List</code> of <code>AttributeValue</code>s for this <code>Bag</code>
+ */
+ public List<AttributeValue<?>> getAttributeValueList() {
+ return this.attributeValues;
+ }
+
+ /**
+ * Creates a new, empty <code>Bag</code>.
+ */
+ public Bag() {
+ }
+
+ /**
+ * Creates a new <code>Bag</code> by copying the {@link com.att.research.xacml.api.AttributeValue}s from the
+ * given <code>Collection</code>.
+ *
+ * @param attributeValuesIn the <code>Collection</code> of <code>AttributeValue</code>s for this <code>Bag</code>.
+ *
+ public Bag(Collection<AttributeValue<?>> attributeValuesIn) {
+ if (attributeValuesIn != null) {
+ this.attributeValues.addAll(attributeValuesIn);
+ }
+ }
+
+ public Bag(Iterator<AttributeValue<?>> iterAttributeValuesIn) {
+ if (iterAttributeValuesIn != null) {
+ while (iterAttributeValuesIn.hasNext()) {
+ this.attributeValues.add(iterAttributeValuesIn.next());
+ }
+ }
+ }
+ */
+
+ /**
+ * Adds an <code>AttributeValue</code> to this <code>Bag</code>>
+ *
+ * @param attributeValue the <code>AttributeValue</code> to add
+ */
+ public void add(AttributeValue<?> attributeValue) {
+ this.attributeValues.add(attributeValue);
+ }
+
+ /**
+ * Gets the number of <code>AttributeValue</code>s in this <code>Bag</code>.
+ *
+ * @return the number of <code>AttributeValue</code>s in this <code>Bag</code>.
+ */
+ public int size() {
+ return this.getAttributeValueList().size();
+ }
+
+ /**
+ * Gets an <code>Iterator</code> over all of the <code>AttributeValue</code>s in this <code>Bag</code>.
+ *
+ * @return an <code>Iterator</code> over all of the <code>AttributeValue</code>s in this <code>Bag</code>.
+ */
+ public Iterator<AttributeValue<?>> getAttributeValues() {
+ return this.getAttributeValueList().iterator();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombinerParameter.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombinerParameter.java
new file mode 100755
index 0000000..8277428
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombinerParameter.java
@@ -0,0 +1,149 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatusCode;
+
+/**
+ * CombinerParameter extends {@link PolicyComponent} to represent a XACML CombinerParameter element.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class CombinerParameter extends PolicyComponent {
+ private String name;
+ private AttributeValue<?> attributeValue;
+
+ @Override
+ protected boolean validateComponent() {
+ if (this.getName() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing parameter name");
+ return false;
+ } else if (this.getAttributeValue() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing attribute value");
+ return false;
+ } else {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+ }
+
+ /**
+ * Creates a new <code>CombinerParameter</code> with the given <code>String</code> name, <code>AttributeValue</code>,
+ * {@link com.att.research.xacml.api.StatusCode} and <code>String</code> status message.
+ *
+ * @param nameIn the <code>String</code> name of the <code>CombinerParameter</code>
+ * @param attributeValueIn the <code>AttributeValue</code> of the <code>CombinerParameter</code>
+ * @param statusCodeIn the <code>StatusCode</code> of the <code>CombinerParameter</code>
+ * @param statusMessageIn the <code>String</code> status message of the <code>CombinerParameter</code>
+ */
+ public CombinerParameter(String nameIn, AttributeValue<?> attributeValueIn, StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ this.name = nameIn;
+ this.attributeValue = attributeValueIn;
+ }
+
+ /**
+ * Creates a new <code>CombinerParameter</code> for an error condition with the given <code>StatusCode</code> and
+ * <code>String</code> status message.
+ *
+ * @param statusCodeIn the <code>StatusCode</code> of the <code>CombinerParameter</code>
+ * @param statusMessageIn the <code>String</code> status message of the <code>CombinerParameter</code>
+ */
+ public CombinerParameter(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ /**
+ * Creates a new <code>CombinerParameter</code> for an error condition with the given <code>StatusCode</code> and
+ * null status message.
+ *
+ * @param statusCodeIn the <code>StatusCode</code> of the <code>CombinerParameter</code>
+ */
+ public CombinerParameter(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ /**
+ * Creates a new <code>CombinerParameter</code> with a default <code>StatusCode</code>, null status message, and the given
+ * <code>String</code> name and <code>AttributeValue</code>>
+ *
+ * @param nameIn the <code>String</code> name of the <code>CombinerParameter</code>
+ * @param attributeValueIn the <code>AttributeValue</code> of the <code>CombinerParameter</code>
+ */
+ public CombinerParameter(String nameIn, AttributeValue<?> attributeValueIn) {
+ super();
+ this.name = nameIn;
+ this.attributeValue = attributeValueIn;
+ }
+
+ public CombinerParameter() {
+
+ }
+
+ /**
+ * Gets the <code>String</code> name of this <code>CombinerParameter</code>.
+ *
+ * @return the <code>String</code> name of this <code>CombinerParameter</code>
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Sets the name of this <code>CombinerParameter</code> to the given <code>String</code>.
+ *
+ * @param nameIn the <code>String</code> name for this <code>CombinerParameter</code>.
+ */
+ public void setName(String nameIn) {
+ this.name = nameIn;
+ }
+
+ /**
+ * Gets the <code>AttributeValue</code> of this <code>CombinerParameter</code>.
+ *
+ * @return the <code>AttributeValue</code> of this <code>CombinerParameter</code>
+ */
+ public AttributeValue<?> getAttributeValue() {
+ return this.attributeValue;
+ }
+
+ /**
+ * Sets the <code>AttributeValue</code> for this <code>CombinerParameter</code>>
+ *
+ * @param attributeValueIn the <code>AttributeValue</code> for this <code>CombinerParameter</code>>
+ */
+ public void setAttributeValue(AttributeValue<?> attributeValueIn) {
+ this.attributeValue = attributeValueIn;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ Object objectToDump;
+ if ((objectToDump = this.getName()) != null) {
+ stringBuilder.append(",name=");
+ stringBuilder.append((String)objectToDump);
+ }
+ if ((objectToDump = this.getAttributeValue()) != null) {
+ stringBuilder.append(",attributeValue=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.java
new file mode 100755
index 0000000..d161efa
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.java
@@ -0,0 +1,49 @@
+/*
+ * 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.policy;
+
+import java.util.List;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.Evaluatable;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+
+/**
+ * CombiningAlgorithm is the interface for objects that implement XACML combining algorithms for rules, policies, and policy sets.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ *
+ * @param <T> the type of object to be combined
+ * @param <U> the type of the identifier for <code>T</code>
+ */
+public interface CombiningAlgorithm<T extends Evaluatable> {
+ /**
+ * Gets the {@link com.att.research.xacml.api.Identifier} for this <code>CombiningAlgorithm</code>.
+ *
+ * @return the <code>Identifier</code> for this <code>CombiningAlgorithm</code>
+ */
+ public Identifier getId();
+
+ /**
+ * Evaluates as many of the <code>CombiningElement</code>s supplied with the given <code>CombinerParameter</code>s based on
+ * the particular combining algorithm and combines their <code>EvaluationResult</code>s into a single <code>EvaluationResult</code>.
+ *
+ * @param evaluationContext the <code>EvaluationContext</code> in which to evaluate each of the <code>CombiningElement</code>s
+ * @param elements the <code>List</code> of <code>CombiningElement</code>s to evaluate
+ * @param combinerParameters the <code>List</code> of <code>CombinerParameter</code>s to apply to the combining algorithm
+ * @return the combined <code>EvaluationResult</code>
+ * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException if there is an error in the <code>evaluate</code> method of any of the <code>CombiningElement</code>s
+ */
+ public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<T>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException;
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.java
new file mode 100755
index 0000000..b6b278e
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.java
@@ -0,0 +1,91 @@
+/*
+ * 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.policy;
+
+import java.util.Properties;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.FactoryFinder;
+import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
+
+/**
+ * CombiningAlgorithmFactory is an abstract class for mapping function {@link com.att.research.xacml.api.Identifier} ids to
+ * {@link CombiningAlgorithm} objects.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public abstract class CombiningAlgorithmFactory {
+ private static final String FACTORYID = ATTPDPProperties.PROP_COMBININGALGORITHMFACTORY;
+ private static final String DEFAULT_FACTORY_CLASSNAME = "com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory";
+
+ protected CombiningAlgorithmFactory() {
+ }
+
+ protected CombiningAlgorithmFactory(Properties properties) {
+ }
+
+ /**
+ * Maps the given <code>Identifier</code> representing a XACML rule combining algorithm to a <code>CombiningAlgorithm</code> object.
+ *
+ * @param combiningAlgorithmId the <code>Identifier</code> of the <code>CombiningAlgorithm</code> to retrieve
+ * @return the <code>CombiningAlgorithm</code> for the given <code>Identifier</code> or null if not found
+ */
+ public abstract CombiningAlgorithm<Rule> getRuleCombiningAlgorithm(Identifier combiningAlgorithmId);
+
+ /**
+ * Maps the given <code>Identifier</code> representing a XACML policy combinign algorithm to a <code>CombiningAlgorithm</code> object.
+ *
+ * @param combiningAlgorithmId the <code.Identifier</code> of the <code>CombiningAlgorithm</code> to retrieve
+ * @return the <code>CombiningAlgorithm</code> for the given <code>Identifier</code> or null if not found
+ */
+ public abstract CombiningAlgorithm<PolicySetChild> getPolicyCombiningAlgorithm(Identifier combiningAlgorithmId);
+
+ /**
+ * Creates an instance of the <code>CombiningAlgorithmFactory</code> using default configuration information.
+ *
+ * @return the default <code>CombiningAlgorithmFactory</code>
+ */
+ public static CombiningAlgorithmFactory newInstance() throws FactoryException {
+ return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, CombiningAlgorithmFactory.class);
+ }
+
+ /**
+ * Creates an instance of the <code>CombiningAlgorithmFactory</code> using default configuration information.
+ *
+ * @return the default <code>CombiningAlgorithmFactory</code>
+ */
+ public static CombiningAlgorithmFactory newInstance(Properties properties) throws FactoryException {
+ return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, CombiningAlgorithmFactory.class, properties);
+ }
+
+ /**
+ * Creates an instance of the <code>CombiningAlgorithmFactory</code> using the given class name.
+ *
+ * @param className the <code>String</code> class name of the <code>CombiningAlgorithmFactory</code> to create
+ * @return the <code>CombiningAlgorithmFactory</code> for the given class name.
+ */
+ public static CombiningAlgorithmFactory newInstance(String className) throws FactoryException {
+ return FactoryFinder.newInstance(className, CombiningAlgorithmFactory.class, null, true);
+ }
+
+ /**
+ * Creates an instance of the <code>CombiningAlgorithmFactory</code> using the given class name using the given <code>ClassLoader</code>.
+ *
+ * @param className the <code>String</code> class name of the <code>CombiningAlgorithmFactory</code> to create
+ * @param classLoader the <code>ClassLoader</code> to use to load the class with the given class name
+ * @return the <code>CombiningAlgorithmFactory</code> for the given class name
+ */
+ public static CombiningAlgorithmFactory newInstance(String className, ClassLoader classLoader) throws FactoryException {
+ return FactoryFinder.newInstance(className, CombiningAlgorithmFactory.class, classLoader, false);
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningElement.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningElement.java
new file mode 100755
index 0000000..8890b1a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningElement.java
@@ -0,0 +1,82 @@
+/*
+ * 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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacmlatt.pdp.eval.Evaluatable;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+
+/**
+ * CombiningElement wraps an {@link com.att.research.xacmlatt.pdp.evl.Evaluatable} with a set of
+ * {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter}s for use with a
+ * {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm} to get a combined {@link com.att.research.xacmlatt.pdp.eval.EvaluationResult}
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ *
+ * @param <T> the java class extending <code>Evaluatable</code> of the objects to be combined
+ */
+public class CombiningElement<T extends Evaluatable> {
+ private T evaluatable;
+ private List<CombinerParameter> targetedCombinerParameters;
+
+ /**
+ * Creates a new <code>CombiningElement</code> with the given <code>Evaluatable</code> and <code>List</code> of
+ * <code>TargetedCombinerParameter</code>.
+ *
+ * @param evaluatableIn the <code>Evaluatable</code>
+ * @param targetedCombinerParametersIn the <code>List</code> of <code>TargetedCombinerParameter</code>s.
+ */
+ public CombiningElement(T evaluatableIn, Collection<CombinerParameter> targetedCombinerParametersIn) {
+ this.evaluatable = evaluatableIn;
+ if (targetedCombinerParametersIn != null) {
+ this.targetedCombinerParameters = new ArrayList<CombinerParameter>();
+ this.targetedCombinerParameters.addAll(targetedCombinerParametersIn);
+ }
+ }
+
+ /**
+ * Gets the <code>Evaluatable</code> for this <code>CombiningElement</code>.
+ *
+ * @return the <code>Evaluatable</code> for this <code>CombiningElement</code>
+ */
+ public T getEvaluatable() {
+ return this.evaluatable;
+ }
+
+ /**
+ * Gets an <code>Iterator</code> over the <code>TargetedCombinerParameters</code> for this
+ * <code>CombiningElement</code>.
+ *
+ * @return an <code>Iterator</code> over the <code>TargetedCombinerParameters</code> for this <code>CombiningElement</code>
+ */
+ public Iterator<CombinerParameter> getTargetedCombinerParameters() {
+ return (this.targetedCombinerParameters == null ? null : this.targetedCombinerParameters.iterator());
+ }
+
+ /**
+ * Evaluates this <code>CombiningElement</code> in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}.
+ *
+ * @param evaluationContext the <code>EvaluationContext</code>
+ * @return the {@link com.att.research.xacmlatt.pdp.eval.EvaluationResult} from the <code>Evaluatable</code>
+ * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException if there is an error in the <code>evaluate</code> method of the <code>Evaluatable</code>
+ */
+ public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException {
+ return this.getEvaluatable().evaluate(evaluationContext);
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Condition.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Condition.java
new file mode 100755
index 0000000..0f02f78
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Condition.java
@@ -0,0 +1,149 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.api.StatusCode;
+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.eval.EvaluationException;
+
+/**
+ * Condition extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} to represent the XACML Condition element
+ * in a XACML Rule.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class Condition extends PolicyComponent {
+ private static final Status STATUS_PE_RETURNED_BAG = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Condition Expression returned a bag");
+ private static final ExpressionResultBoolean ERB_RETURNED_BAG = new ExpressionResultBoolean(STATUS_PE_RETURNED_BAG);
+ private static final Status STATUS_PE_RETURNED_NULL = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Null value from Condition Expression");
+ private static final ExpressionResultBoolean ERB_RETURNED_NULL = new ExpressionResultBoolean(STATUS_PE_RETURNED_NULL);
+ private static final Status STATUS_PE_RETURNED_NON_BOOLEAN = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Non-boolean value from Condition Expression");
+ private static final ExpressionResultBoolean ERB_RETURNED_NON_BOOLEAN = new ExpressionResultBoolean(STATUS_PE_RETURNED_NON_BOOLEAN);
+ private static final Status STATUS_PE_INVALID_BOOLEAN = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Invalid Boolean value");
+ private static final ExpressionResultBoolean ERB_INVALID_BOOLEAN = new ExpressionResultBoolean(STATUS_PE_INVALID_BOOLEAN);
+
+ private Expression expression;
+
+ /**
+ * Creates a <code>Condition</code> with the given {@link com.att.research.xacml.api.StatusCode} and <code>String</code>
+ * status message.
+ *
+ * @param statusCodeIn the <code>StatusCode</code> for the <code>Condition</code>
+ * @param statusMessageIn the <code>String</code> status message for the <code>Condition</code>
+ */
+ public Condition(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ /**
+ * Creates a <code>Condition</code> with the given <code>StatusCode</code. and a null status message.
+ *
+ * @param statusCodeIn the <code>StatusCode</code> for the <code>Condition</code>
+ */
+ public Condition(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ /**
+ * Creates an empty <code>Condition</code>
+ */
+ public Condition() {
+ }
+
+ /**
+ * Creates a new <code>Condition</code> with the given {@link com.att.research.xacmlatt.pdp.policy.Expression} and a default
+ * OK <code>StatusCode</code>.
+ *
+ * @param expressionIn the <code>Expression</code> for the <code>Condition</code>
+ */
+ public Condition(Expression expressionIn) {
+ this.expression = expressionIn;
+ }
+
+ public Expression getExpression() {
+ return this.expression;
+ }
+
+ public void setExpression(Expression expressionIn) {
+ this.expression = expressionIn;
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (this.getExpression() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Expression");
+ return false;
+ } else {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+ }
+
+ /**
+ * Evaluates the <code>Expression</code> in this <code>Condition</code> in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}.
+ * and validates that the result is a boolean.
+ *
+ * @param evaluationContext the <code>EvaluationContext</code> in which to evaluate this <code>Expression</code>
+ * @param policyDefaults the {@link com.att.research.xacml.pdp.policy.PolicyDefaults} to use in evaluating this <code>Expression</code>
+ * @return a {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult}
+ */
+ public ExpressionResultBoolean evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+ if (!this.validate()) {
+ return new ExpressionResultBoolean(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+
+ /*
+ * Evaluate the expression
+ */
+ ExpressionResult expressionResult = this.getExpression().evaluate(evaluationContext, policyDefaults);
+ assert(expressionResult != null);
+
+ if (!expressionResult.isOk()) {
+ return new ExpressionResultBoolean(expressionResult.getStatus());
+ }
+
+ /*
+ * Ensure the result is a single element of type boolean
+ */
+ if (expressionResult.isBag()) {
+ return ERB_RETURNED_BAG;
+ }
+ AttributeValue<?> attributeValueResult = expressionResult.getValue();
+ if (attributeValueResult == null) {
+ return ERB_RETURNED_NULL;
+ } else if (!DataTypes.DT_BOOLEAN.getId().equals(attributeValueResult.getDataTypeId())) {
+ return ERB_RETURNED_NON_BOOLEAN;
+ }
+
+ /*
+ * Otherwise it is a valid condition evaluation
+ */
+ Boolean booleanValue = null;
+ try {
+ booleanValue = DataTypes.DT_BOOLEAN.convert(attributeValueResult.getValue());
+ } catch (DataTypeException ex) {
+ return new ExpressionResultBoolean(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage()));
+ }
+ if (booleanValue == null) {
+ return ERB_INVALID_BOOLEAN;
+ } else {
+ return (booleanValue.booleanValue() ? ExpressionResultBoolean.ERB_TRUE : ExpressionResultBoolean.ERB_FALSE);
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Expression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Expression.java
new file mode 100755
index 0000000..c40c41a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Expression.java
@@ -0,0 +1,44 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+
+/**
+ * Expression extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} to represent a XACML ExpressionType element.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public abstract class Expression extends PolicyComponent {
+
+ public Expression(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public Expression(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public Expression() {
+ }
+
+ /**
+ * Evaluates this <code>Expression</code> in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}.
+ *
+ * @param evaluationContext the <code>EvaluationContext</code> in which to evaluate this <code>Expression</code>
+ * @param policyDefaults the {@link com.att.research.xacml.pdp.policy.PolicyDefaults} to use in evaluating this <code>Expression</code>
+ * @return a {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult}
+ */
+ public abstract ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException;
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResult.java
new file mode 100755
index 0000000..778861f
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResult.java
@@ -0,0 +1,254 @@
+/*
+ * 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.policy;
+
+import java.util.Iterator;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+
+/**
+ * ExpressionResult is the object returned by the <code>evaluate</code> method of {@link Expression}
+ * objects.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public abstract class ExpressionResult implements FunctionArgument {
+ private Status status;
+
+ /**
+ * ExpressionResultError extends <code>ExpressionResult</code> to represent error results.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+ private static class ExpressionResultError extends ExpressionResult {
+ public ExpressionResultError(Status statusIn) {
+ super(statusIn);
+ }
+
+ @Override
+ public AttributeValue<?> getValue() {
+ return null;
+ }
+
+ @Override
+ public boolean isBag() {
+ return false;
+ }
+
+ @Override
+ public Bag getBag() {
+ return null;
+ }
+ }
+
+ /**
+ * ExpressionResultSingle extends <code>ExpressionResult</code> to represent results with a single value.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+ private static class ExpressionResultSingle extends ExpressionResult {
+ AttributeValue<?> attributeValue;
+
+ public ExpressionResultSingle(AttributeValue<?> attributeValueIn) {
+ super(StdStatus.STATUS_OK);
+ this.attributeValue = attributeValueIn;
+ }
+
+ @Override
+ public AttributeValue<?> getValue() {
+ return this.attributeValue;
+ }
+
+ @Override
+ public boolean isBag() {
+ return false;
+ }
+
+ @Override
+ public Bag getBag() {
+ return null;
+ }
+ }
+
+ private static class ExpressionResultBag extends ExpressionResult {
+ private Bag bag;
+
+ public ExpressionResultBag(Bag bagIn) {
+ super(StdStatus.STATUS_OK);
+ this.bag = bagIn;
+ }
+
+ @Override
+ public AttributeValue<?> getValue() {
+ Iterator<AttributeValue<?>> iter = this.bag.getAttributeValues();
+ if (iter != null && iter.hasNext()) {
+ return iter.next();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public boolean isBag() {
+ return true;
+ }
+
+ @Override
+ public Bag getBag() {
+ return this.bag;
+ }
+ }
+
+ private static class ExpressionResultEmptyBag extends ExpressionResult {
+ public ExpressionResultEmptyBag() {
+ super(StdStatus.STATUS_OK);
+ }
+
+ @Override
+ public AttributeValue<?> getValue() {
+ return null;
+ }
+
+ @Override
+ public boolean isBag() {
+ return true;
+ }
+
+ @Override
+ public Bag getBag() {
+ return Bag.EMPTY;
+ }
+ }
+
+ /**
+ * Creates a new <code>ExpressionResult</code> with the given {@link com.att.research.xacml.api.Status}.
+ *
+ * @param statusIn the <code>Status</code> of this <code>ExpressionResult</code>
+ */
+ protected ExpressionResult(Status statusIn) {
+ this.status = statusIn;
+ }
+
+ /**
+ * Gets the <code>Status</code> for this <code>ExpressionResult</code>.
+ *
+ * @return the <code>Status</code> for this <code>ExpressionResult</code>
+ */
+ public Status getStatus() {
+ return this.status;
+ }
+
+ /**
+ * Shortcut procedure for determining if the <code>Status</code> of this <code>ExpressionResult</code> is OK.
+ *
+ * @return true if the <code>Status</code> is null or has a <code>StatusCode</code> value of <code>STATUS_CODE_OK</code>.
+ */
+ public boolean isOk() {
+ return (this.getStatus() == null || this.getStatus().isOk());
+ }
+
+ /**
+ * Gets the single {@link com.att.research.xacml.api.AttributeValue} from this <code>ExpressionResult</code>. If this
+ * <code>ExpressionResult</code> represents a bag, the first element in the bag is returned.
+ *
+ * @return a single <code>AttributeValue</code> from this <code>ExpressionResult</code>
+ */
+ public abstract AttributeValue<?> getValue();
+
+ /**
+ * Determines if this <code>ExpressionResult</code> represents a bag of <code>AttributeValue</code>s or not.
+ *
+ * @return true if this <code>ExpressionResult</code> represents a bag of <code>AttributeValue</code>s, else false
+ */
+ public abstract boolean isBag();
+
+ /**
+ * Gets the {@link Bag} of values for this <code>ExpressionResult</code> if
+ * there is one.
+ *
+ * @return the <code>Bag</code> of <code>AttributeValue</code>s for this <code>ExpressionResult</code>.
+ */
+ public abstract Bag getBag();
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+ stringBuilder.append("isOk=" + this.isOk());
+ stringBuilder.append(", isBag=" + this.isBag());
+ Status thisStatus = this.getStatus();
+ if (thisStatus != null) {
+ stringBuilder.append(", status=");
+ stringBuilder.append(thisStatus.toString());
+ }
+ AttributeValue<?> value = this.getValue();
+ if (value != null) {
+ stringBuilder.append(", value=");
+ stringBuilder.append(value);
+ }
+ /*
+ * Not sure if I want this dumped
+ if (this.isBag()) {
+ Bag bag = this.getBag();
+ if (bag != null) {
+ }
+ }
+ */
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+ /**
+ * Creates a new instance of the <code>ExpressionResult</code> class representing an error.
+ *
+ * @param statusIn the <code>Status</code> containing the error information
+ * @return a new <code>ExpressionResult</code> representing the error
+ */
+ public static ExpressionResult newError(Status statusIn) {
+ return new ExpressionResultError(statusIn);
+ }
+
+ public static ExpressionResult newSingle(AttributeValue<?> attributeValue) {
+ return new ExpressionResultSingle(attributeValue);
+ }
+
+ /**
+ * Creates a new instance of the <code>ExpressionResult</code> class representing a bag of values
+ * from the given <code>Bag</code>.
+ *
+ * @param bag the <code>Bag</code> for the new <code>ExpressionResult</code>
+ * @return a new <code>ExpressionResult</code> representing the given <code>Bag</code>.
+ */
+ public static ExpressionResult newBag(Bag bag) {
+ return new ExpressionResultBag(bag);
+ }
+
+ /**
+ * Creates a new instance of the <code>ExpressionResult</code> class representing an empty bag of values.
+ *
+ * @return the <code>ExpressionResult</code> representing the empty bag of values of the expression
+ */
+ public static ExpressionResult newEmpty() {
+ return new ExpressionResultEmptyBag();
+ }
+
+ public static ExpressionResult newInstance(Status statusIn) {
+ if (statusIn.getStatusCode().equals(StdStatus.STATUS_OK.getStatusCode())) {
+ return newEmpty();
+ } else {
+ return newError(statusIn);
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.java
new file mode 100755
index 0000000..3554dfa
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.java
@@ -0,0 +1,65 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.datatypes.DataTypeBoolean;
+
+/**
+ * ExpressionResultBoolean extends {@link ExpressionResult} to represent predicates.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class ExpressionResultBoolean extends ExpressionResult {
+ private AttributeValue<Boolean> value;
+ public static final ExpressionResultBoolean ERB_FALSE = new ExpressionResultBoolean(false);
+ public static final ExpressionResultBoolean ERB_TRUE = new ExpressionResultBoolean(true);
+
+ public ExpressionResultBoolean(Status statusIn) {
+ super(statusIn);
+ }
+
+ public ExpressionResultBoolean(boolean bvalue) {
+ super(StdStatus.STATUS_OK);
+ this.value = (bvalue ? DataTypeBoolean.AV_TRUE : DataTypeBoolean.AV_FALSE);
+ }
+
+ /**
+ * Gets the <code>boolean</code> value of this <code>ExpressionResultBoolean</code>
+ *
+ * @return the <code>boolean</code> value of this <code>ExpressionResultBoolean</code>
+ */
+ public boolean isTrue() {
+ if (this.value == null) {
+ return false;
+ } else {
+ return this.value.getValue().booleanValue();
+ }
+ }
+
+ @Override
+ public AttributeValue<?> getValue() {
+ return this.value;
+ }
+
+ @Override
+ public boolean isBag() {
+ return false;
+ }
+
+ @Override
+ public Bag getBag() {
+ return null;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgument.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgument.java
new file mode 100755
index 0000000..207da3d
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgument.java
@@ -0,0 +1,62 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Status;
+
+/**
+ * FunctionArgument is the interface implemented by objects that can serve as arguments to a {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition}
+ * <code>evaluate</code> call.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public interface FunctionArgument {
+ /**
+ * Gets the {@link com.att.research.xacml.api.Status} from the evaluation of this <code>FunctionArgument</code>.
+ *
+ * @return the <code>Status</code> from the evaluation of this <code>FunctionArgument</code>>
+ */
+ public Status getStatus();
+
+ /**
+ * Determines if this <code>FunctionArgument</code> is OK and can have its <code>AttributeValue</code> or
+ * <code>Bag</code> retrieved.
+ *
+ * @return true if this <code>FunctionArgument</code> is OK, otherwise false.
+ */
+ public boolean isOk();
+
+ /**
+ * Determines if this <code>FunctionArgument</code> represents a bag of values.
+ *
+ * @return true if this <code>FunctionArgument</code> represents a bag of values, else false.
+ */
+ public boolean isBag();
+
+ /**
+ * Gets the single <code>AttributeValue</code> representing the value of this <code>FunctionArgument</code>. If
+ * this <code>FunctionArgument</code> represents a bag, the value returned is up to the implementation.
+ *
+ * @return the single <code>AttributeValue</code> representing the value of this <code>FunctionArgument</code>.
+ */
+ public AttributeValue<?> getValue();
+
+ /**
+ * Gets the {@link Bag} value for this <code>FunctionArgument</code> if the
+ * argument represents a <code>Bag</code>, (i.e. <code>isBag</code> returns true).
+ *
+ * @return the <code>Bag</code> value for this <code>FunctionArgument</code>.
+ */
+ public Bag getBag();
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.java
new file mode 100755
index 0000000..d81c14b
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.java
@@ -0,0 +1,59 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+
+/**
+ * FunctionArgumentAttributeValue implements {@link FunctionArgument} for a single
+ * {@link com.att.research.xacml.api.AttributeValue}
+ * @author car
+ *
+ */
+public class FunctionArgumentAttributeValue implements FunctionArgument {
+ private AttributeValue<?> attributeValue;
+
+ /**
+ * Creates a new <code>FunctionArgumentAttributeValue</code> from the given <code>AttributeValue</code>.
+ *
+ * @param attributeValueIn the <code>AttributeValue</code> for the new <code>FunctionArgumentAttributeValue</code>.
+ */
+ public FunctionArgumentAttributeValue(AttributeValue<?> attributeValueIn) {
+ this.attributeValue = attributeValueIn;
+ }
+
+ @Override
+ public Status getStatus() {
+ return StdStatus.STATUS_OK;
+ }
+
+ @Override
+ public boolean isOk() {
+ return true;
+ }
+
+ @Override
+ public boolean isBag() {
+ return false;
+ }
+
+ @Override
+ public AttributeValue<?> getValue() {
+ return this.attributeValue;
+ }
+
+ @Override
+ public Bag getBag() {
+ return null;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.java
new file mode 100755
index 0000000..9fc66cd
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.java
@@ -0,0 +1,67 @@
+/*
+ * 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.policy;
+
+import java.util.Iterator;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+
+/**
+ * FunctionArgumentBag implements the {@link FunctionArgument} interface for
+ * a {@link Bag} objects.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class FunctionArgumentBag implements FunctionArgument {
+ private Bag bag;
+
+ /**
+ * Creates a new <code>FunctionArgumentBag</code> from the given <code>Bag</code>.
+ *
+ * @param bagIn the <code>Bag</code> for the new <code>FunctionArgumentBag</code>.
+ */
+ public FunctionArgumentBag(Bag bagIn) {
+ this.bag = bagIn;
+ }
+
+ @Override
+ public Status getStatus() {
+ return StdStatus.STATUS_OK;
+ }
+
+ @Override
+ public boolean isOk() {
+ return true;
+ }
+
+ @Override
+ public boolean isBag() {
+ return true;
+ }
+
+ @Override
+ public AttributeValue<?> getValue() {
+ Iterator<AttributeValue<?>> iterAttributeValues = this.bag.getAttributeValues();
+ if (iterAttributeValues == null || !iterAttributeValues.hasNext()) {
+ return null;
+ } else {
+ return iterAttributeValues.next();
+ }
+ }
+
+ @Override
+ public Bag getBag() {
+ return this.bag;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.java
new file mode 100755
index 0000000..5845280
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.java
@@ -0,0 +1,113 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.AttributeValue;
+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.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+
+/**
+ * FunctionArgumentExpression implements the {@link FunctionArgument} interface for
+ * unevaluated {@link Expression}s.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class FunctionArgumentExpression implements FunctionArgument {
+ private static final Status STATUS_NULL_EXPRESSION_RESULT = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Null expression result");
+
+ private Expression expression;
+ private EvaluationContext evaluationContext;
+ private ExpressionResult expressionResult;
+ private PolicyDefaults policyDefaults;
+
+ protected ExpressionResult evaluateExpression() {
+ if (this.getExpression() != null && this.getEvaluationContext() != null) {
+ try {
+ this.expressionResult = this.getExpression().evaluate(this.getEvaluationContext(), this.getPolicyDefaults());
+ } catch (EvaluationException ex) {
+ this.expressionResult = ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage()));
+ }
+ }
+ return this.expressionResult;
+ }
+
+ public FunctionArgumentExpression() {
+ }
+
+ public FunctionArgumentExpression(Expression expressionIn, EvaluationContext evaluationContextIn, PolicyDefaults policyDefaultsIn) {
+ this.expression = expressionIn;
+ this.evaluationContext = evaluationContextIn;
+ this.policyDefaults = policyDefaultsIn;
+ }
+
+ protected ExpressionResult getExpressionResult() {
+ return this.expressionResult;
+ }
+
+ protected Expression getExpression() {
+ return this.expression;
+ }
+
+ protected EvaluationContext getEvaluationContext() {
+ return this.evaluationContext;
+ }
+
+ protected PolicyDefaults getPolicyDefaults() {
+
+ return this.policyDefaults;
+ }
+
+ @Override
+ public Status getStatus() {
+ ExpressionResult thisExpressionResult = this.getExpressionResult();
+ if (thisExpressionResult == null) {
+ thisExpressionResult = this.evaluateExpression();
+ }
+ return (thisExpressionResult == null ? STATUS_NULL_EXPRESSION_RESULT : thisExpressionResult.getStatus());
+ }
+
+ @Override
+ public boolean isOk() {
+ Status thisStatus = this.getStatus();
+ return (thisStatus == null ? true : thisStatus.isOk());
+ }
+
+ @Override
+ public boolean isBag() {
+ ExpressionResult thisExpressionResult = this.getExpressionResult();
+ if (thisExpressionResult == null) {
+ thisExpressionResult = this.evaluateExpression();
+ }
+ return (thisExpressionResult == null ? false : thisExpressionResult.isBag());
+ }
+
+ @Override
+ public AttributeValue<?> getValue() {
+ ExpressionResult thisExpressionResult = this.getExpressionResult();
+ if (thisExpressionResult == null) {
+ thisExpressionResult = this.evaluateExpression();
+ }
+ return (thisExpressionResult == null ? null : thisExpressionResult.getValue());
+ }
+
+ @Override
+ public Bag getBag() {
+ ExpressionResult thisExpressionResult = this.getExpressionResult();
+ if (thisExpressionResult == null) {
+ thisExpressionResult = this.evaluateExpression();
+ }
+ return (thisExpressionResult == null ? null : thisExpressionResult.getBag());
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.java
new file mode 100755
index 0000000..d112318
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.java
@@ -0,0 +1,56 @@
+/*
+ * 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.policy;
+
+import java.util.List;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+
+/**
+ * FunctionDefinition is the interface that objects representing XACML functions found in Match and Apply elements in Policies, PolicySets
+ * and Rules.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public interface FunctionDefinition {
+ /**
+ * Gets the {@link com.att.research.xacml.api.Identifier} for this <code>FunctionDefinition</code>.
+ *
+ * @return the <code>Identifier</code> for this <code>FunctionDefinition</code>.
+ */
+ public Identifier getId();
+
+ /**
+ * Returns the <code>Identifier</code> for the data type returned by this function if <code>returnsBag()</code> is false or
+ * if this <code>FunctionDefinition</code> returns a bag containing a single data type. Otherwise it returns null.
+ *
+ * @return the <code>Identifier</code> for the XACML data type this <code>FunctionDefinition</code> returns
+ */
+ public Identifier getDataTypeId();
+
+ /**
+ * Determines if this <code>FunctionDefinition</code> returns a bag of values or a single value.
+ *
+ * @return true if this <code>FunctionDefinition</code> returns a bag, else false
+ */
+ public boolean returnsBag();
+
+ /**
+ * Evaluates this <code>FunctionDefinition</code> on the given <code>List</code> of{@link 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 ExpressionResult} with the results of the call
+ */
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments);
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.java
new file mode 100755
index 0000000..f204729
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.java
@@ -0,0 +1,83 @@
+/*
+ * 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.policy;
+
+import java.util.Properties;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.FactoryFinder;
+import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
+
+/**
+ * FunctionDefinitionFactory is an abstract class for mapping function {@link com.att.research.xacml.api.Identifier} ids to
+ * {@link FunctionDefinition} objects.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public abstract class FunctionDefinitionFactory {
+ private static final String FACTORYID = ATTPDPProperties.PROP_FUNCTIONDEFINITIONFACTORY;
+ private static final String DEFAULT_FACTORY_CLASSNAME = "com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory";
+
+ protected FunctionDefinitionFactory() {
+ }
+
+ protected FunctionDefinitionFactory(Properties properties) {
+ }
+
+ /**
+ * Maps the given <code>Identifier</code> representing a XACML function to a <code>FunctionDefinition</code> object.
+ *
+ * @param functionId the <code>Identifier</code> of the <code>FunctionDefinition</code> to retrieve
+ * @return the <code>FunctionDefinition</code> for the given <code>Identifier</code> or null if not found
+ */
+ public abstract FunctionDefinition getFunctionDefinition(Identifier functionId);
+
+ /**
+ * Creates an instance of the <code>FunctionDefinitionFactory</code> using default configuration information.
+ *
+ * @return the default <code>FunctionDefinitionFactory</code>
+ */
+ public static FunctionDefinitionFactory newInstance() throws FactoryException {
+ return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, FunctionDefinitionFactory.class);
+ }
+
+ /**
+ * Creates an instance of the <code>FunctionDefinitionFactory</code> using default configuration information.
+ *
+ * @return the default <code>FunctionDefinitionFactory</code>
+ */
+ public static FunctionDefinitionFactory newInstance(Properties properties) throws FactoryException {
+ return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, FunctionDefinitionFactory.class, properties);
+ }
+
+ /**
+ * Creates an instance of the <code>FunctionDefinitionFactory</code> using the given class name.
+ *
+ * @param className the <code>String</code> class name of the <code>FunctionDefinitionFactory</code> to create
+ * @return the <code>FunctionDefinitionFactory</code> for the given class name.
+ */
+ public static FunctionDefinitionFactory newInstance(String className) throws FactoryException {
+ return FactoryFinder.newInstance(className, FunctionDefinitionFactory.class, null, true);
+ }
+
+ /**
+ * Creates an instance of the <code>FunctionDefinitionFactory</code> using the given class name using the given <code>ClassLoader</code>.
+ *
+ * @param className the <code>String</code> class name of the <code>FunctionDefinitionFactory</code> to create
+ * @param classLoader the <code>ClassLoader</code> to use to load the class with the given class name
+ * @return the <code>FunctionDefinitionFactory</code> for the given class name
+ */
+ public static FunctionDefinitionFactory newInstance(String className, ClassLoader classLoader) throws FactoryException {
+ return FactoryFinder.newInstance(className, FunctionDefinitionFactory.class, classLoader, false);
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Match.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Match.java
new file mode 100755
index 0000000..d32b8cc
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Match.java
@@ -0,0 +1,243 @@
+/*
+ * 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.policy;
+
+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.DataTypeException;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.XACML;
+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.util.FactoryException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+import com.att.research.xacmlatt.pdp.eval.Matchable;
+import com.att.research.xacmlatt.pdp.policy.expressions.AttributeRetrievalBase;
+
+/**
+ * Match extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} and implements the
+ * {@link com.att.research.xacmlatt.pdp.eval.Matchable} interface to represent a XACML Match element.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class Match extends PolicyComponent implements Matchable {
+ private Identifier matchId;
+ private AttributeValue<?> attributeValue;
+ private AttributeRetrievalBase attributeRetrievalBase;
+ private PolicyDefaults policyDefaults;
+ private FunctionDefinition functionDefinition;
+
+ protected FunctionDefinition getFunctionDefinition() {
+ Identifier functionDefinitionId = this.getMatchId();
+ if (this.functionDefinition == null && functionDefinitionId != null) {
+ try {
+ this.functionDefinition = FunctionDefinitionFactory.newInstance().getFunctionDefinition(functionDefinitionId);
+ } catch (FactoryException ex) {
+ this.setStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "FactoryException getting FunctionDefinition");
+ }
+ }
+ return this.functionDefinition;
+ }
+
+ public Match(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public Match(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public Match() {
+ }
+
+ public Match(Identifier matchIdIn, AttributeValue<?> attributeValueIn, AttributeRetrievalBase attributeRetrievalBaseIn, PolicyDefaults policyDefaultsIn) {
+ this(StdStatusCode.STATUS_CODE_OK);
+ this.matchId = matchIdIn;
+ this.attributeValue = attributeValueIn;
+ this.attributeRetrievalBase = attributeRetrievalBaseIn;
+ this.policyDefaults = policyDefaultsIn;
+ }
+
+ public Identifier getMatchId() {
+ return this.matchId;
+ }
+
+ public void setMatchId(Identifier matchIdIn) {
+ this.matchId = matchIdIn;
+ }
+
+ public AttributeValue<?> getAttributeValue() {
+ return this.attributeValue;
+ }
+
+ public void setAttributeValue(AttributeValue<?> attributeValueIn) {
+ this.attributeValue = attributeValueIn;
+ }
+
+ public AttributeRetrievalBase getAttributeRetrievalBase() {
+ return this.attributeRetrievalBase;
+ }
+
+ public void setAttributeRetrievalBase(AttributeRetrievalBase attributeRetrievalBaseIn) {
+ this.attributeRetrievalBase = attributeRetrievalBaseIn;
+ }
+
+ public PolicyDefaults getPolicyDefaults() {
+ return this.policyDefaults;
+ }
+
+ public void setPolicyDefaults(PolicyDefaults policyDefaultsIn) {
+ this.policyDefaults = policyDefaultsIn;
+ }
+
+ private static MatchResult match(EvaluationContext evaluationContext, FunctionDefinition functionDefinition, FunctionArgument arg1, FunctionArgument arg2) throws EvaluationException {
+ List<FunctionArgument> listArguments = new ArrayList<FunctionArgument>(2);
+ listArguments.add(arg1);
+ listArguments.add(arg2);
+
+ ExpressionResult expressionResult = functionDefinition.evaluate(evaluationContext, listArguments);
+ assert(expressionResult != null);
+ if (!expressionResult.isOk()) {
+ return new MatchResult(expressionResult.getStatus());
+ }
+
+ AttributeValue<Boolean> attributeValueResult = null;
+ try {
+ attributeValueResult = DataTypes.DT_BOOLEAN.convertAttributeValue(expressionResult.getValue());
+ } catch (DataTypeException ex) {
+ return new MatchResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage()));
+ }
+ if (attributeValueResult == null) {
+ return new MatchResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Non-boolean result from Match Function " + functionDefinition.getId() + " on " + expressionResult.getValue().toString()));
+ } else if (attributeValueResult.getValue().booleanValue()) {
+ return MatchResult.MM_MATCH;
+ } else {
+ return MatchResult.MM_NOMATCH;
+ }
+
+ }
+
+ @Override
+ public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException {
+ if (!this.validate()) {
+ return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+
+ FunctionDefinition functionDefinitionMatch = this.getFunctionDefinition();
+ assert(functionDefinitionMatch != null);
+
+ AttributeValue<?> attributeValue = this.getAttributeValue();
+ assert(attributeValue != null);
+ FunctionArgument functionArgument1 = new FunctionArgumentAttributeValue(attributeValue);
+
+ AttributeRetrievalBase attributeRetrievalBase = this.getAttributeRetrievalBase();
+ assert(attributeRetrievalBase != null);
+
+ ExpressionResult expressionResult = attributeRetrievalBase.evaluate(evaluationContext, this.getPolicyDefaults());
+ assert(expressionResult != null);
+ if (!expressionResult.isOk()) {
+ return new MatchResult(expressionResult.getStatus());
+ }
+
+ if (expressionResult.isBag()) {
+ MatchResult matchResult = MatchResult.MM_NOMATCH;
+ Bag bagAttributeValues = expressionResult.getBag();
+ if (bagAttributeValues != null) {
+ Iterator<AttributeValue<?>> iterAttributeValues = bagAttributeValues.getAttributeValues();
+ while (matchResult.getMatchCode() != MatchResult.MatchCode.MATCH && iterAttributeValues.hasNext()) {
+ MatchResult matchResultValue = match(evaluationContext, functionDefinitionMatch, functionArgument1, new FunctionArgumentAttributeValue(iterAttributeValues.next()));
+ switch(matchResultValue.getMatchCode()) {
+ case INDETERMINATE:
+ if (matchResult.getMatchCode() != MatchResult.MatchCode.INDETERMINATE) {
+ matchResult = matchResultValue;
+ }
+ break;
+ case MATCH:
+ matchResult = matchResultValue;
+ break;
+ case NOMATCH:
+ break;
+ }
+ }
+ }
+ return matchResult;
+ } else {
+ /*
+ * There is a single value, so add it as the second argument and do the one function evaluation
+ */
+ AttributeValue<?> attributeValueExpressionResult = expressionResult.getValue();
+ if (attributeValueExpressionResult == null) {
+ return new MatchResult(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Null AttributeValue"));
+ }
+
+ return match(evaluationContext, functionDefinitionMatch, functionArgument1, new FunctionArgumentAttributeValue(attributeValueExpressionResult));
+ }
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ FunctionDefinition functionDefinitionHere;
+ if (this.getAttributeValue() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AttributeValue");
+ return false;
+ } else if (this.getMatchId() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing MatchId");
+ return false;
+ } else if ((functionDefinitionHere = this.getFunctionDefinition()) == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Unknown MatchId \"" + this.getMatchId().toString() + "\"");
+ return false;
+ } else if (functionDefinitionHere.returnsBag()) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "FunctionDefinition returns a bag");
+ return false;
+ } else if (functionDefinitionHere.getDataTypeId() == null || !functionDefinitionHere.getDataTypeId().equals(XACML.ID_DATATYPE_BOOLEAN)) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Non-Boolean return type for FunctionDefinition");
+ return false;
+ } else if (this.getAttributeRetrievalBase() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AttributeSelector or AttributeDesignator");
+ return false;
+ } else {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ Object objectToDump;
+ if ((objectToDump = this.getMatchId()) != null) {
+ stringBuilder.append(",matchId=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ if ((objectToDump = this.getAttributeValue()) != null) {
+ stringBuilder.append(",attributeValue=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ if ((objectToDump = this.getAttributeRetrievalBase()) != null) {
+ stringBuilder.append(",attributeRetrieval=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ObligationExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ObligationExpression.java
new file mode 100755
index 0000000..3ef01ef
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ObligationExpression.java
@@ -0,0 +1,174 @@
+/*
+ * 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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.AttributeAssignment;
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Obligation;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdMutableObligation;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+
+/**
+ * ObligationExpression extends {@link PolicyComponent} to implement the XACML
+ * ObligationExpression element.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class ObligationExpression extends PolicyComponent {
+ private Identifier obligationId;
+ private RuleEffect ruleEffect;
+ private List<AttributeAssignmentExpression> attributeAssignmentExpressions;
+
+ protected List<AttributeAssignmentExpression> getAttributeAssignmentExpressionList(boolean bNoNull) {
+ if (this.attributeAssignmentExpressions == null && bNoNull) {
+ this.attributeAssignmentExpressions = new ArrayList<AttributeAssignmentExpression>();
+ }
+ return this.attributeAssignmentExpressions;
+ }
+
+ protected void clearAttributeAssignmentExpressions() {
+ if (this.attributeAssignmentExpressions != null) {
+ this.attributeAssignmentExpressions.clear();
+ }
+ }
+
+ public ObligationExpression(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public ObligationExpression(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public ObligationExpression() {
+ }
+
+ public Identifier getObligationId() {
+ return this.obligationId;
+ }
+
+ public void setObligationId(Identifier identifier) {
+ this.obligationId = identifier;
+ }
+
+ public RuleEffect getRuleEffect() {
+ return this.ruleEffect;
+ }
+
+ public void setRuleEffect(RuleEffect ruleEffectIn) {
+ this.ruleEffect = ruleEffectIn;
+ }
+
+ public Iterator<AttributeAssignmentExpression> getAttributeAssignmentExpressions() {
+ List<AttributeAssignmentExpression> listAttributeAssignmentExpressions = this.getAttributeAssignmentExpressionList(false);
+ return (listAttributeAssignmentExpressions == null ? null : listAttributeAssignmentExpressions.iterator());
+ }
+
+ public void setAttributeAssignmentExpressions(Collection<AttributeAssignmentExpression> attributeAssignmentExpressionsIn) {
+ this.clearAttributeAssignmentExpressions();
+ if (attributeAssignmentExpressionsIn != null) {
+ this.addAttributeAssignmentExpressions(attributeAssignmentExpressionsIn);
+ }
+ }
+
+ public void addAttributeAssignmentExpression(AttributeAssignmentExpression attributeAssignmentExpression) {
+ List<AttributeAssignmentExpression> listAttributeAssignmentExpressions = this.getAttributeAssignmentExpressionList(true);
+ listAttributeAssignmentExpressions.add(attributeAssignmentExpression);
+ }
+
+ public void addAttributeAssignmentExpressions(Collection<AttributeAssignmentExpression> attributeAssignmentExpressionsIn) {
+ List<AttributeAssignmentExpression> listAttributeAssignmentExpressions = this.getAttributeAssignmentExpressionList(true);
+ listAttributeAssignmentExpressions.addAll(attributeAssignmentExpressionsIn);
+ }
+
+ /**
+ * Evaluates this <code>ObligationExpression</code> in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}
+ * to get an {@link com.att.research.xacml.api.Obligation} to include in a PDP result.
+ *
+ * @param evaluationContext the <code>EvaluationContext</code> in which to evaluate this <code>ObligationExpression</code>
+ * @param policyDefaults the <code>PolicyDefaults</code> to apply to the evaluation
+ * @return a new <code>Obliagion</code> from this <code>ObligationExpression</code>
+ * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException if there is an error evaluating any of the <code>AttributeAssignmentExpression</code>s
+ */
+ public Obligation evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+ if (!this.validate()) {
+ return null;
+ }
+ List<AttributeAssignment> listAttributeAssignments = new ArrayList<AttributeAssignment>();
+ Iterator<AttributeAssignmentExpression> iterAttributeAssignmentExpressions = this.getAttributeAssignmentExpressions();
+ if (iterAttributeAssignmentExpressions != null) {
+ while (iterAttributeAssignmentExpressions.hasNext()) {
+ AttributeAssignmentResult attributeAssignmentResult = iterAttributeAssignmentExpressions.next().evaluate(evaluationContext, policyDefaults);
+ if (attributeAssignmentResult.isOk() && attributeAssignmentResult.getNumAttributeAssignments() > 0) {
+ Iterator<AttributeAssignment> iterAttributeAssignments = attributeAssignmentResult.getAttributeAssignments();
+ while (iterAttributeAssignments.hasNext()) {
+ listAttributeAssignments.add(iterAttributeAssignments.next());
+ }
+ }
+ }
+ }
+ return new StdMutableObligation(this.getObligationId(), listAttributeAssignments);
+ }
+
+ /**
+ * Evaluates a <code>Collection</code> of <code>ObligationExpression</code>s in the given <code>EvaluationContext</code> and returns
+ * a <code>List</code> of <code>Obligation</code>s.
+ *
+ * @param evaluationContext
+ * @param policyDefaults
+ * @param listObligationExpressions
+ * @return
+ * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException
+ */
+ public static List<Obligation> evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults, Decision decision, Collection<ObligationExpression> listObligationExpressions) throws EvaluationException {
+ List<Obligation> listObligations = new ArrayList<Obligation>();
+ Iterator<ObligationExpression> iterObligationExpressions = listObligationExpressions.iterator();
+ while (iterObligationExpressions.hasNext()) {
+ ObligationExpression obligationExpression = iterObligationExpressions.next();
+ obligationExpression.validateComponent();
+ if ( ! obligationExpression.isOk()) {
+ throw new EvaluationException(obligationExpression.getStatusMessage());
+ }
+ if (decision == null || obligationExpression.getRuleEffect().getDecision().equals(decision)) {
+ Obligation obligation = obligationExpression.evaluate(evaluationContext, policyDefaults);
+ if (obligation != null) {
+ listObligations.add(obligation);
+ }
+ }
+ }
+ return listObligations;
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (this.getObligationId() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing ObligationId attribute");
+ return false;
+ } else if (this.getRuleEffect() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing FulfillOn attribute");
+ return false;
+ } else {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Policy.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Policy.java
new file mode 100755
index 0000000..a7efaa5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Policy.java
@@ -0,0 +1,323 @@
+/*
+ * 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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Result;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.trace.StdTraceEvent;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+
+/**
+ * Policy extends {@link com.att.research.xacmlatt.pdp.policy.PolicyDef} to represent a XACML 3.0 Policy element.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class Policy extends PolicyDef {
+ private TargetedCombinerParameterMap<String,Rule> ruleCombinerParameters = new TargetedCombinerParameterMap<String,Rule>();
+ private VariableMap variableMap = new VariableMap();
+ private List<Rule> rules = new ArrayList<Rule>();
+ private List<CombiningElement<Rule>> combiningRules;
+ private CombiningAlgorithm<Rule> ruleCombiningAlgorithm;
+
+ @Override
+ protected boolean validateComponent() {
+ if (super.validateComponent()) {
+ if (this.getRuleCombiningAlgorithm() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing rule combining algorithm");
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Performs lazy evaluation of the combining parameters from this <code>Policy</code>.
+ *
+ * @return the <code>List</code> of <code>CombiningElement</code>s for all of the <code>Rule</code>s
+ */
+ protected List<CombiningElement<Rule>> getCombiningRules() {
+ if (this.combiningRules == null) {
+ this.combiningRules = new ArrayList<CombiningElement<Rule>>();
+ Iterator<Rule> iterRules = this.getRules();
+ while (iterRules.hasNext()) {
+ Rule rule = iterRules.next();
+ this.combiningRules.add(new CombiningElement<Rule>(rule, this.ruleCombinerParameters.getCombinerParameters(rule)));
+ }
+ }
+ return this.combiningRules;
+ }
+
+ public Policy(PolicySet policySetParent, StatusCode statusCodeIn, String statusMessageIn) {
+ super(policySetParent, statusCodeIn, statusMessageIn);
+ }
+
+ public Policy(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public Policy(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public Policy(PolicySet policySetParent) {
+ super(policySetParent);
+ }
+
+ public Policy() {
+ super();
+ ruleCombinerParameters.getTargetedCombinerParameters();
+ }
+
+ /**
+ * Gets an <code>Iterator</code> over the {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter}s for
+ * the {@link Rule}s in this <code>Policy</code>.
+ *
+ * @return an <code>Iterator</code> over the <code>TargetedCombinerParameter</code>s for this <code>Policy</code>.
+ */
+ public Iterator<TargetedCombinerParameter<String,Rule>> getRuleCombinerParameters() {
+ return this.ruleCombinerParameters.getTargetedCombinerParameters();
+ }
+
+ /**
+ * Sets the Rule combiner parameters for this <code>Policy</code> to the contents of the given <code>Collection</code> of
+ * <code>TargetedCombinerParameter</code>s.
+ *
+ * @param ruleCombinerParameters the <code>Collection</code> of <code>TargetedCombinerParameter</code>s to set
+ */
+ public void setRuleCombinerParameters(Collection<TargetedCombinerParameter<String,Rule>> ruleCombinerParameters) {
+ this.ruleCombinerParameters.setCombinerParameters(ruleCombinerParameters);
+ }
+
+ /**
+ * Adds the given <code>TargetedCombinerParameter</code> to the set of Rule combiner parameters for this <code>Policy</code>.
+ * @param ruleCombinerParameter the <code>TargetedCombinerParameter</code> for <code>Rule</code>s to add.
+ */
+ public void addRuleCombinerParameter(TargetedCombinerParameter<String,Rule> ruleCombinerParameter) {
+ this.ruleCombinerParameters.addCombinerParameter(ruleCombinerParameter);
+ }
+
+ /**
+ * Adds the contents of the given <code>Collection</code> of <code>TargetedCombinerParameter</code>s to the set of Rule combiner parameters
+ * for this <code>Policy</code>.
+ *
+ * @param ruleCombinerParameters the <code>Collection</code> of <code>TargetedCombinerParameter</code>s to add
+ */
+ public void addRuleCombinerParameters(Collection<TargetedCombinerParameter<String,Rule>> ruleCombinerParameters) {
+ this.ruleCombinerParameters.addCombinerParameters(ruleCombinerParameters);
+ }
+
+ /**
+ * Gets an <code>Iterator</code> over the {@link com.att.research.xacmlatt.pdp.policy.VariableDefinition}s in this <code>Policy</code>.
+ *
+ * @return an <code>Iterator</code> over the <code>VariableDefinition</code>s in this <code>Policy</code>
+ */
+ public Iterator<VariableDefinition> getVariableDefinitions() {
+ return this.variableMap.getVariableDefinitions();
+ }
+
+ /**
+ * Gets the <code>VariableDefinition</code> for the given <code>String</code> variable identifier.
+ *
+ * @param variableId the <code>String</code> variable identifier
+ * @return the <code>VariableDefinition</code> with the given <code>String</code> identifier or null if not found
+ */
+ public VariableDefinition getVariableDefinition(String variableId) {
+ return this.variableMap.getVariableDefinition(variableId);
+ }
+
+ /**
+ * Sets the <code>VariableDefinition</code>s in this <code>Policy</code> to the contents of the given <code>Collection</code>.
+ *
+ * @param listVariableDefinitions the <code>Collection</code> of <code>VariableDefinition</code>s to set
+ */
+ public void setVariableDefinitions(Collection<VariableDefinition> listVariableDefinitions) {
+ this.variableMap.setVariableDefinitions(listVariableDefinitions);
+ }
+
+ /**
+ * Adds the given <code>VariableDefinition</code> to the set of <code>VariableDefinition</code>s for this <code>Policy</code>.
+ *
+ * @param variableDefinition the <code>VariableDefinition</code> to add
+ */
+ public void addVariableDefinition(VariableDefinition variableDefinition) {
+ this.variableMap.add(variableDefinition);
+ }
+
+ /**
+ * Adds the contents of the given <code>Collection</code> of <code>VariableDefinition</code>s to this <code>Policy</code>.
+ *
+ * @param variableDefinitions the <code>Collection</code> of <code>VariableDefinition</code>s to add.
+ */
+ public void addVariableDefinitions(Collection<VariableDefinition> variableDefinitions) {
+ this.variableMap.addVariableDefinitions(variableDefinitions);
+ }
+
+ /**
+ * Gets an <code>Iterator</code> over the <code>Rule</code>s in this <code>Policy</code> or null if there are none.
+ *
+ * @return an <code>Iterator</code> over the <code>Rule</code>s in this <code>Policy</code> or null if there are none.
+ */
+ public Iterator<Rule> getRules() {
+ return this.rules.iterator();
+ }
+
+ /**
+ * Sets the <code>Rule</code>s for this <code>Policy</code> to the contents of the given <code>Collection</code> of
+ * <code>Rule</code>s. If the <code>Collection</code> is null, the set of <code>Rule</code>s for this <code>Policy</code> is set to null.
+ *
+ * @param listRules the <code>Collection</code> of <code>Rule</code>s or null
+ */
+ public void setRules(Collection<Rule> listRules) {
+ this.rules.clear();
+ if (listRules != null) {
+ this.addRules(listRules);
+ }
+ }
+
+ /**
+ * Adds the given <code>Rule</code> to the set of <code>Rule</code>s for this <code>Policy</code>.
+ *
+ * @param rule the <code>Rule</code> to add
+ */
+ public void addRule(Rule rule) {
+ this.rules.add(rule);
+ }
+
+ /**
+ * Adds the contents of the given <code>Collection</code> of <code>Rule</code>s to the set of <code>Rule</code>s for
+ * this <code>Policy</code>.
+ *
+ * @param listRules the <code>Collection</code> of <code>Rule</code>s to add
+ */
+ public void addRules(Collection<Rule> listRules) {
+ this.rules.addAll(listRules);
+ }
+
+ /**
+ * Gets the <code>CombiningAlgorithm</code> for <code>Rule</code>s for this <code>Policy</code>.
+ *
+ * @return the <code>CombiningAlgorithm</code> for <code>Rule</code>s for this <code>Policy</code>.
+ */
+ public CombiningAlgorithm<Rule> getRuleCombiningAlgorithm() {
+ return this.ruleCombiningAlgorithm;
+ }
+
+ /**
+ * Sets the <code>CombiningAlgorithm</code> for <code>Rule</code>s for this <code>Policy</code>>
+ *
+ * @param ruleCombiningAlgorithmIn the <code>CombiningAlgorithm</code> for <code>Rule</code>s for this <code>Policy</code>
+ */
+ public void setRuleCombiningAlgorithm(CombiningAlgorithm<Rule> ruleCombiningAlgorithmIn) {
+ this.ruleCombiningAlgorithm = ruleCombiningAlgorithmIn;
+ }
+
+ @Override
+ public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException {
+ /*
+ * First check to see if we are valid. If not, return an error status immediately
+ */
+ if (!this.validate()) {
+ return new EvaluationResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+
+ /*
+ * See if we match
+ */
+ MatchResult thisMatchResult = this.match(evaluationContext);
+ assert(thisMatchResult != null);
+ if (evaluationContext.isTracing()) {
+ evaluationContext.trace(new StdTraceEvent<MatchResult>("Match", this, thisMatchResult));
+ }
+ switch(thisMatchResult.getMatchCode()) {
+ case INDETERMINATE:
+ return new EvaluationResult(Decision.INDETERMINATE, thisMatchResult.getStatus());
+ case MATCH:
+ break;
+ case NOMATCH:
+ return new EvaluationResult(Decision.NOTAPPLICABLE);
+ }
+
+ /*
+ * Get the combining elements
+ */
+ List<CombiningElement<Rule>> ruleCombiningElements = this.getCombiningRules();
+ assert(ruleCombiningElements != null);
+
+ /*
+ * Run the combining algorithm
+ */
+ assert(this.getRuleCombiningAlgorithm() != null);
+ EvaluationResult evaluationResultCombined = this.getRuleCombiningAlgorithm().combine(evaluationContext, ruleCombiningElements, this.getCombinerParameterList());
+ assert(evaluationResultCombined != null);
+
+ if (evaluationResultCombined.getDecision() == Decision.DENY || evaluationResultCombined.getDecision() == Decision.PERMIT) {
+ this.updateResult(evaluationResultCombined, evaluationContext);
+
+ /*
+ * Add my id to the policy identifiers
+ */
+ if (evaluationContext.getRequest().getReturnPolicyIdList()) {
+ evaluationResultCombined.addPolicyIdentifier(this.getIdReference());
+ }
+ }
+ if (evaluationContext.isTracing()) {
+ evaluationContext.trace(new StdTraceEvent<Result>("Result", this, evaluationResultCombined));
+ }
+ return evaluationResultCombined;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ String iteratorToDump;
+ if ((iteratorToDump = StringUtils.toString(this.getRuleCombinerParameters())) != null) {
+ stringBuilder.append(",ruleCombinerParameters=");
+ stringBuilder.append(iteratorToDump);
+ }
+ if ((iteratorToDump = StringUtils.toString(this.getVariableDefinitions())) != null) {
+ stringBuilder.append(",variableDefinitions=");
+ stringBuilder.append(iteratorToDump);
+ }
+ if ((iteratorToDump = StringUtils.toString(this.getRules())) != null) {
+ stringBuilder.append(",rules=");
+ stringBuilder.append(iteratorToDump);
+ }
+
+ Object objectToDump;
+ if ((objectToDump = this.getRuleCombiningAlgorithm()) != null) {
+ stringBuilder.append(",ruleCombiningAlgorithm=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyComponent.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyComponent.java
new file mode 100755
index 0000000..9195249
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyComponent.java
@@ -0,0 +1,144 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatusCode;
+
+/**
+ * PolicyComponent is the base class for all pieces of a XACML Policy or PolicySet that could potentially have errors associated
+ * with them by the policy loader.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+abstract class PolicyComponent {
+ private StatusCode statusCode;
+ private String statusMessage;
+
+ /**
+ * Creates a new <code>PolicyComponent</code> with the given {@link com.att.research.xacml.api.StatusCode} and
+ * <code>String</code> detailed message. If the <code>StatusCode</code> is null, a default OK status code is used.
+ *
+ * @param statusCodeIn the <code>StatusCode</code> for the new <code>PolicyComponent</code>
+ * @param statusMessageIn the <code>String</code> detailed status message for the new <code>PolicyComponent</code>
+ */
+ public PolicyComponent(StatusCode statusCodeIn, String statusMessageIn) {
+ this.statusCode = statusCodeIn;
+ this.statusMessage = statusMessageIn;
+ }
+
+ /**
+ * Creates a new <code>PolicyComponent</code> with the given <code>StatusCode</code> and no status message.
+ *
+ * @param statusCodeIn the <code>StatusCode</code> for the new <code>PolicyComponent</code>
+ */
+ public PolicyComponent(StatusCode statusCodeIn) {
+ this(statusCodeIn, null);
+ }
+
+ /**
+ * Creates a new <code>PolicyCOmponent</code> with no <code>StatusCode</code> or status message.
+ */
+ public PolicyComponent() {
+ this(null, null);
+ }
+
+ /**
+ * Gets the <code>StatusCode</code> associated with this <code>PolicyComponent</code>.
+ *
+ * @return the <code>StatusCode</code> associated with this <code>PolicyComponent</code>
+ */
+ public StatusCode getStatusCode() {
+ return this.statusCode;
+ }
+
+ /**
+ * Gets the <code>String</code> status message associated with this <code>PolicyComponent</code>.
+ *
+ * @return the <code>String</code> status message associated with this <code>PolicyComponent</code> or null if none
+ */
+ public String getStatusMessage() {
+ return this.statusMessage;
+ }
+
+ /**
+ * Sets the <code>StatusCode</code> and <code>String</code> status message for this <code>PolicyComponent</code>.
+ * This method is mainly provided for objects that may have lazy evaluations performed on them, in which case the
+ * status is not determined until the object is actually used.
+ *
+ * @param statusCodeIn the <code>StatusCode</code> for this <code>PolicyComponent</code>
+ * @param messageIn the <code>String</code> status message for this <code>PolicyComponent</code>
+ */
+ public void setStatus(StatusCode statusCodeIn, String messageIn) {
+ this.statusCode = statusCodeIn;
+ this.statusMessage = messageIn;
+ }
+
+ /**
+ * Does a check on the <code>StatusCode</code> for this element to determine if it is equivalent to the
+ * OK status code.
+ *
+ * @return true if the <code>StatusCode</code> is equivalent to OK, otherwise false
+ */
+ public boolean isOk() {
+ return StdStatusCode.STATUS_CODE_OK.equals(this.getStatusCode());
+ }
+
+ /**
+ * Validates that this <code>PolicyComponent</code> has all of the required elements according to the XACML 3.0
+ * specification. If the component is not valid, this method should set the <code>StatusCode</code> to reflect a
+ * syntax error, and should set the status message to reflect the invalid piece(s).
+ *
+ * <code>PolicyComponent</code>s that implement this method should only validate their immediate elements and not perform
+ * a deep validation of descendents.
+ *
+ * @return true if the resulting status code is OK, otherwise false
+ */
+ abstract protected boolean validateComponent();
+
+ /**
+ * If a <code>StatusCode</code> has not been set, ask this <code>PolicyComponent</code> to validate itself and return
+ * the value from the validation. Otherwise, check to see if the cached <code>StatusCode</code> indicates this <code>PolicyComponent</code> is valid.
+ *
+ * @return true if this <code>PolicyComponent</code> is valid, else false.
+ */
+ public boolean validate() {
+ if (this.getStatusCode() == null) {
+ return this.validateComponent();
+ } else {
+ return this.isOk();
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+ Object objectToDump;
+ boolean needsComma = false;
+ if ((objectToDump = this.getStatusCode()) != null) {
+ stringBuilder.append("statusCode=");
+ stringBuilder.append(objectToDump.toString());
+ needsComma = true;
+ }
+ if ((objectToDump = this.getStatusMessage()) != null) {
+ if (needsComma) {
+ stringBuilder.append(',');
+ }
+ stringBuilder.append("statusMessage=");
+ stringBuilder.append((String)objectToDump);
+ needsComma = true;
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDef.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDef.java
new file mode 100755
index 0000000..1c785c5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDef.java
@@ -0,0 +1,476 @@
+/*
+ * 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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Advice;
+import com.att.research.xacml.api.IdReference;
+import com.att.research.xacml.api.IdReferenceMatch;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Obligation;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.Version;
+import com.att.research.xacml.api.VersionMatch;
+import com.att.research.xacml.std.StdIdReference;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+
+/**
+ * PolicyDef extends {@link com.att.research.xacmlatt.pdp.policy.PolicySetChild} with members and methods common
+ * to XACML 3.0 Policies and PolicySets.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public abstract class PolicyDef extends PolicySetChild {
+ private String description;
+ private PolicyIssuer policyIssuer;
+ private Target target;
+ private List<CombinerParameter> combinerParameters;
+ private List<ObligationExpression> obligationExpressions;
+ private List<AdviceExpression> adviceExpressions;
+ private Version version;
+ private Integer maxDelegationDepth;
+
+ private IdReference idReference;
+
+ private void ensureCombinerParameters() {
+ if (this.combinerParameters == null) {
+ this.combinerParameters = new ArrayList<CombinerParameter>();
+ }
+ }
+
+ private void ensureObligationExpressions() {
+ if (this.obligationExpressions == null) {
+ this.obligationExpressions = new ArrayList<ObligationExpression>();
+ }
+ }
+
+ private void ensureAdviceExpressions() {
+ if (this.adviceExpressions == null) {
+ this.adviceExpressions = new ArrayList<AdviceExpression>();
+ }
+ }
+
+ protected List<CombinerParameter> getCombinerParameterList() {
+ return this.combinerParameters;
+ }
+
+ protected List<ObligationExpression> getObligationExpressionList() {
+ return this.obligationExpressions;
+ }
+
+ protected List<AdviceExpression> getAdviceExpressionList() {
+ return this.adviceExpressions;
+ }
+
+ protected void updateResult(EvaluationResult evaluationResult, EvaluationContext evaluationContext) throws EvaluationException {
+ List<ObligationExpression> thisObligationExpressions = this.getObligationExpressionList();
+ if (thisObligationExpressions != null && thisObligationExpressions.size() > 0) {
+ List<Obligation> listObligations = ObligationExpression.evaluate(evaluationContext, this.getPolicyDefaults(), evaluationResult.getDecision(), thisObligationExpressions);
+ if (listObligations != null && listObligations.size() > 0) {
+ evaluationResult.addObligations(listObligations);
+ }
+ }
+
+ List<AdviceExpression> thisAdviceExpressions = this.getAdviceExpressionList();
+ if (thisAdviceExpressions != null && thisAdviceExpressions.size() > 0) {
+ List<Advice> listAdvices = AdviceExpression.evaluate(evaluationContext, this.getPolicyDefaults(), evaluationResult.getDecision(), thisAdviceExpressions);
+ if (listAdvices != null && listAdvices.size() > 0) {
+ evaluationResult.addAdvice(listAdvices);
+ }
+ }
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (super.validateComponent()) {
+ if (this.getVersion() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing version string");
+ return false;
+ } else if (this.getTarget() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Target in policy " + this.getIdReference().getId().stringValue());
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ public PolicyDef(PolicySet policySetParent, StatusCode statusCodeIn, String statusMessageIn) {
+ super(policySetParent, statusCodeIn, statusMessageIn);
+ }
+
+ public PolicyDef(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public PolicyDef(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public PolicyDef(PolicySet policySetParent) {
+ super(policySetParent);
+ }
+
+ public PolicyDef() {
+ super();
+ }
+
+ @Override
+ public void setIdentifier(Identifier identifierIn) {
+ super.setIdentifier(identifierIn);
+ this.idReference = null;
+ }
+
+ /**
+ * Gets the <code>String</code> description of this <code>PolicyDef</code>.
+ *
+ * @return the <code>String</code> description of this <code>PolicyDef</code>.
+ */
+ public String getDescription() {
+ return this.description;
+ }
+
+ /**
+ * Sets the <code>String</code> description of this <code>PolicyDef</code>.
+ *
+ * @param s the <code>String</code> description of this <code>PolicyDef</code>
+ */
+ public void setDescription(String s) {
+ this.description = s;
+ }
+
+ /**
+ * Gets the {@link com.att.research.xacmlatt.pdp.policy.PolicyIssuer} for this <code>PolicyDef</code>.
+ *
+ * @return the <code>PolicyIssuer</code> for this <code>PolicyDef</code>
+ */
+ public PolicyIssuer getPolicyIssuer() {
+ return this.policyIssuer;
+ }
+
+ /**
+ * Sets the <code>PolicyIssuer</code> for this <code>PolicyDef</code>.
+ *
+ * @param policyIssuerIn the <code>PolicyIssuer</code> for this <code>PolicyDef</code>.
+ */
+ public void setPolicyIssuer(PolicyIssuer policyIssuerIn) {
+ this.policyIssuer = policyIssuerIn;
+ }
+
+ /**
+ * Gets the <code>Target</code> for this <code>PolicyDef</code>.
+ *
+ * @return the <code>Target</code> for this <code>PolicyDef</code>
+ */
+ public Target getTarget() {
+ return this.target;
+ }
+
+ /**
+ * Sets the <code>Target</code> for this <code>PolicyDef</code>.
+ *
+ * @param targetIn the <code>Target</code> for this <code>PolicyDef</code>
+ */
+ public void setTarget(Target targetIn) {
+ this.target = targetIn;
+ }
+
+ /**
+ * Gets an <code>Iterator</code> over the <code>CombinerParameter</code>s for this <code>Policy</code>.
+ *
+ * @return an <code>Iterator</code> over the <code>CombinerParameter</code>s for this <code>Policy</code> or null if there are none
+ */
+ public Iterator<CombinerParameter> getCombinerParameters() {
+ return (this.combinerParameters == null ? null : this.combinerParameters.iterator());
+ }
+
+ /**
+ * Sets the <code>CombinerParameter</code>s for this<code>Policy</code> to the contents of the
+ * given <code>Collection</code>. If the <code>Collection</code> is null, the set of <code>CombinerParameter</code>s
+ * for this <code>Policy</code> is set to null.
+ *
+ * @param combinerParametersIn the <code>Collection</code> of <code>CombinerParameter</code>s for this <code>PolicyDef</code>
+ */
+ public void setCombinerParameters(Collection<CombinerParameter> combinerParametersIn) {
+ this.combinerParameters = null;
+ if (combinerParametersIn != null) {
+ this.addCombinerParameters(combinerParametersIn);
+ }
+ }
+
+ /**
+ * Adds the given <code>CombinerParameter</code> to the set of <code>CombinerParameter</code>s for this
+ * <code>PolicyDef</code>>
+ *
+ * @param combinerParameter the <code>CombinerParameter</code> to add
+ */
+ public void add(CombinerParameter combinerParameter) {
+ this.ensureCombinerParameters();
+ this.combinerParameters.add(combinerParameter);
+ }
+
+ /**
+ * Adds the given <code>Collection</code> of <code>CombinerParameter</code>s to this <code>PolicyDef</code>>
+ *
+ * @param combinerParametersIn the <code>Collection</code> of <code>CombinerParameter</code>s to add
+ */
+ public void addCombinerParameters(Collection<CombinerParameter> combinerParametersIn) {
+ this.ensureCombinerParameters();
+ this.combinerParameters.addAll(combinerParametersIn);
+ }
+
+ /**
+ * Gets an <code>Iterator</code> over the <code>ObligationExpression</code>s for this <code>PolicyDef</code>.
+ *
+ * @return an <code>Iterator</code> over the <code>ObligationExpression</code>s for this <code>PolicyDef</code> or null if there are none.
+ */
+ public Iterator<ObligationExpression> getObligationExpressions() {
+ return (this.obligationExpressions == null ? null : this.obligationExpressions.iterator());
+ }
+
+ /**
+ * Sets the <code>ObligationExpression</code>s for this <code>PolicyDef</code> to the contents of the given <code>Collection</code>.
+ * If the <code>Collection</code> is null, the <code>ObligationExpression</code>s for this <code>PolicyDef</code> are set to null.
+ *
+ * @param obligationExpressionsIn the <code>Collection</code> of <code>ObligationExpression</code>s for this <code>PolicyDef</code>.
+ */
+ public void setObligationExpressions(Collection<ObligationExpression> obligationExpressionsIn) {
+ this.obligationExpressions = null;
+ if (obligationExpressionsIn != null) {
+ this.addObligationExpressions(obligationExpressionsIn);
+ }
+ }
+
+ /**
+ * Adds the given <code>ObligationExpression</code> to the set of <code>ObligationExpression</code>s for this <code>PolicyDef</code>.
+ *
+ * @param obligationExpression the <code>ObligationExpression</code> to add
+ */
+ public void add(ObligationExpression obligationExpression) {
+ this.ensureObligationExpressions();
+ this.obligationExpressions.add(obligationExpression);
+ }
+
+ /**
+ * Adds the contents of the given <code>Collection</code> of <code>ObligationExpression</code>s to the set of <code>ObligationExpression</code>s for
+ * this <code>PolicyDef</code>.
+ *
+ * @param obligationExpressionsIn the <code>Collection</code> of <code>ObligationExpression</code>s to add
+ */
+ public void addObligationExpressions(Collection<ObligationExpression> obligationExpressionsIn) {
+ this.ensureObligationExpressions();
+ this.obligationExpressions.addAll(obligationExpressionsIn);
+ }
+
+ /**
+ * Gets an <code>Iterator</code> over the set of <code>AdviceExpression</code>s for this <code>PolicyDef</code>.
+ *
+ * @return an <code>Iterator</code> over the set of <code>AdviceExpression</code>s for this <code>PolicyDef</code> or null if there are none.
+ */
+ public Iterator<AdviceExpression> getAdviceExpressions() {
+ return (this.adviceExpressions == null ? null : this.adviceExpressions.iterator());
+ }
+
+ /**
+ * Sets the set of <code>AdviceExpression</code>s for this <code>PolicyDef</code> to the contents of the given <code>Collection</code>.
+ *
+ * @param adviceExpressionsIn the <code>Collection</code> of <code>AdviceExpression</code> to add
+ */
+ public void setAdviceExpressions(Collection<AdviceExpression> adviceExpressionsIn) {
+ this.adviceExpressions = null;
+ if (adviceExpressionsIn != null) {
+ this.addAdviceExpressions(adviceExpressionsIn);
+ }
+ }
+
+ /**
+ * Adds the given <code>AdviceExpression</code> to the set of <code>AdviceExpression</code>s for this <code>PolicyDef</code>.
+ *
+ * @param adviceExpression the <code>AdviceExpression</code> to add.
+ */
+ public void add(AdviceExpression adviceExpression) {
+ this.ensureAdviceExpressions();
+ this.adviceExpressions.add(adviceExpression);
+ }
+
+ /**
+ * Adds the contents of the given <code>Collection</code> of <code>AdviceExpression</code>s to the set of
+ * <code>AdviceExpression</code>s for this <code>PolicyDef</code>.
+ *
+ * @param adviceExpressionsIn the <code>Collection</code> of <code>AdviceExpression</code>s to add.
+ */
+ public void addAdviceExpressions(Collection<AdviceExpression> adviceExpressionsIn) {
+ this.ensureAdviceExpressions();
+ this.adviceExpressions.addAll(adviceExpressionsIn);
+ }
+
+ /**
+ * Gets the <code>String</code> version for this <code>PolicyDef</code>.
+ *
+ * @return the <code>String</code> version for this <code>PolicyDef</code>.
+ */
+ public Version getVersion() {
+ return this.version;
+ }
+
+ /**
+ * Sets the version <code>String</code> for this <code>PolicyDef</code>>
+ *
+ * @param versionIn the <code>String</code> version for this <code>PolicyDef</code>
+ */
+ public void setVersion(Version versionIn) {
+ this.version = versionIn;
+ this.idReference = null;
+ }
+
+ /**
+ * Creates the <code>IdReference</code> for this <code>PolicyDef</code> if needed and returns it.
+ *
+ * @return the <code>IdReference</code> for this <code>PolicyDef</code>
+ */
+ public IdReference getIdReference() {
+ if (this.idReference == null) {
+ this.idReference = new StdIdReference(this.getIdentifier(), this.getVersion());
+ }
+ return this.idReference;
+ }
+
+ public boolean matches(IdReferenceMatch idReferenceRequest) {
+ IdReference thisIdReference = this.getIdReference();
+ if (thisIdReference == null || thisIdReference.getId() == null || idReferenceRequest == null || idReferenceRequest.getId() == null) {
+ return false;
+ } else if (!thisIdReference.getId().equals(idReferenceRequest.getId())) {
+ return false;
+ }
+
+ /*
+ * Now do version number matching
+ */
+ VersionMatch idReferenceRequestVersion = idReferenceRequest.getVersion();
+ if (idReferenceRequestVersion != null) {
+ /*
+ * Do exact version matching
+ */
+ Version thisVersion = thisIdReference.getVersion();
+ if (thisVersion == null) {
+ return false;
+ } else {
+ return idReferenceRequestVersion.match(thisVersion, 0);
+ }
+ } else {
+ VersionMatch idReferenceRequestEarliestVersion = idReferenceRequest.getEarliestVersion();
+ Version thisVersion = thisIdReference.getVersion();
+
+ if (idReferenceRequestEarliestVersion != null) {
+ if (thisVersion == null) {
+ return false;
+ } else if (!idReferenceRequestEarliestVersion.match(thisVersion, 1)) {
+ return false;
+ }
+ }
+
+ VersionMatch idReferenceRequestLatestVersion = idReferenceRequest.getLatestVersion();
+ if (idReferenceRequestLatestVersion != null) {
+ if (thisVersion == null) {
+ return false;
+ } else if (!idReferenceRequestLatestVersion.match(thisVersion, -1)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+
+ /**
+ * Gets the <code>Integer</code> maximum delegation depth for this <code>PolicyDef</code>.
+ *
+ * @return the <code>Integer</code> maximum delegation depth for this <code>PolicyDef</code>
+ */
+ public Integer getMaxDelegationDepth() {
+ return this.maxDelegationDepth;
+ }
+
+ /**
+ * Sets the <code>Integer</code> maximum delegation depth for this <code>PolicyDef</code>
+ * @param i the <code>Integer</code> maximum delegation depth for this <code>PolicyDef</code>
+ */
+ public void setMaxDelegationDepth(Integer i) {
+ this.maxDelegationDepth = i;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ Object objectToDump;
+ if ((objectToDump = this.getDescription()) != null) {
+ stringBuilder.append(",description=");
+ stringBuilder.append((String)objectToDump);
+ }
+ if ((objectToDump = this.getPolicyIssuer()) != null) {
+ stringBuilder.append(",policyIssuer=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ if ((objectToDump = this.getTarget()) != null) {
+ stringBuilder.append(",target=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ String iteratorToString;
+ if ((iteratorToString = StringUtils.toString(this.getCombinerParameters())) != null) {
+ stringBuilder.append(",combinerParameters=");
+ stringBuilder.append(iteratorToString);
+ }
+ if ((iteratorToString = StringUtils.toString(this.getObligationExpressions())) != null) {
+ stringBuilder.append(",obligationExpressions=");
+ stringBuilder.append(iteratorToString);
+ }
+ if ((iteratorToString = StringUtils.toString(this.getAdviceExpressions())) != null) {
+ stringBuilder.append(",adviceExpressions=");
+ stringBuilder.append(iteratorToString);
+ }
+ if ((objectToDump = this.getVersion()) != null) {
+ stringBuilder.append(",version=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ if ((objectToDump = this.getMaxDelegationDepth()) != null) {
+ stringBuilder.append(",maxDelegationDepth=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+ @Override
+ public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException {
+ if (!this.validate()) {
+ return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+ return this.getTarget().match(evaluationContext);
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.java
new file mode 100755
index 0000000..a2c0c3c
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.java
@@ -0,0 +1,111 @@
+/*
+ * 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.policy;
+
+import java.net.URI;
+
+import com.att.research.xacml.api.XACML;
+
+/**
+ * PolicyDefaults represents the default values associated with a XACML 3.0 Policy or PolicySet that may
+ * be overridden or inherited by child Policies or PolicySets.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class PolicyDefaults {
+ private static URI xpathVersionDefault;
+
+ static {
+ try {
+ xpathVersionDefault = new URI(XACML.XPATHVERSION_2_0);
+ } catch (Exception ex) {
+
+ }
+ }
+
+ private URI xpathVersion;
+ private PolicyDefaults policyDefaultsParent;
+
+ /**
+ * Creates a new <code>PolicyDefaults</code> with the given <code>URI</code> for the XPath version and
+ * the given <code>PolicyDefaults</code> pointing to the parent.
+ *
+ * @param xpathVersionIn the <code>URI</code> representing the XPath version for the new <code>PolicyDefaults</code>
+ * @param policyDefaultsParentIn the <code>PolicyDefaults</code> object that is the parent of the new <code>PolicyDefaults</code>
+ */
+ public PolicyDefaults(URI xpathVersionIn, PolicyDefaults policyDefaultsParentIn) {
+ this.xpathVersion = xpathVersionIn;
+ this.policyDefaultsParent = policyDefaultsParentIn;
+ }
+
+ /**
+ * Gets the parent <code>PolicyDefaults</code> for this <code>PolicyDefaults</code>.
+ *
+ * @return the parent <code>PolicyDefaults</code> for this <code>PolicyDefaults</code> or null if none
+ */
+ public PolicyDefaults getPolicyDefaultsParent() {
+ return this.policyDefaultsParent;
+ }
+
+ /**
+ * Gets the XPath version <code>URI</code> for this <code>PolicyDefaults</code>. If there is no explicit
+ * version in this <code>PolicyDefaults</code>, walk up the parent <code>PolicyDefaults</code> hierarchy until
+ * one is found, or return the default value.
+ *
+ * @return the <code>URI</code> for the XPath version
+ */
+ public URI getXPathVersion() {
+ /*
+ * See if the XPath version was explicitly set here
+ */
+ if (this.xpathVersion != null) {
+ return this.xpathVersion;
+ }
+
+ /*
+ * Try the parent hierarchy if there is one
+ */
+ PolicyDefaults policyDefaultsParentThis = this.getPolicyDefaultsParent();
+ if (policyDefaultsParentThis != null) {
+ return policyDefaultsParentThis.getXPathVersion();
+ }
+
+ /*
+ * Use the default
+ */
+ return xpathVersionDefault;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+
+ boolean needsComma = false;
+ Object objectToDump;
+ if ((objectToDump = this.xpathVersion) != null) {
+ stringBuilder.append("xpathVersion=");
+ stringBuilder.append(objectToDump.toString());
+ needsComma = true;
+ }
+ if ((objectToDump = this.getPolicyDefaultsParent()) != null) {
+ if (needsComma) {
+ stringBuilder.append(',');
+ }
+ stringBuilder.append("policyDefaultsParent=");
+ stringBuilder.append(objectToDump.toString());
+ needsComma = true;
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinder.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinder.java
new file mode 100755
index 0000000..8a3b391
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinder.java
@@ -0,0 +1,50 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.IdReferenceMatch;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+
+/**
+ * PolicyFinder is the interface for objects that can locate XACML Policies and PolicySets by identifier and contains the root
+ * Policy or Policy set. The interface is designed to allow for finders that can retrieve a root policy from a repository based on
+ * matching a {@link com.att.research.xacml.api.Request}.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public interface PolicyFinder {
+ /**
+ * Gets the root {@link PolicyDef} from the policy store
+ * configured by the particular implementation of the <code>PolicyFinderFactory</code> class that
+ * is applicable to the {@link com.att.research.xacml.api.Request} in the given {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}.
+ *
+ * @return a <code>PolicyFinderResult</code> with the root <code>PolicyDef</code>
+ */
+ public PolicyFinderResult<PolicyDef> getRootPolicyDef(EvaluationContext evaluationContext);
+
+ /**
+ * Gets the {@link Policy} that matches the given {@link com.att.research.xacml.api.IdReferenceMatch}.
+ *
+ * @param idReferenceMatch the <code>IdReferenceMatch</code> to search for
+ * @return a <code>PolicyFinderResult</code> with the <code>Policy</code> matching the given <code>IdReferenceMatch</code>
+ */
+ public PolicyFinderResult<Policy> getPolicy(IdReferenceMatch idReferenceMatch);
+
+ /**
+ * Gets the {@link PolicySet} that matches the given {@link com.att.research.xacml.api.IdReferenceMatch}.
+ *
+ * @param idReferenceMatch the <code>IdReferenceMatch</code> to search for
+ * @return a <code>PolicyFinderResult</code> with the <code>PolicySet</code> matching the given <code>IdReferenceMatch</code>.
+ */
+ public PolicyFinderResult<PolicySet> getPolicySet(IdReferenceMatch idReferenceMatch);
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.java
new file mode 100755
index 0000000..f700046
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.java
@@ -0,0 +1,65 @@
+/*
+ * 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.policy;
+
+import java.util.Properties;
+
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.FactoryFinder;
+import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
+
+/**
+ * PolicyFinderFactory provides methods for loading XACML 3.0 policies and policy sets that are used
+ * by the {@link com.att.research.xacmlatt.pdp.PDPEngine} to evaluate requests.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public abstract class PolicyFinderFactory {
+ private static final String FACTORYID = ATTPDPProperties.PROP_POLICYFINDERFACTORY;
+ private static final String DEFAULT_FACTORY_CLASSNAME = "com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory";
+
+ protected PolicyFinderFactory() {
+ }
+
+ protected PolicyFinderFactory(Properties properties) {
+ }
+
+ public static PolicyFinderFactory newInstance() throws FactoryException {
+ return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, PolicyFinderFactory.class);
+ }
+
+ public static PolicyFinderFactory newInstance(Properties properties) throws FactoryException {
+ return FactoryFinder.find(FACTORYID, DEFAULT_FACTORY_CLASSNAME, PolicyFinderFactory.class, properties);
+ }
+
+ public static PolicyFinderFactory newInstance(String className, ClassLoader classLoader) throws FactoryException {
+ return FactoryFinder.newInstance(className, PolicyFinderFactory.class, classLoader, false);
+ }
+
+ public static PolicyFinderFactory newInstance(String className) throws FactoryException {
+ return FactoryFinder.newInstance(className, PolicyFinderFactory.class, null, true);
+ }
+
+ /**
+ * Gets the configured {@link PolicyFinder}.
+ *
+ * @return the configured <code>PolicyFinder</code>
+ */
+ abstract public PolicyFinder getPolicyFinder() throws FactoryException;
+
+ /**
+ * Gets the configured {@link PolicyFinder}.
+ *
+ * @return the configured <code>PolicyFinder</code>
+ */
+ abstract public PolicyFinder getPolicyFinder(Properties properties) throws FactoryException;
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.java
new file mode 100755
index 0000000..fe1d8ab
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.java
@@ -0,0 +1,36 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.Status;
+
+/**
+ * PolicyFinderResult is the interface for return values of the methods in the {@link com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory} interface.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ * @param <T> the class extending {@link PolicyDef} contained as a result in this <code>PolicyFinderResult</code>
+ */
+public interface PolicyFinderResult<T extends PolicyDef> {
+ /**
+ * Gets the {@link com.att.research.xacml.api.Status} of the method call.
+ *
+ * @return the <code>Status</code> of the method call
+ */
+ public Status getStatus();
+
+ /**
+ * Gets the {@link PolicyDef} returned by the method if the status is OK.
+ *
+ * @return the <code>T</code> returned by the method if the status is OK.
+ */
+ public T getPolicyDef();
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.java
new file mode 100755
index 0000000..ea75497
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.java
@@ -0,0 +1,57 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+
+/**
+ * PolicyIdReference extends {@link com.att.research.xacmlatt.pdp.policy.PolicyIdReferenceBase} for
+ * {@link Policy} objects with an implementation of the <code>ensureReferencee</code>
+ * method to find a <code>Policy</code>.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class PolicyIdReference extends PolicyIdReferenceBase<Policy> {
+
+ public PolicyIdReference(PolicySet policySetParent, StatusCode statusCodeIn, String statusMessageIn) {
+ super(policySetParent, statusCodeIn, statusMessageIn);
+ }
+
+ public PolicyIdReference(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public PolicyIdReference(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public PolicyIdReference(PolicySet policySetParent) {
+ super(policySetParent);
+ }
+
+ public PolicyIdReference() {
+ }
+
+ @Override
+ protected Policy ensureReferencee(EvaluationContext evaluationContext) throws EvaluationException {
+ if (this.getReferencee() == null) {
+ PolicyFinderResult<Policy> policyFactoryResult = evaluationContext.getPolicy(this.getIdReferenceMatch());
+ if (policyFactoryResult.getStatus() == null || policyFactoryResult.getStatus().isOk()) {
+ this.setReferencee(policyFactoryResult.getPolicyDef());
+ }
+ }
+ return this.getReferencee();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.java
new file mode 100755
index 0000000..10961fc
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.java
@@ -0,0 +1,122 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.IdReferenceMatch;
+import com.att.research.xacml.api.StatusCode;
+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.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+
+/**
+ * PolicyIdReferenceBase extends {@link PolicySetChild} to implement a XACML PolicyIdReference element.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public abstract class PolicyIdReferenceBase<T extends PolicyDef> extends PolicySetChild {
+ private IdReferenceMatch idReferenceMatch;
+ private T referencee;
+
+ @Override
+ protected boolean validateComponent() {
+ if (super.validateComponent()) {
+ if (this.getIdReferenceMatch() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing reference id");
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * If the <code>T</code> referencee has not been set, this method will try and find it
+ * in the given <code>EvaluationContext</code> and return it.
+ *
+ * @param evaluationContext the <code>EvaluationContext</code> to search for the referencee
+ * @return the <code>T</code> referencee if found, else null
+ * @throws com.att.research.xacmlatt.pdp.eval.EvaluationException if there is an error attempting to locate the referenced <code>T</code>.
+ */
+ protected abstract T ensureReferencee(EvaluationContext evaluationContext) throws EvaluationException;
+
+ public PolicyIdReferenceBase(PolicySet policySetParent, StatusCode statusCodeIn, String statusMessageIn) {
+ super(policySetParent, statusCodeIn, statusMessageIn);
+ }
+
+ public PolicyIdReferenceBase(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public PolicyIdReferenceBase(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public PolicyIdReferenceBase(PolicySet policySetParent) {
+ super(policySetParent);
+ }
+
+ public PolicyIdReferenceBase() {
+ }
+
+ /**
+ * Gets the {@link com.att.research.xacml.api.IdReferenceMatch} for this <code>PolicyIdReferenceBase</code>.
+ *
+ * @return the <code>IdReferenceMatch</code> for this <code>PolicyIdReference</code>.
+ */
+ public IdReferenceMatch getIdReferenceMatch() {
+ return this.idReferenceMatch;
+ }
+
+ public void setIdReferenceMatch(IdReferenceMatch idReferenceMatchIn) {
+ this.idReferenceMatch = idReferenceMatchIn;
+ }
+
+ /**
+ * Sets the <code>PolicyDef</code> object referred to by this <code>PolicyIdReferenceBase</code>.
+ *
+ * @return the <code>PolicyDef</code> object referred to by this <code>PolicyIdReferenceBase</code>
+ */
+ public T getReferencee() {
+ return this.referencee;
+ }
+
+ public void setReferencee(T referenceeIn) {
+ this.referencee = referenceeIn;
+ }
+
+ @Override
+ public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException {
+ T thisReferencee = this.ensureReferencee(evaluationContext);
+ if (thisReferencee == null) {
+ return new EvaluationResult(Decision.INDETERMINATE, new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Could not find referencee for " + this.getIdReferenceMatch().toString()));
+ } else {
+ return thisReferencee.evaluate(evaluationContext);
+ }
+ }
+
+ @Override
+ public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException {
+ T thisReferencee = this.ensureReferencee(evaluationContext);
+ if (thisReferencee == null) {
+ return new MatchResult(MatchResult.MatchCode.INDETERMINATE, new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Could not find referencee for " + this.getIdReferenceMatch().toString()));
+ } else {
+ return thisReferencee.match(evaluationContext);
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.java
new file mode 100755
index 0000000..792d864
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.java
@@ -0,0 +1,111 @@
+/*
+ * 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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.Attribute;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatusCode;
+
+/**
+ * PolicyIssuer extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} to represent the XACML 3.0
+ * PolicyIssuer element in Policies and PolicySets.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class PolicyIssuer extends PolicyComponent {
+ private Node content;
+ private List<Attribute> attributes;
+
+ public PolicyIssuer(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public PolicyIssuer(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public PolicyIssuer() {
+ }
+
+ public Node getContent() {
+ return this.content;
+ }
+
+ public void setContent(Node nodeContent) {
+ this.content = nodeContent;
+ }
+
+ public Iterator<Attribute> getAttributes() {
+ return (this.attributes == null ? null : this.attributes.iterator());
+ }
+
+ public void setAttributes(Collection<Attribute> listAttributes) {
+ this.attributes = null;
+ if (listAttributes != null) {
+ this.add(listAttributes);
+ }
+ }
+
+ public void add(Attribute attribute) {
+ if (this.attributes == null) {
+ this.attributes = new ArrayList<Attribute>();
+ }
+ this.attributes.add(attribute);
+ }
+
+ public void add(Collection<Attribute> listAttributes) {
+ if (this.attributes == null) {
+ this.attributes = new ArrayList<Attribute>();
+ }
+ this.attributes.addAll(listAttributes);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ Object objectToDump;
+ if ((objectToDump = this.getContent()) != null) {
+ stringBuilder.append(",content=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ Iterator<Attribute> iterAttributes = this.getAttributes();
+ if (iterAttributes != null && iterAttributes.hasNext()) {
+ stringBuilder.append(",attributes=[");
+ stringBuilder.append(iterAttributes.next().toString());
+ while (iterAttributes.hasNext()) {
+ stringBuilder.append(',');
+ stringBuilder.append(iterAttributes.next().toString());
+ }
+ stringBuilder.append(']');
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySet.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySet.java
new file mode 100755
index 0000000..a4333be
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySet.java
@@ -0,0 +1,259 @@
+/*
+ * 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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Result;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.trace.Traceable;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.trace.StdTraceEvent;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+
+/**
+ * PolicySet extends {@link PolicyDef} to represent a XACML PolicySet element.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class PolicySet extends PolicyDef {
+ private TargetedCombinerParameterMap<Identifier,PolicySetChild> policyCombinerParameters = new TargetedCombinerParameterMap<Identifier,PolicySetChild>();
+ private List<PolicySetChild> children;
+ private List<CombiningElement<PolicySetChild>> combiningPolicies;
+ private CombiningAlgorithm<PolicySetChild> combiningAlgorithm;
+
+ private void ensureChildren() {
+ if (this.children == null) {
+ this.children = new ArrayList<PolicySetChild>();
+ }
+ }
+
+ /**
+ * Performs lazy evaluation of the combining parameters from this <code>Policy</code>.
+ *
+ * @return the <code>List</code> of <code>CombiningElement</code>s for all of the <code>Rule</code>s
+ */
+ protected List<CombiningElement<PolicySetChild>> getCombiningPolicies() {
+ if (this.combiningPolicies == null) {
+ this.combiningPolicies = new ArrayList<CombiningElement<PolicySetChild>>();
+ Iterator<PolicySetChild> iterPolicies = this.getChildren();
+ if (iterPolicies != null) {
+ while (iterPolicies.hasNext()) {
+ PolicySetChild policySetChild = iterPolicies.next();
+ this.combiningPolicies.add(new CombiningElement<PolicySetChild>(policySetChild, this.policyCombinerParameters.getCombinerParameters(policySetChild)));
+ }
+ }
+ }
+ return this.combiningPolicies;
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (super.validateComponent()) {
+ if (this.getPolicyCombiningAlgorithm() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing policy combining algorithm");
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ public PolicySet(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public PolicySet(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public PolicySet(PolicySet policySetParent) {
+ super(policySetParent);
+ }
+
+ public PolicySet() {
+ }
+
+ /**
+ * Gets an <code>Iterator</code> over the {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter}s
+ * for {@link Policy} elements in this
+ * <code>PolicySet</code>.
+ *
+ * @return an <code>Iterator</code> over the <code>TargetedCombinerParameter</code>s for <code>Policy</code> elements in this
+ * <code>PolicySet</code>.
+ */
+ public Iterator<TargetedCombinerParameter<Identifier,PolicySetChild>> getPolicyCombinerParameters() {
+ return this.policyCombinerParameters.getTargetedCombinerParameters();
+ }
+
+ /**
+ * Sets the Policy combiner parameters for this <code>PolicySet</code> from the contents of the given <code>Collection</code>
+ * of <code>TargetedCombinerParameter</code>s.
+ *
+ * @param policyCombinerParametersIn the <code>Collection</code> of <code>TargetedCombinerParameter</code>s.
+ */
+ public void setPolicyCombinerParameters(Collection<TargetedCombinerParameter<Identifier,PolicySetChild>> policyCombinerParametersIn) {
+ this.policyCombinerParameters.setCombinerParameters(policyCombinerParametersIn);
+ }
+
+ public void addPolicyCombinerParameter(TargetedCombinerParameter<Identifier,PolicySetChild> policyCombinerParameter) {
+ this.policyCombinerParameters.addCombinerParameter(policyCombinerParameter);
+ }
+
+ public void addPolicyCombinerParameters(Collection<TargetedCombinerParameter<Identifier,PolicySetChild>> policyCombinerParametersIn) {
+ this.policyCombinerParameters.addCombinerParameters(policyCombinerParametersIn);
+ }
+
+ /**
+ * Gets an <code>Iterator</code> over the <code>PolicySetChild</code> children of this <code>PolicySet</code>.
+ *
+ * @return an <code>Iterator</code> over the <code>PolicySetChild</code> children of this <code>PolicySet</code> or null if there are none.
+ */
+ public Iterator<PolicySetChild> getChildren() {
+ return (this.children == null ? null : this.children.iterator());
+ }
+
+ public void setChildren(Collection<PolicySetChild> policySetChildren) {
+ this.children = null;
+ if (policySetChildren != null) {
+ this.addChildren(policySetChildren);
+ }
+ }
+
+ public void addChild(PolicySetChild policySetChild) {
+ this.ensureChildren();
+ this.children.add(policySetChild);
+ }
+
+ public void addChildren(Collection<PolicySetChild> policySetChildren) {
+ this.ensureChildren();
+ this.children.addAll(policySetChildren);
+ }
+
+ /**
+ * Gets the {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm} for <code>PolicySetChild</code> children for this <code>PolicySet</code>.
+ *
+ * @return the <code>CombiningAlgorithm</code> for <code>PolicySetChild</code> children for this <code>PolicySet</code>.
+ */
+ public CombiningAlgorithm<PolicySetChild> getPolicyCombiningAlgorithm() {
+ return this.combiningAlgorithm;
+ }
+
+ public void setPolicyCombiningAlgorithm(CombiningAlgorithm<PolicySetChild> combiningAlgorithmIn) {
+ this.combiningAlgorithm = combiningAlgorithmIn;
+ }
+
+ @Override
+ public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException {
+ /*
+ * First check to see if we are valid. If not, return an error status immediately
+ */
+ if (evaluationContext.isTracing()) {
+ evaluationContext.trace(new StdTraceEvent<Object>("PolicySet", this, null));
+ }
+ if (!this.validate()) {
+ return new EvaluationResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+
+ /*
+ * See if we match
+ */
+ MatchResult thisMatchResult = this.match(evaluationContext);
+ assert(thisMatchResult != null);
+ if (evaluationContext.isTracing()) {
+ evaluationContext.trace(new StdTraceEvent<MatchResult>("Match", this, thisMatchResult));
+ }
+ switch(thisMatchResult.getMatchCode()) {
+ case INDETERMINATE:
+ return new EvaluationResult(Decision.INDETERMINATE, thisMatchResult.getStatus());
+ case MATCH:
+ break;
+ case NOMATCH:
+ return new EvaluationResult(Decision.NOTAPPLICABLE);
+ }
+
+ /*
+ * Get the combining elements
+ */
+ List<CombiningElement<PolicySetChild>> listCombiningElements = this.getCombiningPolicies();
+ assert(listCombiningElements != null);
+
+ /*
+ * Run the PolicyCombiningAlgorithm
+ */
+ assert(this.getPolicyCombiningAlgorithm() != null);
+ EvaluationResult evaluationResultCombined = this.getPolicyCombiningAlgorithm().combine(evaluationContext, listCombiningElements, getCombinerParameterList());
+ assert(evaluationResultCombined != null);
+
+ if (evaluationResultCombined.getDecision() == Decision.DENY || evaluationResultCombined.getDecision() == Decision.PERMIT) {
+ this.updateResult(evaluationResultCombined, evaluationContext);
+
+ /*
+ * Add my id to the policy set identifiers
+ */
+ if (evaluationContext.getRequest().getReturnPolicyIdList()) {
+ evaluationResultCombined.addPolicySetIdentifier(this.getIdReference());
+ }
+ }
+ if (evaluationContext.isTracing()) {
+ evaluationContext.trace(new StdTraceEvent<Result>("Result", this, evaluationResultCombined));
+ }
+ return evaluationResultCombined;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ String iteratorToDump;
+ if ((iteratorToDump = StringUtils.toString(this.getPolicyCombinerParameters())) != null) {
+ stringBuilder.append(",policyCombinerParameters=");
+ stringBuilder.append(iteratorToDump);
+ }
+ if ((iteratorToDump = StringUtils.toString(this.getChildren())) != null) {
+ stringBuilder.append(",children=");
+ stringBuilder.append(iteratorToDump);
+ }
+ Object objectToDump;
+ if ((objectToDump = this.getPolicyCombiningAlgorithm()) != null) {
+ stringBuilder.append(",policyCombiningAlgorithm=");
+ stringBuilder.append(objectToDump.toString());
+ }
+
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+ @Override
+ public String getTraceId() {
+ return this.getIdentifier().stringValue();
+ }
+
+ @Override
+ public Traceable getCause() {
+ return null;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetChild.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetChild.java
new file mode 100755
index 0000000..eeae452
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetChild.java
@@ -0,0 +1,149 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.trace.Traceable;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacmlatt.pdp.eval.Evaluatable;
+import com.att.research.xacmlatt.pdp.eval.Matchable;
+
+/**
+ * PolicySetChild extends {@link com.att.research.xacmlatt.pdp.PolicyComponent} to represent XACML 3.0 Policies, PolicySets, PolicyReferences,
+ * and PolicySetReferences.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public abstract class PolicySetChild extends PolicyComponent implements Evaluatable, Matchable, Traceable {
+ private Identifier identifier;
+ private PolicyDefaults policyDefaults;
+ private PolicySet parent;
+
+ /**
+ * Creates a new <code>PolicySetChild</code> with the given given {@link com.att.research.xacml.api.StatusCode}
+ * and <code>String</code> status message.
+ *
+ * @param statusCodeIn the <code>StatusCode</code> for the new <code>PolicySetChild</code>
+ * @param statusMessageIn the <code>String</code> status message for the new <code>PolicySetChild</code>
+ */
+ protected PolicySetChild(PolicySet parentIn, StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ this.parent = parentIn;
+ }
+
+ protected PolicySetChild(StatusCode statusCodeIn, String statusMessageIn) {
+ this(null, statusCodeIn, statusMessageIn);
+ }
+
+ /**
+ * Creates a new <code>PolicySetChild</code> with the default OK <code>StatusCode</code>.
+ *
+ * @param statusCodeIn the <code>StatusCode</code> for this <code>PolicySetChild</code>
+ */
+ protected PolicySetChild(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ protected PolicySetChild(PolicySet parentIn) {
+ this.parent = parentIn;
+ }
+
+ /**
+ * Creates a new <code>PolicySetChild</code> with the default OK status.
+ */
+ protected PolicySetChild() {
+ super();
+ }
+
+ /**
+ * Gets the <code>Identifier</code> for this <code>PolicySetChild</code>.
+ *
+ * @return the <code>Identifier</code> for this <code>PolicySetChild</code>
+ */
+ public Identifier getIdentifier() {
+ return this.identifier;
+ }
+
+ public void setIdentifier(Identifier identifierIn) {
+ this.identifier = identifierIn;
+ }
+
+ /**
+ * Gets the <code>PolicyDefaults</code> for this <code>PolicySetChild</code>.
+ *
+ * @return the <code>PolicyDefaults</code> for this <code>PolicySetChild</code>
+ */
+ public PolicyDefaults getPolicyDefaults() {
+ return this.policyDefaults;
+ }
+
+ /**
+ * Sets the <code>PolicyDefaults</code> for this <code>PolicySetChild</code>.
+ *
+ * @param policyDefaultsIn the <code>PolicyDefaults</code> for this <code>PolicySetChild</code>
+ */
+ public void setPolicyDefaults(PolicyDefaults policyDefaultsIn) {
+ this.policyDefaults = policyDefaultsIn;
+ }
+
+ /**
+ * Gets the parent {@link PolicySet} containing this <code>PolicySetChild</code>
+ * or null if this is the root.
+ *
+ * @return the parent <code>PolicySet</code> of this <code>PolicySetChild</code>
+ */
+ public PolicySet getParent() {
+ return this.parent;
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (this.getIdentifier() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing identifier");
+ return false;
+ } else {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+ }
+
+ @Override
+ public String getTraceId() {
+ return this.getIdentifier().stringValue();
+ }
+
+ @Override
+ public Traceable getCause() {
+ return this.parent;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ Object objectToDump;
+ if ((objectToDump = this.getIdentifier()) != null) {
+ stringBuilder.append(",identifier=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ if ((objectToDump = this.getPolicyDefaults()) != null) {
+ stringBuilder.append(",policyDefaults=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.java
new file mode 100755
index 0000000..adb96a9
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.java
@@ -0,0 +1,57 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+
+/**
+ * PolicySetIdReference extends {@link com.att.research.xacmlatt.pdp.policy.PolicyIdReferenceBase} for
+ * {@link com.att.research.xacmlatt.pdp.PolicySet} objects to implement the <code>ensureReferencee</code>
+ * method to find <code>PolicySet</code>s.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class PolicySetIdReference extends PolicyIdReferenceBase<PolicySet> {
+
+ public PolicySetIdReference(PolicySet policySetParent, StatusCode statusCodeIn, String statusMessageIn) {
+ super(policySetParent, statusCodeIn, statusMessageIn);
+ }
+
+ public PolicySetIdReference(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public PolicySetIdReference(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public PolicySetIdReference(PolicySet policySetParent) {
+ super(policySetParent);
+ }
+
+ public PolicySetIdReference() {
+ }
+
+ @Override
+ protected PolicySet ensureReferencee(EvaluationContext evaluationContext) throws EvaluationException {
+ if (this.getReferencee() == null) {
+ PolicyFinderResult<PolicySet> policyFactoryResult = evaluationContext.getPolicySet(this.getIdReferenceMatch());
+ if (policyFactoryResult.getStatus() == null || policyFactoryResult.getStatus().isOk()) {
+ this.setReferencee(policyFactoryResult.getPolicyDef());
+ }
+ }
+ return this.getReferencee();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Rule.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Rule.java
new file mode 100755
index 0000000..467255b
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Rule.java
@@ -0,0 +1,299 @@
+/*
+ * 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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Advice;
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Obligation;
+import com.att.research.xacml.api.Result;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.trace.Traceable;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.trace.StdTraceEvent;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.Evaluatable;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+import com.att.research.xacmlatt.pdp.eval.Matchable;
+
+/**
+ * Rule extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} to represent a XACML Rule within a Policy. It implements
+ * {@link com.att.research.xacmlatt.pdp.eval.Matchable} and {@link com.att.research.xacmlatt.pdp.eval.Evaluatable} for matching and evaluation
+ * a request.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class Rule extends PolicyComponent implements Matchable, Evaluatable, Traceable {
+ private Policy policy;
+ private String ruleId;
+ private RuleEffect ruleEffect;
+ private String description;
+ private Target target;
+ private Condition condition;
+ private List<ObligationExpression> obligationExpressions = new ArrayList<ObligationExpression>();
+ private List<AdviceExpression> adviceExpressions = new ArrayList<AdviceExpression>();
+
+ protected List<ObligationExpression> getObligationExpressionList() {
+ return this.obligationExpressions;
+ }
+
+ protected void clearObligationExpressions() {
+ this.getObligationExpressionList().clear();
+ }
+
+ protected List<AdviceExpression> getAdviceExpressionList() {
+ return this.adviceExpressions;
+ }
+
+ protected void clearAdviceExpressions() {
+ this.getAdviceExpressionList().clear();
+ }
+
+ public Rule(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public Rule(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public Rule() {
+ }
+
+ public Policy getPolicy() {
+ return this.policy;
+ }
+
+ public void setPolicy(Policy policyIn) {
+ this.policy = policyIn;
+ }
+
+ public String getRuleId() {
+ return this.ruleId;
+ }
+
+ public void setRuleId(String ruleIdIn) {
+ this.ruleId = ruleIdIn;
+ }
+
+ public RuleEffect getRuleEffect() {
+ return this.ruleEffect;
+ }
+
+ public void setRuleEffect(RuleEffect ruleEffectIn) {
+ this.ruleEffect = ruleEffectIn;
+ }
+
+ public String getDescription() {
+ return this.description;
+ }
+
+ public void setDescription(String descriptionIn) {
+ this.description = descriptionIn;
+ }
+
+ public Target getTarget() {
+ return this.target;
+ }
+
+ public void setTarget(Target targetIn) {
+ this.target = targetIn;
+ }
+
+ public Condition getCondition() {
+ return this.condition;
+ }
+
+ public void setCondition(Condition conditionIn) {
+ this.condition = conditionIn;
+ }
+
+ public Iterator<ObligationExpression> getObligationExpressions() {
+ return (this.obligationExpressions == null ? null : this.obligationExpressions.iterator());
+ }
+
+ public void setObligationExpressions(Collection<ObligationExpression> obligationExpressionsIn) {
+ this.clearObligationExpressions();
+ if (obligationExpressionsIn != null) {
+ this.addObligationExpressions(obligationExpressionsIn);
+ }
+ }
+
+ public void addObligationExpression(ObligationExpression obligationExpression) {
+ this.getObligationExpressionList().add(obligationExpression);
+ }
+
+ public void addObligationExpressions(Collection<ObligationExpression> obligationExpressionsIn) {
+ this.getObligationExpressionList().addAll(obligationExpressionsIn);
+ }
+
+ public Iterator<AdviceExpression> getAdviceExpressions() {
+ return (this.adviceExpressions == null ? null : this.adviceExpressions.iterator());
+ }
+
+ public void setAdviceExpressions(Collection<AdviceExpression> adviceExpressionsIn) {
+ this.clearAdviceExpressions();
+ if (adviceExpressionsIn != null) {
+ this.addAdviceExpressions(adviceExpressionsIn);
+ }
+ }
+
+ public void addAdviceExpression(AdviceExpression adviceExpression) {
+ this.getAdviceExpressionList().add(adviceExpression);
+ }
+
+ public void addAdviceExpressions(Collection<AdviceExpression> adviceExpressionsIn) {
+ this.getAdviceExpressionList().addAll(adviceExpressionsIn);
+ }
+
+ @Override
+ public EvaluationResult evaluate(EvaluationContext evaluationContext) throws EvaluationException {
+ if (!this.validate()) {
+ return new EvaluationResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+
+ /*
+ * See if our target matches
+ */
+ MatchResult matchResult = this.match(evaluationContext);
+ if (evaluationContext.isTracing()) {
+ evaluationContext.trace(new StdTraceEvent<MatchResult>("Match", this, matchResult));
+ }
+ switch(matchResult.getMatchCode()) {
+ case INDETERMINATE:
+ return new EvaluationResult(Decision.INDETERMINATE, matchResult.getStatus());
+ case MATCH:
+ break;
+ case NOMATCH:
+ return new EvaluationResult(Decision.NOTAPPLICABLE);
+ }
+
+ /*
+ * See if our condition matches
+ */
+ Condition thisCondition = this.getCondition();
+ if (thisCondition != null) {
+ ExpressionResultBoolean expressionResultCondition = thisCondition.evaluate(evaluationContext, this.getPolicy().getPolicyDefaults());
+ assert(expressionResultCondition != null);
+
+ if (evaluationContext.isTracing()) {
+ evaluationContext.trace(new StdTraceEvent<ExpressionResultBoolean>("Condition", this, expressionResultCondition));
+ }
+
+ if (!expressionResultCondition.isOk()) {
+ return new EvaluationResult(Decision.INDETERMINATE, expressionResultCondition.getStatus());
+ } else if (!expressionResultCondition.isTrue()) {
+ return new EvaluationResult(Decision.NOTAPPLICABLE);
+ }
+ }
+
+ /*
+ * The target and condition match, so we can start creating the EvaluationResult
+ */
+ List<Obligation> listObligations = ObligationExpression.evaluate(evaluationContext, this.getPolicy().getPolicyDefaults(), this.getRuleEffect().getDecision(), this.getObligationExpressionList());
+ List<Advice> listAdvices = AdviceExpression.evaluate(evaluationContext, this.getPolicy().getPolicyDefaults(), this.getRuleEffect().getDecision(), this.getAdviceExpressionList());
+
+ EvaluationResult evaluationResult = new EvaluationResult(this.getRuleEffect().getDecision(), listObligations, listAdvices);
+ if (evaluationContext.isTracing()) {
+ evaluationContext.trace(new StdTraceEvent<Result>("Result", this, evaluationResult));
+ }
+ return evaluationResult;
+ }
+
+ @Override
+ public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException {
+ if (!this.validate()) {
+ return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+ Target thisTarget = this.getTarget();
+ if (thisTarget != null) {
+ return thisTarget.match(evaluationContext);
+ } else {
+ return MatchResult.MM_MATCH;
+ }
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (this.getRuleId() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing rule id");
+ return false;
+ } else if (this.getPolicy() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Rule not in a Policy");
+ return false;
+ } else if (this.getRuleEffect() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing effect");
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer stringBuffer = new StringBuffer("{");
+ stringBuffer.append("super=");
+ stringBuffer.append(super.toString());
+
+ Object objectToDump;
+ if ((objectToDump = this.getRuleId()) != null) {
+ stringBuffer.append(",ruleId=");
+ stringBuffer.append((String)objectToDump);
+ }
+ if ((objectToDump = this.getRuleEffect()) != null) {
+ stringBuffer.append(",ruleEffect=");
+ stringBuffer.append(objectToDump.toString());
+ }
+ if ((objectToDump = this.getDescription()) != null) {
+ stringBuffer.append(",description=");
+ stringBuffer.append((String)objectToDump);
+ }
+ if ((objectToDump = this.getTarget()) != null) {
+ stringBuffer.append(",target=");
+ stringBuffer.append(objectToDump.toString());
+ }
+ if ((objectToDump = this.getCondition()) != null) {
+ stringBuffer.append(",condition=");
+ stringBuffer.append(objectToDump.toString());
+ }
+
+ String iterToDump;
+ if ((iterToDump = StringUtils.toString(this.getObligationExpressions())) != null) {
+ stringBuffer.append(",obligationExpressions=");
+ stringBuffer.append(iterToDump);
+ }
+ if ((iterToDump = StringUtils.toString(this.getAdviceExpressions())) != null) {
+ stringBuffer.append(",adviceExpressions=");
+ stringBuffer.append(iterToDump);
+ }
+ stringBuffer.append('}');
+ return stringBuffer.toString();
+ }
+
+ @Override
+ public String getTraceId() {
+ return this.getRuleId();
+ }
+
+ @Override
+ public Traceable getCause() {
+ return this.policy;
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/RuleEffect.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/RuleEffect.java
new file mode 100755
index 0000000..bdf95e3
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/RuleEffect.java
@@ -0,0 +1,61 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.Decision;
+
+/**
+ * RuleEffect is an enumeration of the XACML decision effects that a {@link Rule} may apply
+ * to.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public enum RuleEffect {
+ DENY("Deny", Decision.DENY),
+ PERMIT("Permit", Decision.PERMIT)
+ ;
+
+ private String name;
+ private Decision decision;
+ private RuleEffect(String nameIn, Decision decisionIn) {
+ this.name = nameIn;
+ this.decision = decisionIn;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public Decision getDecision() {
+ return this.decision;
+ }
+
+ @Override
+ public String toString() {
+ return this.getName();
+ }
+
+ /**
+ * Maps a XACML rule effect <code>String</code> name to the matching <code>RuleEffect</code>.
+ *
+ * @param effectName the <code>String</code> effect name to match
+ * @return the matching <code>RuleEffect</code> or null if there is no match
+ */
+ public static RuleEffect getRuleEffect(String effectName) {
+ for (RuleEffect ruleEffect: RuleEffect.values()) {
+ if (ruleEffect.getName().equalsIgnoreCase(effectName)) {
+ return ruleEffect;
+ }
+ }
+ return null;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Target.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Target.java
new file mode 100755
index 0000000..b4eac6c
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Target.java
@@ -0,0 +1,138 @@
+/*
+ * 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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+import com.att.research.xacmlatt.pdp.eval.Matchable;
+
+/**
+ * Target extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} to implement XACML 3.0 Target elements for
+ * Policies, PolicySets, and Rules.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class Target extends PolicyComponent implements Matchable {
+ private List<AnyOf> anyOfs;
+
+ protected List<AnyOf> getAnyOfList(boolean bNoNull) {
+ if (this.anyOfs == null && bNoNull) {
+ this.anyOfs = new ArrayList<AnyOf>();
+ }
+ return this.anyOfs;
+ }
+
+ protected void clearAnyOfList() {
+ if (this.anyOfs != null) {
+ this.anyOfs.clear();
+ }
+ }
+
+ public Target(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public Target(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public Target() {
+ }
+
+ public Target(Collection<AnyOf> anyOfsIn) {
+ if (anyOfsIn != null) {
+ this.addAnyOfs(anyOfsIn);
+ }
+ }
+
+ public Target(AnyOf anyOfIn) {
+ if (anyOfIn != null) {
+ this.addAnyOf(anyOfIn);
+ }
+ }
+
+ /**
+ * Gets an <code>Iterator</code> over all of the {@link AnyOf}s in this <code>Target</code>.
+ *
+ * @return an <code>Iterator</code> over all of the <code>AnyOf</code>s in this <code>Target</code> or null if there are none
+ */
+ public Iterator<AnyOf> getAnyOfs() {
+ return (this.anyOfs == null ? null : this.anyOfs.iterator());
+ }
+
+ public void setAnyOfs(Collection<AnyOf> anyOfsIn) {
+ this.clearAnyOfList();
+ if (anyOfsIn != null) {
+ this.addAnyOfs(anyOfsIn);
+ }
+ }
+
+ public void addAnyOf(AnyOf anyOfIn) {
+ List<AnyOf> listAnyOfs = this.getAnyOfList(true);
+ listAnyOfs.add(anyOfIn);
+ }
+
+ public void addAnyOfs(Collection<AnyOf> anyOfsIn) {
+ List<AnyOf> listAnyOfs = this.getAnyOfList(true);
+ listAnyOfs.addAll(anyOfsIn);
+ }
+
+ @Override
+ public MatchResult match(EvaluationContext evaluationContext) throws EvaluationException {
+ if (!this.validate()) {
+ return new MatchResult(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+ Iterator<AnyOf> iterAnyOfs = this.getAnyOfs();
+ if (iterAnyOfs == null || !iterAnyOfs.hasNext()) {
+ return MatchResult.MM_MATCH;
+ } else {
+ MatchResult matchResult = MatchResult.MM_MATCH;
+ while (iterAnyOfs.hasNext()) {
+ matchResult = iterAnyOfs.next().match(evaluationContext);
+ if (matchResult.getMatchCode() != MatchResult.MatchCode.MATCH) {
+ return matchResult;
+ }
+ }
+ return matchResult;
+ }
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ String iterToDump = StringUtils.toString(this.getAnyOfs());
+ if (iterToDump != null) {
+ stringBuilder.append(",anyOfs=");
+ stringBuilder.append(iterToDump);
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.java
new file mode 100755
index 0000000..f93b520
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.java
@@ -0,0 +1,107 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.StatusCode;
+
+/**
+ * TargetedCombinerParameter extends {@link CombinerParameter} to include a lazy
+ * reference to a particular sub-element within the evaluatable children that should be used when combining evaluation
+ * results from that sub-element.
+ *
+ * @author car
+ *
+ * @param <T> the type of the identifier used to reference the targeted object
+ * @param <U> the type of the targeted object
+ */
+public class TargetedCombinerParameter<T, U> extends CombinerParameter {
+ private T targetId;
+ private U target;
+
+ public TargetedCombinerParameter(T targetIdIn, String nameIn, AttributeValue<?> attributeValueIn, StatusCode statusCodeIn, String statusMessageIn) {
+ super(nameIn, attributeValueIn, statusCodeIn, statusMessageIn);
+ this.targetId = targetIdIn;
+ }
+
+ public TargetedCombinerParameter(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public TargetedCombinerParameter(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public TargetedCombinerParameter(T targetIdIn, String nameIn, AttributeValue<?> attributeValueIn) {
+ super(nameIn, attributeValueIn);
+ this.targetId = targetIdIn;
+ }
+
+ public TargetedCombinerParameter() {
+
+ }
+
+ /**
+ * Gets the target id of this <code>TargetedCombinerParameter</code>.
+ *
+ * @return the <code>T</code> id of this <code>TargetedCombinerParameter</code>
+ */
+ public T getTargetId() {
+ return this.targetId;
+ }
+
+ /**
+ * Sets the target id to the given <code>T</code> value.
+ *
+ * @param targetIdIn the <code>T</code> to set as the target id
+ */
+ public void setTargetId(T targetIdIn) {
+ this.targetId = targetIdIn;
+ }
+
+ /**
+ * Gets the target for this <code>TargetedCombinerParameter</code>.
+ *
+ * @return the <code>U</code> target for this <code>TargetedCombinerParameter</code>
+ */
+ public U getTarget() {
+ return this.target;
+ }
+
+ /**
+ * Sets the target for this <code>TargetedCombinerParameter</code> to the given <code>U</code>.
+ *
+ * @param targetIn the <code>U</code> target for this <code>TargetedCombinerParameter</code>
+ */
+ public void setTarget(U targetIn) {
+ this.target = targetIn;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ Object objectToDump;
+ if ((objectToDump = this.getTargetId()) != null) {
+ stringBuilder.append("targetId=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ if ((objectToDump = this.getTarget()) != null) {
+ stringBuilder.append("target=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.java
new file mode 100755
index 0000000..1ffa5c0
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.java
@@ -0,0 +1,155 @@
+/*
+ * 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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * TargetedCombinerParameterMap is a utility for maintaining a collection of {@link com.att.research.xacmlatt.policy.TargetedCombinerParameter}
+ * objects with the mappings to their targets.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ *
+ * @param <T> the type of the identifier for the <code>TargetedCombinerParameter</code>s in the map
+ * @param <U> the type of the object referenced by the identifier
+ */
+public class TargetedCombinerParameterMap<T, U> {
+ List<TargetedCombinerParameter<T,U>> targetedCombinerParameters = null;
+ Map<T,U> mapTargetIdToTarget = new HashMap<T,U>();
+ Map<U,List<CombinerParameter>> mapTargetToCombinerParameters = null;
+
+ private void ensureTargetedCombinerParameters() {
+ if (this.targetedCombinerParameters == null) {
+ this.targetedCombinerParameters = new ArrayList<TargetedCombinerParameter<T,U>>();
+ }
+ }
+
+ /**
+ * Gets the target from the given <code>TargetedCombinerParameter</code> if present. If not, find the
+ * target in the target id to target mapping, update the <code>TargetedCombinerParameter</code> and then
+ * return the target.
+ *
+ * @param targetedCombinerParameter the <code>TargetedCombinerParameter</code> to resolve
+ * @return the target for the given <code>TargetedCombinerParameter</code>
+ */
+ protected U resolve(TargetedCombinerParameter<T,U> targetedCombinerParameter) {
+ U result;
+ if ((result = targetedCombinerParameter.getTarget()) != null) {
+ return result;
+ } else if ((result = this.mapTargetIdToTarget.get(targetedCombinerParameter.getTargetId())) != null) {
+ targetedCombinerParameter.setTarget(result);
+ return result;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Ensures the <code>Map</code> from targets to <code>List</code> of <code>CombinerParameter</code>s has been
+ * created if needed.
+ *
+ * @throws IllegalStateException if there are <code>TargetedCombinerParameter</code>s that cannot be resolved
+ */
+ protected void ensureMap() throws IllegalStateException {
+ if (this.mapTargetToCombinerParameters == null) {
+ if (this.targetedCombinerParameters != null && this.targetedCombinerParameters.size() > 0) {
+ this.mapTargetToCombinerParameters = new HashMap<U,List<CombinerParameter>>();
+ for (TargetedCombinerParameter<T,U> targetedCombinerParameter: this.targetedCombinerParameters) {
+ U target = this.resolve(targetedCombinerParameter);
+ if (target == null) {
+ throw new IllegalStateException("Unresolved TargetCombinerParameter \"" + targetedCombinerParameter.toString() + "\"");
+ }
+ List<CombinerParameter> listCombinerParameters = this.mapTargetToCombinerParameters.get(target);
+ if (listCombinerParameters == null) {
+ listCombinerParameters = new ArrayList<CombinerParameter>();
+ this.mapTargetToCombinerParameters.put(target, listCombinerParameters);
+ }
+ listCombinerParameters.add(targetedCombinerParameter);
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates a new <code>TargetedCombinerParameterMap</code>.
+ */
+ public TargetedCombinerParameterMap() {
+ }
+
+ /**
+ * Adds a new target object to the identifier map.
+ *
+ * @param targetId the id for the target
+ * @param target the target
+ */
+ public void addTarget(T targetId, U target) {
+ this.mapTargetIdToTarget.put(targetId, target);
+ }
+
+ /**
+ * Adds a new <code>TargetedCombinerParameter</code> to this <code>TargetedCombinerParameterMap</code>.
+ *
+ * @param targetdCombinerParameter the <code>TargetedCombinerParameter</code> to add
+ */
+ public void addCombinerParameter(TargetedCombinerParameter<T,U> targetdCombinerParameter) {
+ this.ensureTargetedCombinerParameters();
+ this.targetedCombinerParameters.add(targetdCombinerParameter);
+ this.mapTargetToCombinerParameters = null;
+ }
+
+ /**
+ * Adds the contents of the given <code>Collection</code> of <code>TargetedCombinerParameter</code>s to this <code>TargetedCombinerParameterMap</code>.
+ *
+ * @param listTargetedCombinerParameters the <code>Collection</code> of <code>TargetedCombinerParameter</code>s to add
+ */
+ public void addCombinerParameters(Collection<TargetedCombinerParameter<T,U>> listTargetedCombinerParameters) {
+ this.ensureTargetedCombinerParameters();
+ this.targetedCombinerParameters.addAll(listTargetedCombinerParameters);
+ this.mapTargetToCombinerParameters = null;
+ }
+
+ /**
+ * Sets the set of <code>TargetedCombinerParameter</code>s for this <code>TargetedCombinerParameterMap</code> to the contents of the
+ * given <code>Collection</code>>
+ *
+ * @param listTargetedCombinerParameters the <code>Collection</code> of <code>TargetedCombinerParameter</code>s to set
+ */
+ public void setCombinerParameters(Collection<TargetedCombinerParameter<T,U>> listTargetedCombinerParameters) {
+ this.targetedCombinerParameters = null;
+ if (listTargetedCombinerParameters != null) {
+ this.addCombinerParameters(targetedCombinerParameters);
+ }
+ }
+
+ /**
+ * Looks up the given target in the map for any {@link CombinerParameter}s for the
+ * given target.
+ *
+ * @param target the target
+ * @return a <code>List</code> of <code>CombinerParameter</code>s for the target or null if none
+ * @throws IllegalStateException if there are <code>TargetedCombinerParameter</code>s that cannot be resolved
+ */
+ public List<CombinerParameter> getCombinerParameters(U target) throws IllegalStateException {
+ this.ensureMap();
+ return (this.mapTargetToCombinerParameters == null ? null : this.mapTargetToCombinerParameters.get(target));
+ }
+
+ public Iterator<TargetedCombinerParameter<T,U>> getTargetedCombinerParameters() {
+ return (this.targetedCombinerParameters == null ? null : this.targetedCombinerParameters.iterator());
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableDefinition.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableDefinition.java
new file mode 100755
index 0000000..017dd12
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableDefinition.java
@@ -0,0 +1,106 @@
+/*
+ * 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.policy;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatusCode;
+
+/**
+ * VariableDefinition extends {@link PolicyComponent} to represent a XACML VariableDefinition element.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class VariableDefinition extends PolicyComponent {
+ private String id;
+ private Expression expression;
+
+ public VariableDefinition(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public VariableDefinition(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public VariableDefinition() {
+ super();
+ }
+
+ /**
+ * Gets the id of the variable for this <code>VariableDefinition</code>.
+ *
+ * @return the <code>String</code> id for the variable for this <code>VariableDefinition</code>.
+ */
+ public String getId() {
+ return this.id;
+ }
+
+ /**
+ * Sets the id of the variable for this <code>VariableDefinition</code>.
+ *
+ * @param idIn the <code>String</code> id for the variable for this <code>VariableDefinition</code>.
+ */
+ public void setId(String idIn) {
+ this.id = idIn;
+ }
+
+ /**
+ * Gets the {@link Expression} for this <code>VariableDefinition</code>.
+ *
+ * @return the <code>Expression</code> for this <code>VariableDefinition</code>.
+ */
+ public Expression getExpression() {
+ return this.expression;
+ }
+
+ /**
+ * Sets the <code>Expression</code> for this <code>VariableDefinition</code>.
+ *
+ * @param expressionIn the <code>Expression</code> for this <code>VariableDefinition</code>
+ */
+ public void setExpression(Expression expressionIn) {
+ this.expression = expressionIn;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ Object objectToDump;
+ if ((objectToDump = this.getId()) != null) {
+ stringBuilder.append(",id=");
+ stringBuilder.append((String)objectToDump);
+ }
+ if ((objectToDump = this.getExpression()) != null) {
+ stringBuilder.append(",expression=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (this.getId() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing variable id");
+ return false;
+ } else if (this.getExpression() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing variable expression");
+ return false;
+ } else {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableMap.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableMap.java
new file mode 100755
index 0000000..4d55a9d
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableMap.java
@@ -0,0 +1,116 @@
+/*
+ * 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.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import com.att.research.xacml.util.StringUtils;
+
+/**
+ * VariableMap is a collection of {@link com.att.research.xacmlatt.pdp.policy.VariableDefinition}s that are accessible by
+ * the variable identifier.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class VariableMap {
+ private List<VariableDefinition> variableDefinitions;
+ private Map<String, VariableDefinition> mapVariableDefinitions;
+
+ private void ensureVariableDefinitions() {
+ if (this.variableDefinitions == null) {
+ this.variableDefinitions = new ArrayList<VariableDefinition>();
+ }
+ }
+
+ private void ensureMap() {
+ if (this.mapVariableDefinitions == null) {
+ this.mapVariableDefinitions = new HashMap<String, VariableDefinition>();
+ }
+ }
+
+ public VariableMap() {
+ }
+
+ /**
+ * Gets the <code>VariableDefinition</code> with the given <code>String</code> id.
+ *
+ * @param variableId the <code>String</code> identifier of the <code>VariableDefinition</code> to retrieve
+ * @return the <code>VariableDefinition</code> with the given <code>String</code> id or null if not found.
+ */
+ public VariableDefinition getVariableDefinition(String variableId) {
+ return (this.mapVariableDefinitions == null ? null : this.mapVariableDefinitions.get(variableId));
+ }
+
+ /**
+ * Gets an <code>Iterator</code> over the <code>VariableDefinition</code>s in this <code>VariableMap</code>
+ * in the order they were added.
+ *
+ * @return an <code>Iterator</code> over the <code>VariableDefinition</code>s in this <code>VariableMap</code>
+ */
+ public Iterator<VariableDefinition> getVariableDefinitions() {
+ return (this.variableDefinitions == null ? null : this.variableDefinitions.iterator());
+ }
+
+ /**
+ * Adds the given <code>VariableDefinition</code> to this <code>VariableMap</code>.
+ *
+ * @param variableDefinition the <code>VariableDefinition</code> to add
+ */
+ public void add(VariableDefinition variableDefinition) {
+ this.ensureMap();
+ this.ensureVariableDefinitions();
+ this.variableDefinitions.add(variableDefinition);
+ this.mapVariableDefinitions.put(variableDefinition.getId(), variableDefinition);
+ }
+
+ /**
+ * Adds the contents of the given <code>Collection</code> of <code>VariableDefinition</code>s to the set of
+ * <code>VariableDefinition</code>s in this <code>VariableMap</code>>
+ *
+ * @param listVariableDefinitions the <code>Collection</code> of <code>VariableDefinition</code>s to add
+ */
+ public void addVariableDefinitions(Collection<VariableDefinition> listVariableDefinitions) {
+ for (VariableDefinition variableDefinition: listVariableDefinitions) {
+ this.add(variableDefinition);
+ }
+ }
+
+ /**
+ * Sets the <code>VariableDefinition</code>s in this <code>VariableMap</code> to the contents of the given
+ * <code>Collection</code>.
+ *
+ * @param listVariableDefinitions the <code>Collection</code> of <code>VariableDefinition</code> to set
+ */
+ public void setVariableDefinitions(Collection<VariableDefinition> listVariableDefinitions) {
+ this.variableDefinitions = null;
+ this.mapVariableDefinitions = null;
+ if (listVariableDefinitions != null) {
+ this.addVariableDefinitions(variableDefinitions);
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+ if (this.mapVariableDefinitions.size() > 0) {
+ stringBuilder.append("variableDefinitions=");
+ stringBuilder.append(StringUtils.toString(this.mapVariableDefinitions.values().iterator()));
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.java
new file mode 100755
index 0000000..eda3962
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.java
@@ -0,0 +1,191 @@
+/*
+ * 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.policy.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.AdviceExpression;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.RuleEffect;
+
+/**
+ * DOMAdviceExpression extends {@link com.att.research.xacmlatt.pdp.policy.AdviceExpression} with methods for creation
+ * from {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMAdviceExpression extends AdviceExpression {
+ private static final Log logger = LogFactory.getLog(DOMAdviceExpression.class);
+
+ protected DOMAdviceExpression() {
+ }
+
+ /**
+ * Creates a new <code>AdviceExpression</code> by parsing the given <code>Node</code> representing a XACML AdviceExpression element.
+ *
+ * @param nodeAdviceExpression the <code>Node</code> representing the XACML AdviceExpression element
+ * @param policy the {@link com.att.research.xacmlatt.pdp.policy.Policy} encompassing the AdviceExpression element
+ * @return a new <code>AdviceExpression</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static AdviceExpression newInstance(Node nodeAdviceExpression, Policy policy) throws DOMStructureException {
+ Element elementAdviceExpression = DOMUtil.getElement(nodeAdviceExpression);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMAdviceExpression domAdviceExpression = new DOMAdviceExpression();
+
+ try {
+ NodeList children = elementAdviceExpression.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEASSIGNMENTEXPRESSION.equals(child.getLocalName())) {
+ domAdviceExpression.addAttributeAssignmentExpression(DOMAttributeAssignmentExpression.newInstance(child, policy));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeAdviceExpression);
+ }
+ }
+ }
+ }
+
+ domAdviceExpression.setAdviceId(DOMUtil.getIdentifierAttribute(elementAdviceExpression, XACML3.ATTRIBUTE_ADVICEID, !bLenient));
+
+ String string = DOMUtil.getStringAttribute(elementAdviceExpression, XACML3.ATTRIBUTE_APPLIESTO, !bLenient);
+ RuleEffect ruleEffect = RuleEffect.getRuleEffect(string);
+ if (ruleEffect == null && !bLenient) {
+ throw new DOMStructureException(nodeAdviceExpression, "Unknown EffectType \"" + string + "\"");
+ } else {
+ domAdviceExpression.setAppliesTo(ruleEffect);
+ }
+ } catch (DOMStructureException ex) {
+ domAdviceExpression.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+
+ return domAdviceExpression;
+ }
+
+ public static boolean repair(Node nodeAdviceExpression) throws DOMStructureException {
+ Element elementAdviceExpression = DOMUtil.getElement(nodeAdviceExpression);
+ boolean result = false;
+
+ NodeList children = elementAdviceExpression.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEASSIGNMENTEXPRESSION.equals(child.getLocalName())) {
+ result = DOMAttributeAssignmentExpression.repair(child) || result;
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ nodeAdviceExpression.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+
+ result = DOMUtil.repairIdentifierAttribute(elementAdviceExpression, XACML3.ATTRIBUTE_ADVICEID, logger) || result;
+ result = DOMUtil.repairStringAttribute(elementAdviceExpression, XACML3.ATTRIBUTE_APPLIESTO, RuleEffect.DENY.getName(), logger) || result;
+ String stringRuleEffect = DOMUtil.getStringAttribute(elementAdviceExpression, XACML3.ATTRIBUTE_APPLIESTO);
+ RuleEffect ruleEffect = RuleEffect.getRuleEffect(stringRuleEffect);
+ if (ruleEffect == null) {
+ logger.warn("Setting invalid RuleEffect " + stringRuleEffect + " to " + RuleEffect.DENY.getName());
+ elementAdviceExpression.setAttribute(XACML3.ATTRIBUTE_APPLIESTO, RuleEffect.DENY.getName());
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ * Creates a <code>List</code> of <code>AdviceExpression</code>s by parsing the given <code>Node</code> representing a
+ * XACML AdviceExpressions element.
+ *
+ * @param nodeAdviceExpressions the <code>Node</code> representing the XACML AdviceExpressions element
+ * @param policy the <code>Policy</code> encompassing the AdviceExpressions element
+ * @return a new <code>List</code> of <code>AdviceExpression</code>s parsed from the given <code>Node</code>.
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static List<AdviceExpression> newList(Node nodeAdviceExpressions, Policy policy) throws DOMStructureException {
+ Element elementAdviceExpressions = DOMUtil.getElement(nodeAdviceExpressions);
+ boolean bLenient = DOMProperties.isLenient();
+
+ List<AdviceExpression> listAdviceExpressions = new ArrayList<AdviceExpression>();
+
+ NodeList children = elementAdviceExpressions.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ADVICEEXPRESSION.equals(child.getLocalName())) {
+ listAdviceExpressions.add(DOMAdviceExpression.newInstance(child, policy));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeAdviceExpressions);
+ }
+ }
+ }
+ }
+
+ if (listAdviceExpressions.size() == 0 && !bLenient) {
+ throw DOMUtil.newMissingElementException(nodeAdviceExpressions, XACML3.XMLNS, XACML3.ELEMENT_ADVICEEXPRESSION);
+ }
+ return listAdviceExpressions;
+ }
+
+ public static boolean repairList(Node nodeAdviceExpressions) throws DOMStructureException {
+ Element elementAdviceExpressions = DOMUtil.getElement(nodeAdviceExpressions);
+ boolean result = false;
+
+ boolean sawAdviceExpression = false;
+ NodeList children = elementAdviceExpressions.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ADVICEEXPRESSION.equals(child.getLocalName())) {
+ sawAdviceExpression = true;
+ result = result || DOMAdviceExpression.repair(child);
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ nodeAdviceExpressions.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+
+ if (!sawAdviceExpression) {
+ throw DOMUtil.newMissingElementException(nodeAdviceExpressions, XACML3.XMLNS, XACML3.ELEMENT_ADVICEEXPRESSION);
+ }
+
+ return result;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.java
new file mode 100755
index 0000000..c169bc7
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.java
@@ -0,0 +1,109 @@
+/*
+ * 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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.AllOf;
+
+/**
+ * DOMAllOf extends {@link com.att.research.xacmlatt.pdp.policy.AllOf} with methods for creation from
+ * DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMAllOf extends AllOf {
+ private static final Log logger = LogFactory.getLog(DOMAllOf.class);
+
+ protected DOMAllOf() {
+ }
+
+ /**
+ * Creates a new <code>DOMAllOf</code> by parsing the given <code>Node</code> representing a XACML AllOf element.
+ *
+ * @param nodeAllOf the <code>Node</code> representing the XACML AllOf element
+ * @return a new <code>DOMAllOf</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the given <code>Node</code>
+ */
+ public static AllOf newInstance(Node nodeAllOf) throws DOMStructureException {
+ Element elementAllOf = DOMUtil.getElement(nodeAllOf);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMAllOf domAllOf = new DOMAllOf();
+
+ try {
+ NodeList children = elementAllOf.getChildNodes();
+ int numChildren;
+ boolean sawMatch = false;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_MATCH.equals(child.getLocalName())) {
+ domAllOf.addMatch(DOMMatch.newInstance(child));
+ sawMatch = true;
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeAllOf);
+ }
+ }
+ }
+ }
+ if (!sawMatch && !bLenient) {
+ throw DOMUtil.newMissingElementException(nodeAllOf, XACML3.XMLNS, XACML3.ELEMENT_MATCH);
+ }
+ } catch (DOMStructureException ex) {
+ domAllOf.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+ return domAllOf;
+ }
+
+ public static boolean repair(Node nodeAllOf) throws DOMStructureException {
+ Element elementAllOf = DOMUtil.getElement(nodeAllOf);
+ boolean result = false;
+
+ NodeList children = elementAllOf.getChildNodes();
+ int numChildren;
+ boolean sawMatch = false;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_MATCH.equals(child.getLocalName())) {
+ result = DOMMatch.repair(child) || result;
+ sawMatch = true;
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementAllOf.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+ if (!sawMatch) {
+ throw DOMUtil.newMissingElementException(nodeAllOf, XACML3.XMLNS, XACML3.ELEMENT_MATCH);
+ }
+
+ return result;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.java
new file mode 100755
index 0000000..882ce67
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.java
@@ -0,0 +1,100 @@
+/*
+ * 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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.AnyOf;
+
+/**
+ * DOMAnyOf extends {@link com.att.research.xacmlatt.pdp.policy.AnyOf} with methods for creation
+ * from DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMAnyOf extends AnyOf {
+ private static final Log logger = LogFactory.getLog(DOMAnyOf.class);
+
+ protected DOMAnyOf() {
+ }
+
+ /**
+ * Creates a new <code>DOMAnyOf</code> by parsing the given <code>Node</code> representing a XACML AnyOf element.
+ *
+ * @param nodeAnyOf the <code>Node</code> representing the XACML AnyOf element
+ * @return a new <code>DOMAnyOf</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the given <code>Node</code>.
+ */
+ public static AnyOf newInstance(Node nodeAnyOf) throws DOMStructureException {
+ Element elementAnyOf = DOMUtil.getElement(nodeAnyOf);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMAnyOf domAnyOf = new DOMAnyOf();
+
+ try {
+ NodeList children = elementAnyOf.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && (XACML3.ELEMENT_ALLOF.equals(child.getLocalName()))) {
+ domAnyOf.addAllOf(DOMAllOf.newInstance(child));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeAnyOf);
+ }
+ }
+ }
+ }
+ } catch (DOMStructureException ex) {
+ domAnyOf.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+
+ return domAnyOf;
+ }
+
+ public static boolean repair(Node nodeAnyOf) throws DOMStructureException {
+ Element elementAnyOf = DOMUtil.getElement(nodeAnyOf);
+ boolean result = false;
+
+ NodeList children = elementAnyOf.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && (XACML3.ELEMENT_ALLOF.equals(child.getLocalName()))) {
+ result = DOMAllOf.repair(child) || result;
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementAnyOf.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.java
new file mode 100755
index 0000000..1ca3021
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.java
@@ -0,0 +1,111 @@
+/*
+ * 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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.expressions.Apply;
+
+/**
+ * DOMApply extends {@link com.att.research.xacmlatt.pdp.policy.expressions.Apply} with methods for creation from
+ * DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMApply extends Apply {
+ private static final Log logger = LogFactory.getLog(DOMApply.class);
+
+ protected DOMApply() {
+ }
+
+ /**
+ * Creates a new <code>Apply</code> by parsing the given <code>Node</core> representing a XACML Apply element.
+ *
+ * @param nodeApply the <code>Node</code> representing the XACML Apply element
+ * @param policy the <code>Policy</code> encompassing the Apply element
+ * @return a new <code>Apply</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static Apply newInstance(Node nodeApply, Policy policy) throws DOMStructureException {
+ Element elementApply = DOMUtil.getElement(nodeApply);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMApply domApply = new DOMApply();
+
+ try {
+ NodeList children = nodeApply.getChildNodes();
+ if (children != null) {
+ int numChildren = children.getLength();
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE && XACML3.XMLNS.equals(child.getNamespaceURI())) {
+ String childName = child.getLocalName();
+ if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+ domApply.setDescription(child.getTextContent());
+ } else if (DOMExpression.isExpression(child)) {
+ domApply.addArgument(DOMExpression.newInstance(child, policy));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeApply);
+ }
+ }
+ }
+ }
+
+ domApply.setFunctionId(DOMUtil.getIdentifierAttribute(elementApply, XACML3.ATTRIBUTE_FUNCTIONID, !bLenient));
+ } catch (DOMStructureException ex) {
+ domApply.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+
+ return domApply;
+ }
+
+ public static boolean repair(Node nodeApply) throws DOMStructureException {
+ Element elementApply = DOMUtil.getElement(nodeApply);
+ boolean result = false;
+
+ NodeList children = nodeApply.getChildNodes();
+ if (children != null) {
+ int numChildren = children.getLength();
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE && XACML3.XMLNS.equals(child.getNamespaceURI())) {
+ String childName = child.getLocalName();
+ if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+ } else if (DOMExpression.isExpression(child)) {
+ result = DOMExpression.repair(child) || result;
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementApply.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+
+ result = DOMUtil.repairIdentifierAttribute(elementApply, XACML3.ATTRIBUTE_FUNCTIONID, XACML3.ID_FUNCTION_STRING_EQUAL, logger) || result;
+
+ return result;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.java
new file mode 100755
index 0000000..4e42751
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.java
@@ -0,0 +1,116 @@
+/*
+ * 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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.AttributeAssignmentExpression;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+
+/**
+ * DOMAttributeAssignmentExpression extends {@link com.att.research.xacmlatt.pdp.policy.AttributeAssignmentExpression} with
+ * methods for creation from {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class DOMAttributeAssignmentExpression extends AttributeAssignmentExpression {
+ private static final Log logger = LogFactory.getLog(DOMAttributeAssignmentExpression.class);
+
+ protected DOMAttributeAssignmentExpression() {
+ }
+
+ /**
+ * Creates a new <code>AttributeAssignmentExpression</code> by parsing the given <code>Node</code> representing
+ * a XACML AttributeAssignmentExpression element.
+ *
+ * @param nodeAttributeAssignmentExpression the <code>Node</code> representing the XACML AttributeAssignmentExpression element
+ * @return a new <code>AttributeAssignmentExpression</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static AttributeAssignmentExpression newInstance(Node nodeAttributeAssignmentExpression, Policy policy) throws DOMStructureException {
+ Element elementAttributeAssignmentExpression = DOMUtil.getElement(nodeAttributeAssignmentExpression);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMAttributeAssignmentExpression domAttributeAssignmentExpression = new DOMAttributeAssignmentExpression();
+
+ try {
+ Node node = DOMUtil.getFirstChildElement(elementAttributeAssignmentExpression);
+ if (node == null) {
+ if (!bLenient) {
+ throw DOMUtil.newMissingElementException(elementAttributeAssignmentExpression, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION);
+ }
+ } else {
+ domAttributeAssignmentExpression.setExpression(DOMExpression.newInstance(node, policy));
+ }
+
+ Identifier identifier;
+ domAttributeAssignmentExpression.setAttributeId(DOMUtil.getIdentifierAttribute(elementAttributeAssignmentExpression, XACML3.ATTRIBUTE_ATTRIBUTEID, !bLenient));;
+ if ((identifier = DOMUtil.getIdentifierAttribute(elementAttributeAssignmentExpression, XACML3.ATTRIBUTE_CATEGORY)) != null) {
+ domAttributeAssignmentExpression.setCategory(identifier);
+ }
+
+ String issuer = DOMUtil.getStringAttribute(elementAttributeAssignmentExpression, XACML3.ATTRIBUTE_ISSUER);
+ if (issuer != null) {
+ domAttributeAssignmentExpression.setIssuer(issuer);
+ }
+ } catch (DOMStructureException ex) {
+ domAttributeAssignmentExpression.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+
+ return domAttributeAssignmentExpression;
+ }
+
+ public static boolean repair(Node nodeAttributeAssignmentExpression) throws DOMStructureException {
+ Element elementAttributeAssignmentExpression = DOMUtil.getElement(nodeAttributeAssignmentExpression);
+ boolean result = false;
+
+ if (DOMUtil.getFirstChildElement(elementAttributeAssignmentExpression) == null) {
+ /*
+ * See if we can repair the <AttributeAssignmentExpression DataType="">string</AttributeAssignmentExpression> pattern
+ */
+ Identifier identifier = DOMUtil.getIdentifierAttribute(elementAttributeAssignmentExpression, XACML3.ATTRIBUTE_DATATYPE);
+ String textContent = elementAttributeAssignmentExpression.getTextContent();
+ if (textContent != null) {
+ textContent = textContent.trim();
+ }
+ if (textContent != null && textContent.length() > 0 && identifier != null) {
+ Element attributeValue = elementAttributeAssignmentExpression.getOwnerDocument().createElementNS(XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+ attributeValue.setAttribute(XACML3.ATTRIBUTE_DATATYPE, identifier.stringValue());
+ attributeValue.setTextContent(textContent);
+ logger.warn("Adding a new AttributeValue using the DataType from the AttributeAssignment");
+ elementAttributeAssignmentExpression.removeAttribute(XACML3.ATTRIBUTE_DATATYPE);
+ while (elementAttributeAssignmentExpression.hasChildNodes()) {
+ elementAttributeAssignmentExpression.removeChild(elementAttributeAssignmentExpression.getFirstChild());
+ }
+ elementAttributeAssignmentExpression.appendChild(attributeValue);
+ result = true;
+ } else {
+ throw DOMUtil.newMissingElementException(elementAttributeAssignmentExpression, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION);
+ }
+ }
+ result = DOMUtil.repairIdentifierAttribute(elementAttributeAssignmentExpression, XACML3.ATTRIBUTE_ATTRIBUTEID, logger) || result;
+
+ return result;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.java
new file mode 100755
index 0000000..1d5936f
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.java
@@ -0,0 +1,87 @@
+/*
+ * 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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.expressions.AttributeDesignator;
+
+/**
+ * DOMAttributeDesignator extends {@link com.att.research.xacmlatt.pdp.policy.expressions.AttributeDesignator} with methods
+ * for creation from DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class DOMAttributeDesignator extends AttributeDesignator {
+ private static final Log logger = LogFactory.getLog(DOMAttributeDesignator.class);
+
+ protected DOMAttributeDesignator() {
+ }
+
+ /**
+ * Creates a new <code>DOMAttributeDesignator</code> by parsing the given <code>Node</code> representing a XACML AttributeDesignator
+ * element.
+ *
+ * @param nodeAttributeDesignator the <code>Node</code> representing the XACML AttributeDesignator element
+ * @return a new <code>DOMAttributeDesignator</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static AttributeDesignator newInstance(Node nodeAttributeDesignator) throws DOMStructureException {
+ Element elementAttributeDesignator = DOMUtil.getElement(nodeAttributeDesignator);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMAttributeDesignator domAttributeDesignator = new DOMAttributeDesignator();
+
+ try {
+ domAttributeDesignator.setCategory(DOMUtil.getIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_CATEGORY, !bLenient));
+ domAttributeDesignator.setAttributeId(DOMUtil.getIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_ATTRIBUTEID, !bLenient));
+ domAttributeDesignator.setDataTypeId(DOMUtil.getIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_DATATYPE, !bLenient));
+
+ String string;
+ if ((string = DOMUtil.getStringAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_ISSUER)) != null) {
+ domAttributeDesignator.setIssuer(string);
+ }
+ Boolean mustBePresent = DOMUtil.getBooleanAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_MUSTBEPRESENT, !bLenient);
+ if (mustBePresent != null) {
+ domAttributeDesignator.setMustBePresent(mustBePresent);
+ }
+ } catch (DOMStructureException ex) {
+ domAttributeDesignator.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+
+ return domAttributeDesignator;
+ }
+
+ public static boolean repair(Node nodeAttributeDesignator) throws DOMStructureException {
+ Element elementAttributeDesignator = DOMUtil.getElement(nodeAttributeDesignator);
+ boolean result = false;
+
+ result = DOMUtil.repairIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_CATEGORY, logger) || result;
+ result = DOMUtil.repairIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_ATTRIBUTEID, logger) || result;
+ result = DOMUtil.repairIdentifierAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_DATATYPE, logger) || result;
+ result = DOMUtil.repairBooleanAttribute(elementAttributeDesignator, XACML3.ATTRIBUTE_MUSTBEPRESENT, false, logger) || result;
+
+ return result;
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.java
new file mode 100755
index 0000000..da1359b
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.java
@@ -0,0 +1,87 @@
+/*
+ * 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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.expressions.AttributeSelector;
+
+/**
+ * DOMAttributeSelector extends {@link com.att.research.xacmlatt.pdp.policy.expressions.AttributeSelector} with methods
+ * for creation from DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class DOMAttributeSelector extends AttributeSelector {
+ private static Log logger = LogFactory.getLog(DOMAttributeSelector.class);
+
+ protected DOMAttributeSelector() {
+ }
+
+ /**
+ * Creates a new <code>DOMAttributeSelector</code> by parsing the given <code>Node</code> representing a XACML AttributeSelector element.
+ *
+ * @param nodeAttributeSelector the <code>Node</code> representing the XACML AttributeSelector element
+ * @return a new <code>DOMAttributeSelector</code> parsed from the given <code>Node</code>.
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static AttributeSelector newInstance(Node nodeAttributeSelector) throws DOMStructureException {
+ Element elementAttributeSelector = DOMUtil.getElement(nodeAttributeSelector);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMAttributeSelector domAttributeSelector = new DOMAttributeSelector();
+
+ try {
+ domAttributeSelector.setCategory(DOMUtil.getIdentifierAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_CATEGORY, !bLenient));
+
+ Identifier identifier;
+ if ((identifier = DOMUtil.getIdentifierAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_CONTEXTSELECTORID)) != null) {
+ domAttributeSelector.setContextSelectorId(identifier);
+ }
+
+ domAttributeSelector.setPath(DOMUtil.getStringAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_PATH, !bLenient));
+ domAttributeSelector.setDataTypeId(DOMUtil.getIdentifierAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_DATATYPE, !bLenient));
+ Boolean mustBePresent = DOMUtil.getBooleanAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_MUSTBEPRESENT, !bLenient);
+ if (mustBePresent != null) {
+ domAttributeSelector.setMustBePresent(mustBePresent);
+ }
+ } catch (DOMStructureException ex) {
+ domAttributeSelector.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+
+ return domAttributeSelector;
+ }
+
+ public static boolean repair(Node nodeAttributeSelector) throws DOMStructureException {
+ Element elementAttributeSelector = DOMUtil.getElement(nodeAttributeSelector);
+ boolean result = false;
+
+ result = DOMUtil.repairIdentifierAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_CATEGORY, logger) || result;
+ result = DOMUtil.repairStringAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_PATH, "/", logger) || result;
+ result = DOMUtil.repairIdentifierAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_DATATYPE, logger) || result;
+ result = DOMUtil.repairBooleanAttribute(elementAttributeSelector, XACML3.ATTRIBUTE_MUSTBEPRESENT, false, logger) || result;
+
+ return result;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.java
new file mode 100755
index 0000000..b32a4c7
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.java
@@ -0,0 +1,183 @@
+/*
+ * 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.policy.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMAttributeValue;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+
+/**
+ * DOMCombinerParameter extends {@link com.att.research.xacmlatt.pdp.policy.CombinerParameter} with methods for
+ * creation from DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMCombinerParameter extends CombinerParameter {
+ private static final Log logger = LogFactory.getLog(DOMCombinerParameter.class);
+
+ protected DOMCombinerParameter() {
+
+ }
+
+ /**
+ * Creates a new <code>CombinerParameter</code> by parsing the given <code>Node</code> representing a XACML CombinerParameter element.
+ *
+ * @param nodeCombinerParameter the <code>Node</code> representing the XACML CombinerParameter element
+ * @return a new <code>CombinerParameter</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static CombinerParameter newInstance(Node nodeCombinerParameter) throws DOMStructureException {
+ Element elementCombinerParameter = DOMUtil.getElement(nodeCombinerParameter);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMCombinerParameter combinerParameter = new DOMCombinerParameter();
+
+ try {
+ NodeList children = elementCombinerParameter.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+ if (combinerParameter.getAttributeValue() != null && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, elementCombinerParameter);
+ } else {
+ combinerParameter.setAttributeValue(DOMAttributeValue.newInstance(child, null));
+ }
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, elementCombinerParameter);
+ }
+ }
+ }
+ }
+
+ if (combinerParameter.getAttributeValue() == null && !bLenient) {
+ throw DOMUtil.newMissingElementException(elementCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+ }
+ combinerParameter.setName(DOMUtil.getStringAttribute(elementCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, !bLenient));
+ } catch (DOMStructureException ex) {
+ combinerParameter.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+
+ return combinerParameter;
+ }
+
+ public static boolean repair(Node nodeCombinerParameter) throws DOMStructureException {
+ Element elementCombinerParameter = DOMUtil.getElement(nodeCombinerParameter);
+ boolean result = false;
+
+ NodeList children = elementCombinerParameter.getChildNodes();
+ int numChildren;
+ boolean sawAttributeValue = false;
+
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+ if (sawAttributeValue) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementCombinerParameter.removeChild(child);
+ result = true;
+ } else {
+ result = DOMAttributeValue.repair(child) || result;
+ sawAttributeValue = true;
+ }
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementCombinerParameter.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+
+ if (!sawAttributeValue) {
+ throw DOMUtil.newMissingElementException(elementCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+ }
+
+ result = DOMUtil.repairStringAttribute(elementCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, "parameter", logger) || result;
+
+ return result;
+ }
+
+ /**
+ * Creates a <code>List</code> of <code>CombinerParameter</code>s by parsing the given <code>Node</code> representing a
+ * XACML CombinerParameters element.
+ *
+ * @param nodeCombinerParameters the <code>Node</code> representing the XACML CombinerParameters element
+ * @return a <code>List</code> of <code>CombinerParameter</code>s parsed from the given <code>Node</code>.
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static List<CombinerParameter> newList(Node nodeCombinerParameters) throws DOMStructureException {
+ Element elementCombinerParameters = DOMUtil.getElement(nodeCombinerParameters);
+ boolean bLenient = DOMProperties.isLenient();
+
+ List<CombinerParameter> listCombinerParameters = new ArrayList<CombinerParameter>();
+
+ NodeList children = elementCombinerParameters.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_COMBINERPARAMETER.equals(child.getLocalName())) {
+ listCombinerParameters.add(DOMCombinerParameter.newInstance(child));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, elementCombinerParameters);
+ }
+ }
+ }
+ }
+ return listCombinerParameters;
+ }
+
+ public static boolean repairList(Node nodeCombinerParameters) throws DOMStructureException {
+ Element elementCombinerParameters = DOMUtil.getElement(nodeCombinerParameters);
+ boolean result = false;
+
+ NodeList children = elementCombinerParameters.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_COMBINERPARAMETER.equals(child.getLocalName())) {
+ result = DOMCombinerParameter.repair(child) || result;
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementCombinerParameters.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+ return result;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.java
new file mode 100755
index 0000000..f25e6cd
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.java
@@ -0,0 +1,70 @@
+/*
+ * 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.policy.dom;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+
+/**
+ * DOMDocumentRepair extends {@link com.att.research.xacml.std.dom.DOMDocumentRepair} to repair Policy documents as well as
+ * Request and Response documents.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class DOMDocumentRepair extends com.att.research.xacml.std.dom.DOMDocumentRepair {
+ protected boolean repairPolicy(Node nodePolicy) throws DOMStructureException {
+ return DOMPolicy.repair(nodePolicy);
+ }
+
+ protected boolean repairPolicySet(Node nodePolicySet) throws DOMStructureException {
+ return DOMPolicySet.repair(nodePolicySet);
+ }
+
+ public DOMDocumentRepair() {
+ }
+
+ /**
+ * Determines what kind of XACML document is represented by the given <code>Document</code> and
+ * attempts to repair it.
+ *
+ * @param document the <code>Document</code> to check
+ * @return true if any repairs were made in the <code>Document</code>, else false
+ * @throws DOMStructureException if there were unrecoverable errors found
+ * @throws UnsupportedDocumentTypeException if the root element is not a XACML Request or Response.
+ */
+ public boolean repair(Document document) throws DOMStructureException, UnsupportedDocumentTypeException {
+ Node firstChild = DOMUtil.getFirstChildElement(document);
+ if (firstChild == null || !DOMUtil.isElement(firstChild)) {
+ return false;
+ }
+
+ if (!DOMUtil.isInNamespace(firstChild, XACML3.XMLNS)) {
+ throw new UnsupportedDocumentTypeException("Not a XACML document: " + DOMUtil.getNodeLabel(firstChild));
+ }
+ if (XACML3.ELEMENT_REQUEST.equals(firstChild.getLocalName())) {
+ return this.repairRequest(firstChild);
+ } else if (XACML3.ELEMENT_RESPONSE.equals(firstChild.getLocalName())) {
+ return this.repairResponse(firstChild);
+ } else if (XACML3.ELEMENT_POLICY.equals(firstChild.getLocalName())) {
+ return this.repairPolicy(firstChild);
+ } else if (XACML3.ELEMENT_POLICYSET.equals(firstChild.getLocalName())) {
+ return this.repairPolicySet(firstChild);
+ } else {
+ throw new UnsupportedDocumentTypeException("Not a XACML Request or Response: " + DOMUtil.getNodeLabel(firstChild));
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.java
new file mode 100755
index 0000000..b9b1ac7
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.java
@@ -0,0 +1,120 @@
+/*
+ * 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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMAttributeValue;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.Expression;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.expressions.AttributeValueExpression;
+import com.att.research.xacmlatt.pdp.policy.expressions.Function;
+import com.att.research.xacmlatt.pdp.policy.expressions.VariableReference;
+
+/**
+ * DOMExpression extends {@link com.att.research.xacmlatt.pdp.policy.Expression} with methods for creation
+ * from DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public abstract class DOMExpression extends Expression {
+ private static final Log logger = LogFactory.getLog(DOMExpression.class);
+
+ protected DOMExpression() {
+ }
+
+ public static boolean isExpression(Node nodeExpression) {
+ String nodeName = nodeExpression.getLocalName();
+ return (XACML3.ELEMENT_APPLY.equals(nodeName) ||
+ XACML3.ELEMENT_ATTRIBUTEDESIGNATOR.equals(nodeName) ||
+ XACML3.ELEMENT_ATTRIBUTESELECTOR.equals(nodeName) ||
+ XACML3.ELEMENT_ATTRIBUTEVALUE.equals(nodeName) ||
+ XACML3.ELEMENT_FUNCTION.equals(nodeName) ||
+ XACML3.ELEMENT_VARIABLEREFERENCE.equals(nodeName)
+ );
+ }
+
+ /**
+ * Creates a new <code>Expression</code> of the appropriate sub-type based on the name of the given <code>Node</code>.
+ *
+ * @param nodeExpression the <code>Node</code> to parse
+ * @param policy the {@link com.att.research.xacmlatt.pdp.policy.Policy} containing the Expression element
+ * @return a new <code>Expression</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static Expression newInstance(Node nodeExpression, Policy policy) throws DOMStructureException {
+ Element elementExpression = DOMUtil.getElement(nodeExpression);
+ boolean bLenient = DOMProperties.isLenient();
+
+ if (DOMUtil.isInNamespace(elementExpression, XACML3.XMLNS)) {
+ if (elementExpression.getLocalName().equals(XACML3.ELEMENT_APPLY)) {
+ return DOMApply.newInstance(elementExpression, policy);
+ } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTEDESIGNATOR)) {
+ return DOMAttributeDesignator.newInstance(elementExpression);
+ } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTESELECTOR)) {
+ return DOMAttributeSelector.newInstance(elementExpression);
+ } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTEVALUE)) {
+ AttributeValue<?> attributeValue = null;
+ try {
+ attributeValue = DOMAttributeValue.newInstance(elementExpression, null);
+ } catch (DOMStructureException ex) {
+ return new AttributeValueExpression(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ }
+ return new AttributeValueExpression(attributeValue);
+ } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_FUNCTION)) {
+ return new Function(DOMUtil.getIdentifierAttribute(elementExpression, XACML3.ATTRIBUTE_FUNCTIONID));
+ } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_VARIABLEREFERENCE)) {
+ return new VariableReference(policy, DOMUtil.getStringAttribute(elementExpression, XACML3.ATTRIBUTE_VARIABLEID));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(nodeExpression);
+ } else {
+ return null;
+ }
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(nodeExpression);
+ } else {
+ return null;
+ }
+ }
+
+ public static boolean repair(Node nodeExpression) throws DOMStructureException {
+ Element elementExpression = DOMUtil.getElement(nodeExpression);
+ if (DOMUtil.isInNamespace(elementExpression, XACML3.XMLNS)) {
+ if (elementExpression.getLocalName().equals(XACML3.ELEMENT_APPLY)) {
+ return DOMApply.repair(elementExpression);
+ } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTEDESIGNATOR)) {
+ return DOMAttributeDesignator.repair(elementExpression);
+ } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTESELECTOR)) {
+ return DOMAttributeSelector.repair(elementExpression);
+ } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_ATTRIBUTEVALUE)) {
+ return DOMAttributeValue.repair(elementExpression);
+ } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_FUNCTION)) {
+ return DOMUtil.repairIdentifierAttribute(elementExpression, XACML3.ATTRIBUTE_FUNCTIONID, XACML3.ID_FUNCTION_STRING_EQUAL, logger);
+ } else if (elementExpression.getLocalName().equals(XACML3.ELEMENT_VARIABLEREFERENCE)) {
+ return DOMUtil.repairStringAttribute(elementExpression, XACML3.ATTRIBUTE_VARIABLEID, "variableId", logger);
+ } else {
+ throw DOMUtil.newUnexpectedElementException(nodeExpression);
+ }
+ } else {
+ throw DOMUtil.newUnexpectedElementException(nodeExpression);
+ }
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.java
new file mode 100755
index 0000000..756750a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.java
@@ -0,0 +1,173 @@
+/*
+ * 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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMAttributeValue;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.Match;
+
+/**
+ * DOMMatch extends {@link com.att.research.xacmlatt.pdp.policy.Match} with methods for creation from
+ * DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class DOMMatch extends Match {
+ private static Log logger = LogFactory.getLog(DOMMatch.class);
+
+ protected DOMMatch() {
+ }
+
+ /**
+ * Creates a new <code>DOMMatch</code> by parsing the given <code>Node</code> representing a XACML Match element.
+ *
+ * @param nodeMatch the <code>Node</code> representing the XACML Match element
+ * @return a new <code>DOMMatch</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the given <code>Node</code>
+ */
+ public static Match newInstance(Node nodeMatch) throws DOMStructureException {
+ Element elementMatch = DOMUtil.getElement(nodeMatch);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMMatch domMatch = new DOMMatch();
+
+ try {
+ NodeList children = elementMatch.getChildNodes();
+ int numChildren;
+
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+ String childName = child.getLocalName();
+ if (XACML3.ELEMENT_ATTRIBUTEVALUE.equals(childName)) {
+ domMatch.setAttributeValue(DOMAttributeValue.newInstance(child, null));
+ } else if (XACML3.ELEMENT_ATTRIBUTEDESIGNATOR.equals(childName)) {
+ if (domMatch.getAttributeRetrievalBase() != null && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeMatch);
+ }
+ domMatch.setAttributeRetrievalBase(DOMAttributeDesignator.newInstance(child));
+ } else if (XACML3.ELEMENT_ATTRIBUTESELECTOR.equals(childName)) {
+ if (domMatch.getAttributeRetrievalBase() != null) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeMatch);
+ }
+ domMatch.setAttributeRetrievalBase(DOMAttributeSelector.newInstance(child));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeMatch);
+ }
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeMatch);
+ }
+ }
+ }
+ }
+
+ /*
+ * We have to see exactly one of these
+ */
+ if (domMatch.getAttributeRetrievalBase() == null && !bLenient) {
+ throw DOMUtil.newMissingElementException(nodeMatch, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEDESIGNATOR + " or " + XACML3.ELEMENT_ATTRIBUTESELECTOR);
+ } else if (domMatch.getAttributeValue() == null && !bLenient) {
+ throw DOMUtil.newMissingElementException(nodeMatch, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+ }
+
+ domMatch.setMatchId(DOMUtil.getIdentifierAttribute(elementMatch, XACML3.ATTRIBUTE_MATCHID, !bLenient));
+
+ } catch (DOMStructureException ex) {
+ domMatch.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+ return domMatch;
+ }
+
+ public static boolean repair(Node nodeMatch) throws DOMStructureException {
+ Element elementMatch = DOMUtil.getElement(nodeMatch);
+ boolean result = false;
+
+ NodeList children = elementMatch.getChildNodes();
+ int numChildren;
+ boolean sawAttributeRetrievalBase = false;
+ boolean sawAttributeValue = false;
+
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+ String childName = child.getLocalName();
+ if (XACML3.ELEMENT_ATTRIBUTEVALUE.equals(childName)) {
+ if (sawAttributeValue) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementMatch.removeChild(child);
+ result = true;
+ } else {
+ result = DOMAttributeValue.repair(child) || result;
+ sawAttributeValue = true;
+ }
+ } else if (XACML3.ELEMENT_ATTRIBUTEDESIGNATOR.equals(childName)) {
+ if (sawAttributeRetrievalBase) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementMatch.removeChild(child);
+ result = true;
+ } else {
+ result = DOMAttributeDesignator.repair(child) || result;
+ sawAttributeRetrievalBase = true;
+ }
+ } else if (XACML3.ELEMENT_ATTRIBUTESELECTOR.equals(childName)) {
+ if (sawAttributeRetrievalBase) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementMatch.removeChild(child);
+ result = true;
+ } else {
+ result = DOMAttributeSelector.repair(child) || result;
+ sawAttributeRetrievalBase = true;
+ }
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementMatch.removeChild(child);
+ result = true;
+ }
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementMatch.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+
+ /*
+ * We have to see exactly one of these
+ */
+ if (!sawAttributeRetrievalBase) {
+ throw DOMUtil.newMissingElementException(nodeMatch, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEDESIGNATOR + " or " + XACML3.ELEMENT_ATTRIBUTESELECTOR);
+ } else if (!sawAttributeValue) {
+ throw DOMUtil.newMissingElementException(nodeMatch, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+ }
+ result = DOMUtil.repairIdentifierAttribute(elementMatch, XACML3.ATTRIBUTE_MATCHID, logger) || result;
+
+ return result;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.java
new file mode 100755
index 0000000..7f5832c
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.java
@@ -0,0 +1,195 @@
+/*
+ * 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.policy.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.ObligationExpression;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.RuleEffect;
+
+/**
+ * DOMObligationExpression extends {@link com.att.research.xacmlatt.pdp.policy.ObligationExpression} with methods
+ * for creation from {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class DOMObligationExpression extends ObligationExpression {
+ private static final Log logger = LogFactory.getLog(DOMObligationExpression.class);
+
+ protected DOMObligationExpression() {
+ }
+
+ /**
+ * Creates a new <code>ObligationExpression</code> by parsing the given <code>Node</code> representing a XACML ObligationExpression element.
+ *
+ * @param nodeObligationExpression the <code>Node</code> representing the XACML ObligationExpression element
+ * @param policy the {@link com.att.research.xacmlatt.pdp.policy.Policy} encompassing the ObligationExpression element
+ * @return a new <code>ObligationExpression</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static ObligationExpression newInstance(Node nodeObligationExpression, Policy policy) throws DOMStructureException {
+ Element elementObligationExpression = DOMUtil.getElement(nodeObligationExpression);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMObligationExpression domObligationExpression = new DOMObligationExpression();
+
+ try {
+ NodeList children = elementObligationExpression.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEASSIGNMENTEXPRESSION.equals(child.getLocalName())) {
+ domObligationExpression.addAttributeAssignmentExpression(DOMAttributeAssignmentExpression.newInstance(child, policy));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeObligationExpression);
+ }
+ }
+ }
+ }
+
+ domObligationExpression.setObligationId(DOMUtil.getIdentifierAttribute(elementObligationExpression, XACML3.ATTRIBUTE_OBLIGATIONID, !bLenient));
+
+ String string = DOMUtil.getStringAttribute(elementObligationExpression, XACML3.ATTRIBUTE_FULFILLON, !bLenient);
+ RuleEffect ruleEffectType = RuleEffect.getRuleEffect(string);
+ if (ruleEffectType == null) {
+ if (!bLenient) {
+ throw new DOMStructureException(nodeObligationExpression, "Invalid EffectType \"" + string + "\" in \"" + DOMUtil.getNodeLabel(nodeObligationExpression) + "\"");
+ }
+ } else {
+ domObligationExpression.setRuleEffect(ruleEffectType);
+ }
+ } catch (DOMStructureException ex) {
+ domObligationExpression.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+ return domObligationExpression;
+ }
+
+ public static boolean repair(Node nodeObligationExpression) throws DOMStructureException {
+ Element elementObligationExpression = DOMUtil.getElement(nodeObligationExpression);
+ boolean result = false;
+
+ NodeList children = elementObligationExpression.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEASSIGNMENTEXPRESSION.equals(child.getLocalName())) {
+ result = DOMAttributeAssignmentExpression.repair(child) || result;
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementObligationExpression.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+
+ result = DOMUtil.repairIdentifierAttribute(elementObligationExpression, XACML3.ATTRIBUTE_OBLIGATIONID, logger) || result;
+ result = DOMUtil.repairStringAttribute(elementObligationExpression, XACML3.ATTRIBUTE_FULFILLON, RuleEffect.DENY.getName(), logger) || result;
+
+ String string = DOMUtil.getStringAttribute(elementObligationExpression, XACML3.ATTRIBUTE_FULFILLON);
+ RuleEffect ruleEffectType = RuleEffect.getRuleEffect(string);
+ if (ruleEffectType == null) {
+ logger.warn("Setting invalid RuleEffect " + string + " to " + RuleEffect.DENY.getName());
+ elementObligationExpression.setAttribute(XACML3.ATTRIBUTE_FULFILLON, RuleEffect.DENY.getName());
+ result = true;
+ }
+
+ return result;
+ }
+
+ /**
+ * Creates a <code>List</code> of <code>ObligationExpression</code>s by parsing the given <code>Node</code>
+ * representing a XACML ObligationExpressions element.
+ *
+ * @param nodeObligationExpressions the <code>Node</code> representing the XACML ObligationExpressions element
+ * @param policy the <code>Policy</code> encompassing the ObligationExpressions element
+ * @return a new <code>List</code> of <code>ObligationExpression</code>s parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static List<ObligationExpression> newList(Node nodeObligationExpressions, Policy policy) throws DOMStructureException {
+ Element elementObligationExpressions = DOMUtil.getElement(nodeObligationExpressions);
+ boolean bLenient = DOMProperties.isLenient();
+
+ List<ObligationExpression> listObligationExpressions = new ArrayList<ObligationExpression>();
+
+ NodeList children = elementObligationExpressions.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_OBLIGATIONEXPRESSION.equals(child.getLocalName())) {
+ listObligationExpressions.add(DOMObligationExpression.newInstance(child, policy));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, elementObligationExpressions);
+ }
+ }
+ }
+ }
+
+ if (listObligationExpressions.size() == 0 && !bLenient) {
+ throw DOMUtil.newMissingElementException(elementObligationExpressions, XACML3.XMLNS, XACML3.ELEMENT_OBLIGATIONEXPRESSION);
+ }
+
+ return listObligationExpressions;
+ }
+
+ public static boolean repairList(Node nodeObligationExpressions) throws DOMStructureException {
+ Element elementObligationExpressions = DOMUtil.getElement(nodeObligationExpressions);
+ boolean result = false;
+
+ boolean sawObligationExpression = false;
+ NodeList children = elementObligationExpressions.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_OBLIGATIONEXPRESSION.equals(child.getLocalName())) {
+ result = DOMObligationExpression.repair(child) || result;
+ sawObligationExpression = true;
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementObligationExpressions.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+ if (!sawObligationExpression) {
+ throw DOMUtil.newMissingElementException(elementObligationExpressions, XACML3.XMLNS, XACML3.ELEMENT_OBLIGATIONEXPRESSION);
+ }
+
+ return result;
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.java
new file mode 100755
index 0000000..b248325
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.java
@@ -0,0 +1,315 @@
+/*
+ * 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.policy.dom;
+
+import java.io.File;
+import java.util.Iterator;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+import com.att.research.xacmlatt.pdp.policy.Rule;
+
+/**
+ * DOMPolicy extends {@link com.att.research.xacmlatt.pdp.policy.Policy} with methods for creation from a
+ * DOM {@link org.w3c.dom.Node}.
+ *
+ * @author car
+ * @version $Revision: 1.4 $
+ */
+public class DOMPolicy {
+ private static final Log logger = LogFactory.getLog(DOMPolicy.class);
+
+ /**
+ * Creates a new <code>DOMPolicy</code> to be configured from a DOM <code>Node</code>.
+ */
+ protected DOMPolicy() {
+ }
+
+ /**
+ * Creates a new <code>DOMPolicy</code> by parsing the given <code>Node</code> representing a XACML Policy element.
+ *
+ * @param nodePolicy the <code>Node</code> representing the Policy element
+ * @param policyDefaultsParent the <code>PolicyDefaults</code> of the parent element of the Policy element or null if this is the root
+ * @return a new <code>DOMPolicy</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static Policy newInstance(Node nodePolicy, PolicySet policySetParent, PolicyDefaults policyDefaultsParent) throws DOMStructureException {
+ Element elementPolicy = DOMUtil.getElement(nodePolicy);
+ boolean bLenient = DOMProperties.isLenient();
+
+ Policy domPolicy = new Policy(policySetParent);
+
+ Identifier identifier;
+ Integer integer;
+ Iterator<?> iterator;
+
+ try {
+ NodeList children = elementPolicy.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ /*
+ * Run through once, quickly, to set the PolicyDefaults for the new DOMPolicySet
+ */
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isNamespaceElement(child, XACML3.XMLNS) && XACML3.ELEMENT_POLICYDEFAULTS.equals(child.getLocalName())) {
+ if (domPolicy.getPolicyDefaults() != null && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicy);
+ }
+ domPolicy.setPolicyDefaults(DOMPolicyDefaults.newInstance(child, policyDefaultsParent));
+ }
+ }
+ if (domPolicy.getPolicyDefaults() == null) {
+ domPolicy.setPolicyDefaults(policyDefaultsParent);
+ }
+
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+ String childName = child.getLocalName();
+ if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+ if (domPolicy.getDescription() != null && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicy);
+ }
+ domPolicy.setDescription(child.getTextContent());
+ } else if (XACML3.ELEMENT_POLICYISSUER.equals(childName)) {
+ if (domPolicy.getPolicyIssuer() != null && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicy);
+ }
+ domPolicy.setPolicyIssuer(DOMPolicyIssuer.newInstance(child));
+ } else if (XACML3.ELEMENT_POLICYDEFAULTS.equals(childName)) {
+ } else if (XACML3.ELEMENT_TARGET.equals(childName)) {
+ if (domPolicy.getTarget() != null && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicy);
+ }
+ domPolicy.setTarget(DOMTarget.newInstance(child));
+ } else if (XACML3.ELEMENT_COMBINERPARAMETERS.equals(childName)) {
+ domPolicy.addCombinerParameters(DOMCombinerParameter.newList(child));
+ } else if (XACML3.ELEMENT_RULECOMBINERPARAMETERS.equals(childName)) {
+ domPolicy.addRuleCombinerParameter(DOMRuleCombinerParameters.newInstance(child));
+ } else if (XACML3.ELEMENT_VARIABLEDEFINITION.equals(childName)) {
+ domPolicy.addVariableDefinition(DOMVariableDefinition.newInstance(child, domPolicy));
+ } else if (XACML3.ELEMENT_RULE.equals(childName)) {
+ domPolicy.addRule(DOMRule.newInstance(child, domPolicy));
+ } else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) {
+ if ((iterator = domPolicy.getObligationExpressions()) != null && iterator.hasNext() && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicy);
+ }
+ domPolicy.setObligationExpressions(DOMObligationExpression.newList(child, domPolicy));
+ } else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) {
+ if ((iterator = domPolicy.getAdviceExpressions())!= null && iterator.hasNext() && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicy);
+ }
+ domPolicy.setAdviceExpressions(DOMAdviceExpression.newList(child, domPolicy));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicy);
+ }
+ }
+ }
+ }
+ }
+ domPolicy.setIdentifier(DOMUtil.getIdentifierAttribute(elementPolicy, XACML3.ATTRIBUTE_POLICYID, !bLenient));
+ domPolicy.setVersion(DOMUtil.getVersionAttribute(elementPolicy, XACML3.ATTRIBUTE_VERSION, !bLenient));
+
+ identifier = DOMUtil.getIdentifierAttribute(elementPolicy, XACML3.ATTRIBUTE_RULECOMBININGALGID, !bLenient);
+ CombiningAlgorithm<Rule> combiningAlgorithmRule = null;
+ try {
+ combiningAlgorithmRule = CombiningAlgorithmFactory.newInstance().getRuleCombiningAlgorithm(identifier);
+ } catch (FactoryException ex) {
+ if (!bLenient) {
+ throw new DOMStructureException("Failed to get CombiningAlgorithm", ex);
+ }
+ }
+ if (combiningAlgorithmRule == null && !bLenient) {
+ throw new DOMStructureException(elementPolicy, "Unknown rule combining algorithm \"" + identifier.toString() + "\" in \"" + DOMUtil.getNodeLabel(nodePolicy));
+ } else {
+ domPolicy.setRuleCombiningAlgorithm(combiningAlgorithmRule);
+ }
+
+
+ if ((integer = DOMUtil.getIntegerAttribute(elementPolicy, XACML3.ATTRIBUTE_MAXDELEGATIONDEPTH)) != null) {
+ domPolicy.setMaxDelegationDepth(integer);
+ }
+ } catch (DOMStructureException ex) {
+ domPolicy.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+
+ return domPolicy;
+ }
+
+ public static boolean repair(Node nodePolicy) throws DOMStructureException {
+ Element elementPolicy = DOMUtil.getElement(nodePolicy);
+ boolean result = false;
+
+ NodeList children = elementPolicy.getChildNodes();
+ int numChildren;
+ boolean sawDescription = false;
+ boolean sawIssuer = false;
+ boolean sawTarget = false;
+ boolean sawPolicyDefaults = false;
+ boolean sawObligationExprs = false;
+ boolean sawAdviceExprs = false;
+
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+ String childName = child.getLocalName();
+ if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+ if (sawDescription) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicy.removeChild(child);
+ result = true;
+ } else {
+ sawDescription = true;
+ }
+ } else if (XACML3.ELEMENT_POLICYISSUER.equals(childName)) {
+ if (sawIssuer) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicy.removeChild(child);
+ result = true;
+ } else {
+ sawDescription = true;
+ result = DOMPolicyIssuer.repair(child) || result;
+ }
+ } else if (XACML3.ELEMENT_POLICYDEFAULTS.equals(childName)) {
+ if (sawPolicyDefaults) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicy.removeChild(child);
+ result = true;
+ } else {
+ sawPolicyDefaults = true;
+ result = DOMPolicyDefaults.repair(child) || result;
+ }
+ } else if (XACML3.ELEMENT_TARGET.equals(childName)) {
+ if (sawTarget) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicy.removeChild(child);
+ result = true;
+ } else {
+ sawTarget = true;
+ result = DOMTarget.repair(child) || result;
+ }
+ } else if (XACML3.ELEMENT_COMBINERPARAMETERS.equals(childName)) {
+ result = DOMCombinerParameter.repair(child) || result;
+ } else if (XACML3.ELEMENT_RULECOMBINERPARAMETERS.equals(childName)) {
+ result = DOMRuleCombinerParameters.repair(child) || result;
+ } else if (XACML3.ELEMENT_VARIABLEDEFINITION.equals(childName)) {
+ result = DOMVariableDefinition.repair(child) || result;
+ } else if (XACML3.ELEMENT_RULE.equals(childName)) {
+ result = DOMRule.repair(child) || result;
+ } else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) {
+ if (sawObligationExprs) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicy.removeChild(child);
+ result = true;
+ } else {
+ sawObligationExprs = true;
+ result = DOMObligationExpression.repairList(child) || result;
+ }
+ } else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) {
+ if (sawAdviceExprs) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicy.removeChild(child);
+ result = true;
+ } else {
+ sawAdviceExprs = true;
+ result = DOMAdviceExpression.repairList(child) || result;
+ }
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicy.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+ }
+ result = DOMUtil.repairIdentifierAttribute(elementPolicy, XACML3.ATTRIBUTE_POLICYID, logger) || result;
+ result = DOMUtil.repairVersionAttribute(elementPolicy, XACML3.ATTRIBUTE_VERSION, logger) || result;
+ result = DOMUtil.repairIdentifierAttribute(elementPolicy, XACML3.ATTRIBUTE_RULECOMBININGALGID, XACML3.ID_RULE_DENY_OVERRIDES, logger) || result;
+
+ Identifier identifier = DOMUtil.getIdentifierAttribute(elementPolicy, XACML3.ATTRIBUTE_RULECOMBININGALGID);
+ CombiningAlgorithm<Rule> combiningAlgorithmRule = null;
+ try {
+ combiningAlgorithmRule = CombiningAlgorithmFactory.newInstance().getRuleCombiningAlgorithm(identifier);
+ } catch (FactoryException ex) {
+ combiningAlgorithmRule = null;
+ }
+ if(combiningAlgorithmRule == null) {
+ logger.warn("Setting invalid " + XACML3.ATTRIBUTE_RULECOMBININGALGID + " attribute " + identifier.stringValue() + " to " + XACML3.ID_RULE_DENY_OVERRIDES.stringValue());
+ elementPolicy.setAttribute(XACML3.ATTRIBUTE_RULECOMBININGALGID, XACML3.ID_RULE_DENY_OVERRIDES.stringValue());
+ result = true;
+ }
+ return result;
+ }
+
+ public static void main(String args[]) {
+ try {
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+
+ for (String fileName: args) {
+ File filePolicy = new File(fileName);
+ if (filePolicy.exists() && filePolicy.canRead()) {
+ try {
+ Document documentPolicy = documentBuilder.parse(filePolicy);
+ if (documentPolicy.getFirstChild() == null) {
+ System.err.println(fileName + ": Error: No Policy found");
+ } else if (!XACML3.ELEMENT_POLICY.equals(documentPolicy.getFirstChild().getLocalName())) {
+ System.err.println(fileName + ": Error: Not a Policy documnt");
+ } else {
+ Policy policy = DOMPolicy.newInstance(documentPolicy.getFirstChild(), null, null);
+ System.out.println(fileName + ": validate()=" + policy.validate());
+ System.out.println(StringUtils.prettyPrint(policy.toString()));
+ }
+ } catch (Exception ex) {
+ System.err.println("Exception processing policy file \"" + fileName + "\"");
+ ex.printStackTrace(System.err);
+ }
+ } else {
+ System.err.println("Cannot read policy file \"" + fileName + "\"");
+ }
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace(System.err);
+ System.exit(1);
+ }
+ System.exit(0);
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.java
new file mode 100755
index 0000000..041769f
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.java
@@ -0,0 +1,124 @@
+/*
+ * 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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMAttributeValue;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+import com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter;
+
+/**
+ * DOMPolicyCombinerParameter extends {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter} for
+ * {@link com.att.research.xacmlatt.pdp.policy.Policy}s with methods for creation from DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMPolicyCombinerParameter extends TargetedCombinerParameter<Identifier, PolicySetChild> {
+ private static final Log logger = LogFactory.getLog(DOMPolicyCombinerParameter.class);
+
+ protected DOMPolicyCombinerParameter() {
+
+ }
+
+ /**
+ * Creates a new <code>TargetedCombinerParameter</code> for <code>Policy</code>s by parsing the given <code>Node</code>
+ * representing a XACML PolicyCombinerParameter element.
+ *
+ * @param nodeCombinerParameter the <code>Node</code> representing the XACML PolicyCombinerParameter element
+ * @return a new <code>TargetedCombinerParameter</code> for <code>Policy</code>s parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static TargetedCombinerParameter<Identifier,PolicySetChild> newInstance(Node nodeCombinerParameter) throws DOMStructureException {
+ Element elementPolicyCombinerParameter = DOMUtil.getElement(nodeCombinerParameter);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMPolicyCombinerParameter domPolicyCombinerParameter = new DOMPolicyCombinerParameter();
+
+ try {
+ NodeList children = elementPolicyCombinerParameter.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+ domPolicyCombinerParameter.setAttributeValue(DOMAttributeValue.newInstance(child, null));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeCombinerParameter);
+ }
+ }
+ }
+ }
+ if (domPolicyCombinerParameter.getAttributeValue() == null && !bLenient) {
+ throw DOMUtil.newMissingElementException(nodeCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+ }
+ domPolicyCombinerParameter.setName(DOMUtil.getStringAttribute(elementPolicyCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, !bLenient));
+ domPolicyCombinerParameter.setTargetId(DOMUtil.getIdentifierAttribute(elementPolicyCombinerParameter, XACML3.ATTRIBUTE_POLICYIDREF, !bLenient));
+
+ } catch (DOMStructureException ex) {
+ domPolicyCombinerParameter.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+
+ return domPolicyCombinerParameter;
+
+ }
+ public static boolean repair(Node nodePolicyCombinerParameter) throws DOMStructureException {
+ Element elementPolicyCombinerParameter = DOMUtil.getElement(nodePolicyCombinerParameter);
+ boolean result = false;
+
+ NodeList children = elementPolicyCombinerParameter.getChildNodes();
+ int numChildren;
+ boolean sawAttributeValue = false;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+ if (sawAttributeValue) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicyCombinerParameter.removeChild(child);
+ result = true;
+ } else {
+ sawAttributeValue = true;
+ result = DOMAttributeValue.repair(child) || result;
+ }
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicyCombinerParameter.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+ if (!sawAttributeValue) {
+ throw DOMUtil.newMissingElementException(nodePolicyCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+ }
+ result = DOMUtil.repairStringAttribute(elementPolicyCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, "parameter", logger) || result;
+ result = DOMUtil.repairIdentifierAttribute(elementPolicyCombinerParameter, XACML3.ATTRIBUTE_POLICYIDREF, logger) || result;
+
+ return result;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.java
new file mode 100755
index 0000000..45fbc17
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.java
@@ -0,0 +1,129 @@
+/*
+ * 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.policy.dom;
+
+import java.io.File;
+import java.io.InputStream;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+
+/**
+ * DOMPolicyDef extends {@link com.att.research.xacmlatt.pdp.policy.PolicyDef} with methods for loading them from a <code>File</code>.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public abstract class DOMPolicyDef {
+ protected DOMPolicyDef() {
+ }
+
+ protected static PolicyDef newInstance(Document document, PolicySet policySetParent) throws DOMStructureException {
+ PolicyDef policyDef = null;
+ try {
+ Node rootNode = document.getFirstChild();
+ if (rootNode == null) {
+ throw new Exception("No child in document");
+ }
+
+ if (DOMUtil.isInNamespace(rootNode, XACML3.XMLNS)) {
+ if (XACML3.ELEMENT_POLICY.equals(rootNode.getLocalName())) {
+ policyDef = DOMPolicy.newInstance(rootNode, policySetParent, null);
+ if (policyDef == null) {
+ throw new DOMStructureException("Failed to parse Policy");
+ }
+ } else if (XACML3.ELEMENT_POLICYSET.equals(rootNode.getLocalName())) {
+ policyDef = DOMPolicySet.newInstance(rootNode, policySetParent, null);
+ if (policyDef == null) {
+ throw new DOMStructureException("Failed to parse PolicySet");
+ }
+ } else {
+ throw DOMUtil.newUnexpectedElementException(rootNode);
+ }
+ } else {
+ throw DOMUtil.newUnexpectedElementException(rootNode);
+ }
+ } catch (Exception ex) {
+ throw new DOMStructureException("Exception parsing Policy: " + ex.getMessage(), ex);
+ }
+ return policyDef;
+ }
+
+ public static PolicyDef load(InputStream inputStream) throws DOMStructureException {
+ /*
+ * Get the DocumentBuilderFactory
+ */
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ if (documentBuilderFactory == null) {
+ throw new DOMStructureException("No XML DocumentBuilderFactory configured");
+ }
+ documentBuilderFactory.setNamespaceAware(true);
+
+ /*
+ * Get the DocumentBuilder
+ */
+ DocumentBuilder documentBuilder = null;
+ try {
+ documentBuilder = documentBuilderFactory.newDocumentBuilder();
+ } catch (Exception ex) {
+ throw new DOMStructureException("Exception creating DocumentBuilder: " + ex.getMessage(), ex);
+ }
+
+ /*
+ * Parse the XML file
+ */
+ PolicyDef policyDef = null;
+ try {
+ Document document = documentBuilder.parse(inputStream);
+ if (document == null) {
+ throw new Exception("Null document returned");
+ }
+ policyDef = newInstance(document, null);
+ } catch (Exception ex) {
+ throw new DOMStructureException("Exception loading Policy from input stream: " + ex.getMessage(), ex);
+ }
+ return policyDef;
+ }
+
+ /**
+ * Creates a new <code>PolicyDef</code> derived object by loading the given <code>File</code> containing a XACML 3.0
+ * Policy or PolicySet.
+ *
+ * @param filePolicy the <code>File</code> containing the XACML Policy or PolicySet
+ * @return the newly created <code>PolicyDef</code>
+ * @throws DOMStructureException if there is an error loading the <code>PolicyDef</code>
+ */
+ public static PolicyDef load(File filePolicy) throws DOMStructureException {
+ /*
+ * Parse the XML file
+ */
+ PolicyDef policyDef = null;
+ try {
+ Document document = DOMUtil.loadDocument(filePolicy);
+ if (document == null) {
+ throw new Exception("Null document returned");
+ }
+ policyDef = newInstance(document, null);
+ } catch (Exception ex) {
+ throw new DOMStructureException("Exception loading Policy file \"" + filePolicy.getAbsolutePath() + "\": " + ex.getMessage(), ex);
+ }
+ return policyDef;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.java
new file mode 100755
index 0000000..65a78b1
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.java
@@ -0,0 +1,103 @@
+/*
+ * 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.policy.dom;
+
+import java.net.URI;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+
+/**
+ * DOMPolicyDefaults extends {@link com.att.research.xacmlatt.pdp.policy.PolicyDefaults} with methods for creation from
+ * DOM {@org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMPolicyDefaults extends PolicyDefaults {
+ private static final Log logger = LogFactory.getLog(DOMPolicyDefaults.class);
+
+ protected DOMPolicyDefaults(URI xpathVersionIn, PolicyDefaults policyDefaultsParentIn) {
+ super(xpathVersionIn, policyDefaultsParentIn);
+ }
+
+ /**
+ * Creates a new <code>DOMPolicyDefaults</code> by parsing the given <code>Node</code> representing a XACML PolicyDefaults element.
+ *
+ * @param nodePolicyDefaults the <code>Node</code> representing the PolicyDefaults element.
+ * @param policyDefaultsParent the <code>PolicyDefaults</code> parent for the new <code>DOMPolicyDefaults</code>
+ * @return a new <code>DOMPolicyDefaults</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if the conversion is not possible
+ */
+ public static PolicyDefaults newInstance(Node nodePolicyDefaults, PolicyDefaults policyDefaultsParent) throws DOMStructureException {
+ Element elementPolicyDefaults = DOMUtil.getElement(nodePolicyDefaults);
+ boolean bLenient = DOMProperties.isLenient();
+
+ URI uriXPathVersion = null;
+
+ NodeList children = elementPolicyDefaults.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_XPATHVERSION.equals(child.getLocalName())) {
+ uriXPathVersion = DOMUtil.getURIContent(child);
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicyDefaults);
+ }
+ }
+ }
+ }
+ return new DOMPolicyDefaults(uriXPathVersion, policyDefaultsParent);
+ }
+
+ public static boolean repair(Node nodePolicyDefaults) throws DOMStructureException {
+ Element elementPolicyDefaults = DOMUtil.getElement(nodePolicyDefaults);
+ boolean result = false;
+
+ NodeList children = elementPolicyDefaults.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_XPATHVERSION.equals(child.getLocalName())) {
+ try {
+ DOMUtil.getURIContent(child);
+ } catch (DOMStructureException ex) {
+ logger.warn("Setting invalid " + XACML3.ELEMENT_XPATHVERSION + " attribute " + child.getTextContent() + " to " + XACML.XPATHVERSION_2_0);
+ child.setTextContent(XACML.XPATHVERSION_2_0);
+ result = true;
+ }
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicyDefaults.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.java
new file mode 100755
index 0000000..3aa9870
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.java
@@ -0,0 +1,59 @@
+/*
+ * 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.policy.dom;
+
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMIdReferenceMatch;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacmlatt.pdp.policy.PolicyIdReference;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+
+/**
+ * DOMPolicyIdReference extends {@link com.att.research.xacmlatt.pdp.policy.PolicyIdReference} with methods for creation
+ * from DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMPolicyIdReference {
+
+ protected DOMPolicyIdReference() {
+ }
+
+ /**
+ * Creates a new <code>PolicyIdReference</code> parsed from the given <code>Node</code> representing a XACML PolicyIdReference element.
+ *
+ * @param nodePolicyIdReference the <code>Node</code> representing the XACML PolicyIdReference element
+ * @return a new <code>PolicyIdReference</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static PolicyIdReference newInstance(Node nodePolicyIdReference, PolicySet policySetParent) throws DOMStructureException {
+ PolicyIdReference domPolicyIdReference = new PolicyIdReference(policySetParent);
+
+ try {
+ domPolicyIdReference.setIdReferenceMatch(DOMIdReferenceMatch.newInstance(nodePolicyIdReference));
+ } catch (DOMStructureException ex) {
+ domPolicyIdReference.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+
+ return domPolicyIdReference;
+ }
+
+ public static boolean repair(Node nodePolicyIdReference) throws DOMStructureException {
+ return DOMIdReferenceMatch.repair(nodePolicyIdReference);
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.java
new file mode 100755
index 0000000..d1e4089
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.java
@@ -0,0 +1,126 @@
+/*
+ * 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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMAttribute;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.PolicyIssuer;
+
+/**
+ * DOMPolicyIssuer extends {@link com.att.research.xacmlatt.pdp.policy.PolicyIsser} with methods for creation from
+ * DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMPolicyIssuer extends PolicyIssuer {
+ private static Log logger = LogFactory.getLog(DOMPolicyIssuer.class);
+ private static Identifier identifierCategoryPolicyIssuer = new IdentifierImpl("urn:att:names:tc:xacml:3.0:policy-issuer");
+
+ protected DOMPolicyIssuer() {
+ super();
+ }
+
+ /**
+ * Creates a new <code>DOMPolicyIssuer</code> by parsing the given <code>Node</code> representing a XACML PolicyIssuer element.
+ *
+ * @param nodePolicyIssuer the <code>Node</code> representing the PolicyIssuer element
+ * @return the new <code>DOMPolicyIssuer</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if the conversion is not possible
+ */
+ public static PolicyIssuer newInstance(Node nodePolicyIssuer) throws DOMStructureException {
+ Element elementPolicyIssuer = DOMUtil.getElement(nodePolicyIssuer);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMPolicyIssuer domPolicyIssuer = new DOMPolicyIssuer();
+
+ try {
+ NodeList children = elementPolicyIssuer.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+ String childName = child.getLocalName();
+ if (XACML3.ELEMENT_CONTENT.equals(childName)) {
+ if (domPolicyIssuer.getContent() != null && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicyIssuer);
+ }
+ domPolicyIssuer.setContent(child);
+ } else if (XACML3.ELEMENT_ATTRIBUTE.equals(childName)) {
+ domPolicyIssuer.add(DOMAttribute.newInstance(identifierCategoryPolicyIssuer, child));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicyIssuer);
+ }
+ }
+ }
+ }
+ }
+ } catch (DOMStructureException ex) {
+ domPolicyIssuer.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+
+ return domPolicyIssuer;
+ }
+
+ public static boolean repair(Node nodePolicyIssuer) throws DOMStructureException {
+ Element elementPolicyIssuer = DOMUtil.getElement(nodePolicyIssuer);
+ boolean result = false;
+
+ boolean sawContent = false;
+ NodeList children = elementPolicyIssuer.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+ String childName = child.getLocalName();
+ if (XACML3.ELEMENT_CONTENT.equals(childName)) {
+ if (sawContent) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicyIssuer.removeChild(child);
+ result = true;
+ } else {
+ sawContent = true;
+ }
+ } else if (XACML3.ELEMENT_ATTRIBUTE.equals(childName)) {
+ result = DOMAttribute.repair(child) || result;
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicyIssuer.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.java
new file mode 100755
index 0000000..20cff15
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.java
@@ -0,0 +1,113 @@
+/*
+ * 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.policy.dom;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.dom.DOMUtil;
+
+/**
+ * DOMPolicyRepair is an application for reading a XACML Policy or PolicySet document and ensuring it has the required attributes and then writing
+ * the repaired Policy or PolicySet to an output file.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class DOMPolicyRepair {
+ private static final String DEFAULT_VERSION = "1.0";
+
+ public static void main(String[] args) {
+ InputStream inputStream = System.in;
+ OutputStream outputStream = System.out;
+
+ for (int i = 0 ; i < args.length ; ) {
+ if (args[i].equals("-i")) {
+ if (i+1 < args.length) {
+ try {
+ inputStream = new FileInputStream(args[i+1]);
+ } catch (IOException ex) {
+ System.err.println("IOException opening \"" + args[i+1] + "\" for reading.");
+ System.exit(1);
+ }
+ i += 2;
+ } else {
+ i++;
+ }
+ } else if (args[i].equals("-o")) {
+ if (i+1 < args.length){
+ try {
+ outputStream = new FileOutputStream(args[i+1]);
+ } catch (IOException ex) {
+ System.err.println("IOException opening \"" + args[i+1] + "\" for writing.");
+ ex.printStackTrace(System.err);
+ System.exit(1);;
+ }
+ i += 2;
+ } else {
+ i++;
+ }
+ } else {
+ System.err.println("Unrecognized command line option \"" + args[i] + "\"");
+ System.exit(1);
+ }
+ }
+
+ /*
+ * Get the XML Parser for the input file
+ */
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ try {
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+ Document documentInput = documentBuilder.parse(inputStream);
+ Element elementRoot = DOMUtil.getFirstChildElement(documentInput);
+ if (elementRoot == null) {
+ System.err.println("No root element");
+ System.exit(1);
+ } else if (!XACML3.ELEMENT_POLICY.equals(elementRoot.getLocalName()) && !XACML3.ELEMENT_POLICYSET.equals(elementRoot.getLocalName())) {
+ System.err.println("Root element is not a Policy or PolicySet");
+ System.exit(1);
+ }
+
+ /*
+ * Make sure there is a Version attribute
+ */
+ Node nodeVersion = DOMUtil.getAttribute(elementRoot, XACML3.ATTRIBUTE_VERSION);
+ if (nodeVersion == null) {
+ System.out.println("Adding Version attribute with value \"" + DEFAULT_VERSION + "\"");
+ elementRoot.setAttribute(XACML3.ATTRIBUTE_VERSION, DEFAULT_VERSION);
+ }
+
+ /*
+ * Write out the updated document
+ */
+ String newDocument = DOMUtil.toString(documentInput);
+ outputStream.write(newDocument.getBytes());
+ } catch (Exception ex) {
+ ex.printStackTrace(System.err);
+ System.exit(1);
+ }
+ System.exit(0);
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.java
new file mode 100755
index 0000000..c69a921
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.java
@@ -0,0 +1,349 @@
+/*
+ * 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.policy.dom;
+
+import java.io.File;
+import java.util.Iterator;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.StringUtils;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+
+/**
+ * DOMPolicySet extends {@link com.att.research.xacmlatt.pdp.policy.PolicySet} with methods for creation
+ * from DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.4 $
+ */
+public class DOMPolicySet {
+ private static final Log logger = LogFactory.getLog(DOMPolicySet.class);
+
+ protected DOMPolicySet() {
+ }
+
+ /**
+ * Creates a new <code>PolicySet</code> by parsing the given <code>Node</code> representing a XACML PolicySet element.
+ *
+ * @param nodePolicySet the <code>Node</code> representing the XACML PolicySetelement
+ * @param policyDefaultsParent the {@link com.att.research.xacmlatt.pdp.policy.PolicyDefaults} from the parent element
+ * @return a new <code>PolicySet</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static PolicySet newInstance(Node nodePolicySet, PolicySet policySetParent, PolicyDefaults policyDefaultsParent) throws DOMStructureException {
+ Element elementPolicySet = DOMUtil.getElement(nodePolicySet);
+ boolean bLenient = DOMProperties.isLenient();
+
+ PolicySet domPolicySet = new PolicySet(policySetParent);
+
+ Iterator<?> iterator;
+ Identifier identifier;
+ Integer integer;
+
+ try {
+ NodeList children = elementPolicySet.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ /*
+ * Run through once, quickly, to set the PolicyDefaults for the new DOMPolicySet
+ */
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isNamespaceElement(child, XACML3.XMLNS) && XACML3.ELEMENT_POLICYDEFAULTS.equals(child.getLocalName())) {
+ if (domPolicySet.getPolicyDefaults() != null && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+ }
+ domPolicySet.setPolicyDefaults(DOMPolicyDefaults.newInstance(child, policyDefaultsParent));
+ }
+ }
+ if (domPolicySet.getPolicyDefaults() == null) {
+ domPolicySet.setPolicyDefaults(policyDefaultsParent);
+ }
+
+ /*
+ * Now process the other elements so we can pull up the parent policy defaults
+ */
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+ String childName = child.getLocalName();
+ if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+ if (domPolicySet.getDescription() != null && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+ }
+ domPolicySet.setDescription(child.getTextContent());
+ } else if (XACML3.ELEMENT_POLICYISSUER.equals(childName)) {
+ if (domPolicySet.getPolicyIssuer() != null && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+ }
+ domPolicySet.setPolicyIssuer(DOMPolicyIssuer.newInstance(child));
+ } else if (XACML3.ELEMENT_POLICYSETDEFAULTS.equals(childName)) {
+ } else if (XACML3.ELEMENT_TARGET.equals(childName)) {
+ if (domPolicySet.getTarget() != null && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+ }
+ domPolicySet.setTarget(DOMTarget.newInstance(child));
+ } else if (XACML3.ELEMENT_POLICYSET.equals(childName)) {
+ domPolicySet.addChild(DOMPolicySet.newInstance(child, domPolicySet, domPolicySet.getPolicyDefaults()));
+ } else if (XACML3.ELEMENT_POLICY.equals(childName)) {
+ domPolicySet.addChild(DOMPolicy.newInstance(child, domPolicySet, domPolicySet.getPolicyDefaults()));
+ } else if (XACML3.ELEMENT_POLICYIDREFERENCE.equals(childName)) {
+ domPolicySet.addChild(DOMPolicyIdReference.newInstance(child, domPolicySet));
+ } else if (XACML3.ELEMENT_POLICYSETIDREFERENCE.equals(childName)) {
+ domPolicySet.addChild(DOMPolicySetIdReference.newInstance(child, domPolicySet));
+ } else if (XACML3.ELEMENT_COMBINERPARAMETERS.equals(childName)) {
+ domPolicySet.addCombinerParameters(DOMCombinerParameter.newList(child));
+ } else if (XACML3.ELEMENT_POLICYCOMBINERPARAMETERS.equals(childName)) {
+ domPolicySet.addPolicyCombinerParameter(DOMPolicyCombinerParameter.newInstance(child));
+ } else if (XACML3.ELEMENT_POLICYSETCOMBINERPARAMETERS.equals(childName)) {
+ domPolicySet.addPolicyCombinerParameter(DOMPolicySetCombinerParameter.newInstance(child));
+ } else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) {
+ if ((iterator = domPolicySet.getObligationExpressions()) != null && iterator.hasNext() && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+ }
+ domPolicySet.setObligationExpressions(DOMObligationExpression.newList(child, null));
+ } else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) {
+ if ((iterator = domPolicySet.getAdviceExpressions()) != null && iterator.hasNext() && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+ }
+ domPolicySet.setAdviceExpressions(DOMAdviceExpression.newList(child, null));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+ }
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodePolicySet);
+ }
+ }
+ }
+ }
+ if (domPolicySet.getTarget() == null && !bLenient) {
+ throw DOMUtil.newMissingElementException(nodePolicySet, XACML3.XMLNS, XACML3.ELEMENT_TARGET);
+ }
+
+ /*
+ * Get the attributes
+ */
+ domPolicySet.setIdentifier(DOMUtil.getIdentifierAttribute(elementPolicySet, XACML3.ATTRIBUTE_POLICYSETID, !bLenient));
+ domPolicySet.setVersion(DOMUtil.getVersionAttribute(elementPolicySet, XACML3.ATTRIBUTE_VERSION, !bLenient));
+
+ identifier = DOMUtil.getIdentifierAttribute(elementPolicySet, XACML3.ATTRIBUTE_POLICYCOMBININGALGID, !bLenient);
+ CombiningAlgorithm<PolicySetChild> combiningAlgorithm = null;
+ try {
+ combiningAlgorithm = CombiningAlgorithmFactory.newInstance().getPolicyCombiningAlgorithm(identifier);
+ } catch (FactoryException ex) {
+ if (!bLenient) {
+ throw new DOMStructureException("Failed to get CombinginAlgorithm", ex);
+ }
+ }
+ if (combiningAlgorithm == null && !bLenient) {
+ throw new DOMStructureException(elementPolicySet, "Unknown policy combining algorithm \"" + identifier.toString() + "\" in \"" + DOMUtil.getNodeLabel(nodePolicySet));
+ } else {
+ domPolicySet.setPolicyCombiningAlgorithm(combiningAlgorithm);
+ }
+
+ if ((integer = DOMUtil.getIntegerAttribute(elementPolicySet, XACML3.ATTRIBUTE_MAXDELEGATIONDEPTH)) != null) {
+ domPolicySet.setMaxDelegationDepth(integer);
+ }
+ } catch (DOMStructureException ex) {
+ domPolicySet.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+
+ return domPolicySet;
+ }
+
+ public static boolean repair(Node nodePolicySet) throws DOMStructureException {
+ Element elementPolicySet = DOMUtil.getElement(nodePolicySet);
+ boolean result = false;
+
+ NodeList children = elementPolicySet.getChildNodes();
+ int numChildren;
+ boolean sawDescription = false;
+ boolean sawPolicyIssuer = false;
+ boolean sawPolicyDefaults = false;
+ boolean sawTarget = false;
+ boolean sawObligationExprs = false;
+ boolean sawAdviceExprs = false;
+
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ /*
+ * Now process the other elements so we can pull up the parent policy defaults
+ */
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+ String childName = child.getLocalName();
+ if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+ if (sawDescription) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicySet.removeChild(child);
+ result = true;
+ } else {
+ sawDescription = true;
+ }
+ } else if (XACML3.ELEMENT_POLICYISSUER.equals(childName)) {
+ if (sawPolicyIssuer) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicySet.removeChild(child);
+ result = true;
+ } else {
+ sawPolicyIssuer = true;
+ result = DOMPolicyIssuer.repair(child) || result;
+ }
+ } else if (XACML3.ELEMENT_POLICYSETDEFAULTS.equals(childName)) {
+ if (sawPolicyDefaults) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicySet.removeChild(child);
+ result = true;
+ } else {
+ sawPolicyDefaults = true;
+ result = DOMPolicyDefaults.repair(child) || result;
+ }
+ } else if (XACML3.ELEMENT_TARGET.equals(childName)) {
+ if (sawTarget) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicySet.removeChild(child);
+ result = true;
+ } else {
+ sawTarget = true;
+ result = DOMTarget.repair(child) || result;
+ }
+ } else if (XACML3.ELEMENT_POLICYSET.equals(childName)) {
+ result = DOMPolicySet.repair(child) || result;
+ } else if (XACML3.ELEMENT_POLICY.equals(childName)) {
+ result = DOMPolicy.repair(child) || result;
+ } else if (XACML3.ELEMENT_POLICYIDREFERENCE.equals(childName)) {
+ result = DOMPolicyIdReference.repair(child) || result;
+ } else if (XACML3.ELEMENT_POLICYSETIDREFERENCE.equals(childName)) {
+ result = DOMPolicySetIdReference.repair(child) || result;
+ } else if (XACML3.ELEMENT_COMBINERPARAMETERS.equals(childName)) {
+ result = DOMCombinerParameter.repair(child) || result;
+ } else if (XACML3.ELEMENT_POLICYCOMBINERPARAMETERS.equals(childName)) {
+ result = DOMPolicyCombinerParameter.repair(child) || result;
+ } else if (XACML3.ELEMENT_POLICYSETCOMBINERPARAMETERS.equals(childName)) {
+ result = DOMPolicySetCombinerParameter.repair(child) || result;
+ } else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) {
+ if (sawObligationExprs) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicySet.removeChild(child);
+ result = true;
+ } else {
+ sawObligationExprs = true;
+ result = DOMObligationExpression.repairList(child) || result;
+ }
+ } else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) {
+ if (sawAdviceExprs) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicySet.removeChild(child);
+ result = true;
+ } else {
+ sawAdviceExprs = true;
+ result = DOMAdviceExpression.repairList(child) || result;
+ }
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicySet.removeChild(child);
+ result = true;
+ }
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicySet.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+ if (!sawTarget) {
+ throw DOMUtil.newMissingElementException(nodePolicySet, XACML3.XMLNS, XACML3.ELEMENT_TARGET);
+ }
+
+ /*
+ * Get the attributes
+ */
+ result = DOMUtil.repairIdentifierAttribute(elementPolicySet, XACML3.ATTRIBUTE_POLICYSETID, logger) || result;
+ result = DOMUtil.repairVersionAttribute(elementPolicySet, XACML3.ATTRIBUTE_VERSION, logger) || result;
+ result = DOMUtil.repairIdentifierAttribute(elementPolicySet, XACML3.ATTRIBUTE_POLICYCOMBININGALGID, XACML3.ID_POLICY_DENY_OVERRIDES, logger) || result;
+
+ Identifier identifier = DOMUtil.getIdentifierAttribute(elementPolicySet, XACML3.ATTRIBUTE_POLICYCOMBININGALGID);
+ CombiningAlgorithm<PolicySetChild> combiningAlgorithm = null;
+ try {
+ combiningAlgorithm = CombiningAlgorithmFactory.newInstance().getPolicyCombiningAlgorithm(identifier);
+ } catch (FactoryException ex) {
+ combiningAlgorithm = null;
+ }
+ if (combiningAlgorithm == null) {
+ logger.warn("Setting invalid " + XACML3.ATTRIBUTE_POLICYCOMBININGALGID + " attribute " + identifier.stringValue() + " to " + XACML3.ID_POLICY_DENY_OVERRIDES.stringValue());
+ elementPolicySet.setAttribute(XACML3.ATTRIBUTE_POLICYCOMBININGALGID, XACML3.ID_POLICY_DENY_OVERRIDES.stringValue());
+ result = true;
+ }
+
+ return result;
+ }
+
+ public static void main(String args[]) {
+ try {
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+
+ for (String fileName: args) {
+ File filePolicy = new File(fileName);
+ if (filePolicy.exists() && filePolicy.canRead()) {
+ try {
+ Document documentPolicy = documentBuilder.parse(filePolicy);
+ if (documentPolicy.getFirstChild() == null) {
+ System.err.println(fileName + ": Error: No PolicySet found");
+ } else if (!XACML3.ELEMENT_POLICYSET.equals(documentPolicy.getFirstChild().getLocalName())) {
+ System.err.println(fileName + ": Error: Not a PolicySet document");
+ } else {
+ PolicySet policySet = DOMPolicySet.newInstance(documentPolicy.getFirstChild(), null, null);
+ System.out.println(fileName + ": validate()=" + policySet.validate());
+ System.out.println(StringUtils.prettyPrint(policySet.toString()));
+ }
+ } catch (Exception ex) {
+ System.err.println("Exception processing policy set file \"" + fileName + "\"");
+ ex.printStackTrace(System.err);
+ }
+ } else {
+ System.err.println("Cannot read policy set file \"" + fileName + "\"");
+ }
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace(System.err);
+ System.exit(1);
+ }
+ System.exit(0);
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.java
new file mode 100755
index 0000000..42d856c
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.java
@@ -0,0 +1,126 @@
+/*
+ * 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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMAttributeValue;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+import com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter;
+
+/**
+ * DOMPolicySetCombinerParameter extends {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter} for
+ * {@link com.att.research.xacmlatt.pdp.policy.PolicySet}s with methods for creation from DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMPolicySetCombinerParameter extends TargetedCombinerParameter<Identifier, PolicySetChild> {
+ public static final Log logger = LogFactory.getLog(DOMPolicySetCombinerParameter.class);
+
+ protected DOMPolicySetCombinerParameter() {
+
+ }
+
+ /**
+ * Creates a new <code>TargetedCombinerParameter</code> for <code>PolicySet</code>s by parsing the given <code>Node</code>
+ * representing a XACML PolicySetCombinerParameter element.
+ *
+ * @param nodeCombinerParameter the <code>Node</code> representing the XACML PolicySetCombinerParameter element
+ * @return a new <code>TargetedCombinerParameter</code> for <code>PolicySet</code>s parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static TargetedCombinerParameter<Identifier,PolicySetChild> newInstance(Node nodeCombinerParameter) throws DOMStructureException {
+ Element elementPolicySetCombinerParameter = DOMUtil.getElement(nodeCombinerParameter);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMPolicySetCombinerParameter domPolicySetCombinerParameter = new DOMPolicySetCombinerParameter();
+
+ try {
+ NodeList children = elementPolicySetCombinerParameter.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+ if (domPolicySetCombinerParameter.getAttributeValue() != null && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeCombinerParameter);
+ }
+ domPolicySetCombinerParameter.setAttributeValue(DOMAttributeValue.newInstance(child, null));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeCombinerParameter);
+ }
+ }
+ }
+ }
+ if (domPolicySetCombinerParameter.getAttributeValue() == null && !bLenient) {
+ throw DOMUtil.newMissingElementException(elementPolicySetCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+ }
+ domPolicySetCombinerParameter.setName(DOMUtil.getStringAttribute(elementPolicySetCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, !bLenient));
+ domPolicySetCombinerParameter.setTargetId(DOMUtil.getIdentifierAttribute(elementPolicySetCombinerParameter, XACML3.ATTRIBUTE_POLICYSETIDREF, !bLenient));
+ } catch (DOMStructureException ex) {
+ domPolicySetCombinerParameter.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+
+ return domPolicySetCombinerParameter;
+
+ }
+
+ public static boolean repair(Node nodeCombinerParameter) throws DOMStructureException {
+ Element elementPolicySetCombinerParameter = DOMUtil.getElement(nodeCombinerParameter);
+ boolean result = false;
+
+ NodeList children = elementPolicySetCombinerParameter.getChildNodes();
+ int numChildren;
+ boolean sawAttributeValue = false;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+ if (sawAttributeValue) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicySetCombinerParameter.removeChild(child);
+ result = true;
+ } else {
+ sawAttributeValue = true;
+ result = DOMAttributeValue.repair(child) || result;
+ }
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementPolicySetCombinerParameter.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+ if (!sawAttributeValue) {
+ throw DOMUtil.newMissingElementException(elementPolicySetCombinerParameter, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+ }
+ result = DOMUtil.repairStringAttribute(elementPolicySetCombinerParameter, XACML3.ATTRIBUTE_PARAMETERNAME, "parameter", logger) || result;
+ result = DOMUtil.repairIdentifierAttribute(elementPolicySetCombinerParameter, XACML3.ATTRIBUTE_POLICYSETIDREF, logger) || result;
+ return result;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.java
new file mode 100755
index 0000000..0f45c43
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.java
@@ -0,0 +1,58 @@
+/*
+ * 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.policy.dom;
+
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMIdReferenceMatch;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+import com.att.research.xacmlatt.pdp.policy.PolicySetIdReference;
+
+/**
+ * DOMPolicySetIdReference extends {@link com.att.research.xacmlatt.pdp.policy.PolicySetIdReference} with methods for creation
+ * from DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMPolicySetIdReference {
+ protected DOMPolicySetIdReference() {
+ }
+
+ /**
+ * Creates a new <code>PolicySetIdReference</code> parsed from the given <code>Node</code> representing a XACML PolicySetIdReference element.
+ *
+ * @param nodePolicySetIdReference the <code>Node</code> representing the XACML PolicySetIdReference element
+ * @return a new <code>PolicySetIdReference</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static PolicySetIdReference newInstance(Node nodePolicySetIdReference, PolicySet policySetParent) throws DOMStructureException {
+ PolicySetIdReference domPolicySetIdReference = new PolicySetIdReference(policySetParent);
+
+ try {
+ domPolicySetIdReference.setIdReferenceMatch(DOMIdReferenceMatch.newInstance(nodePolicySetIdReference));
+ } catch (DOMStructureException ex) {
+ domPolicySetIdReference.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+
+ return domPolicySetIdReference;
+ }
+
+ public static boolean repair(Node nodePolicySetIdReference) throws DOMStructureException {
+ return DOMIdReferenceMatch.repair(nodePolicySetIdReference);
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.java
new file mode 100755
index 0000000..102f546
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.java
@@ -0,0 +1,221 @@
+/*
+ * 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.policy.dom;
+
+import java.util.Iterator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.Condition;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.Rule;
+import com.att.research.xacmlatt.pdp.policy.RuleEffect;
+
+/**
+ * DOMRule extends {@link com.att.research.xacmlatt.pdp.policy.Rule} with methods for creation from
+ * DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class DOMRule extends Rule {
+ private static final Log logger = LogFactory.getLog(DOMRule.class);
+
+ protected DOMRule() {
+ }
+
+ /**
+ * Creates a new <code>Rule</code> by parsing the given <code>Node</code> representing a XACML Rule element.
+ *
+ * @param nodeRule the <code>Node</code> representing the XACML Rule element
+ * @param policy the {@link com.att.research.xacmlatt.pdp.policy.Policy} encompassing the Rule element
+ * @return a new <code>Rule</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static Rule newInstance(Node nodeRule, Policy policy) throws DOMStructureException {
+ Element elementRule = DOMUtil.getElement(nodeRule);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMRule domRule = new DOMRule();
+
+ domRule.setPolicy(policy);
+
+ Iterator<?> iterator;
+
+ try {
+ NodeList children = elementRule.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+ String childName = child.getLocalName();
+ if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+ if (domRule.getDescription() != null && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeRule);
+ }
+ domRule.setDescription(child.getTextContent());
+ } else if (XACML3.ELEMENT_TARGET.equals(childName)) {
+ if (domRule.getTarget() != null && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeRule);
+ }
+ domRule.setTarget(DOMTarget.newInstance(child));
+ } else if (XACML3.ELEMENT_CONDITION.equals(childName)) {
+ if (domRule.getCondition() != null && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeRule);
+ }
+ Node nodeExpression = DOMUtil.getFirstChildElement(child);
+ if (nodeExpression == null && !bLenient) {
+ throw DOMUtil.newMissingElementException(child, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION);
+ }
+ domRule.setCondition(new Condition(DOMExpression.newInstance(nodeExpression, policy)));
+ } else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) {
+ if ((iterator = domRule.getObligationExpressions()) != null && iterator.hasNext() && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeRule);
+ }
+ domRule.setObligationExpressions(DOMObligationExpression.newList(child, policy));
+ } else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) {
+ if ((iterator = domRule.getAdviceExpressions()) != null && iterator.hasNext() && !bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeRule);
+ }
+ domRule.setAdviceExpressions(DOMAdviceExpression.newList(child, policy));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeRule);
+ }
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeRule);
+ }
+ }
+ }
+ }
+
+ domRule.setRuleId(DOMUtil.getStringAttribute(elementRule, XACML3.ATTRIBUTE_RULEID, !bLenient));
+ String string = DOMUtil.getStringAttribute(elementRule, XACML3.ATTRIBUTE_EFFECT, !bLenient);
+ RuleEffect ruleEffect = RuleEffect.getRuleEffect(string);
+ if (ruleEffect == null && !bLenient) {
+ throw new DOMStructureException(elementRule, "Unknown RuleEffect \"" + string + "\" in \"" + DOMUtil.getNodeLabel(nodeRule) + "\"");
+ }
+ domRule.setRuleEffect(ruleEffect);
+
+ } catch (DOMStructureException ex) {
+ domRule.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+ return domRule;
+ }
+
+ public static boolean repair(Node nodeRule) throws DOMStructureException {
+ Element elementRule = DOMUtil.getElement(nodeRule);
+ boolean result = false;
+
+ NodeList children = elementRule.getChildNodes();
+ int numChildren;
+ boolean sawDescription = false;
+ boolean sawTarget = false;
+ boolean sawCondition = false;
+ boolean sawObligationExpressions = false;
+ boolean sawAdviceExpressions = false;
+
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS)) {
+ String childName = child.getLocalName();
+ if (XACML3.ELEMENT_DESCRIPTION.equals(childName)) {
+ if (sawDescription) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementRule.removeChild(child);
+ result = true;
+ } else {
+ sawDescription = true;
+ }
+ } else if (XACML3.ELEMENT_TARGET.equals(childName)) {
+ if (sawTarget) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementRule.removeChild(child);
+ result = true;
+ } else {
+ sawTarget = true;
+ result = DOMTarget.repair(child) || result;
+ }
+ } else if (XACML3.ELEMENT_CONDITION.equals(childName)) {
+ if (sawCondition) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementRule.removeChild(child);
+ result = true;
+ } else {
+ sawCondition = true;
+ Node nodeExpression = DOMUtil.getFirstChildElement(child);
+ if (nodeExpression == null) {
+ throw DOMUtil.newMissingElementException(child, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION);
+ }
+ result = DOMExpression.repair(nodeExpression) || result;
+ }
+ } else if (XACML3.ELEMENT_OBLIGATIONEXPRESSIONS.equals(childName)) {
+ if (sawObligationExpressions) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementRule.removeChild(child);
+ result = true;
+ } else {
+ sawObligationExpressions = true;
+ result = DOMObligationExpression.repairList(child) || result;
+ }
+ } else if (XACML3.ELEMENT_ADVICEEXPRESSIONS.equals(childName)) {
+ if (sawAdviceExpressions) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementRule.removeChild(child);
+ result = true;
+ } else {
+ sawAdviceExpressions = true;
+ result = DOMAdviceExpression.repairList(child) || result;
+ }
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementRule.removeChild(child);
+ result = true;
+ }
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementRule.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+
+ result = DOMUtil.repairStringAttribute(elementRule, XACML3.ATTRIBUTE_RULEID, IdentifierImpl.gensym().stringValue(), logger) || result;
+ result = DOMUtil.repairStringAttribute(elementRule, XACML3.ATTRIBUTE_EFFECT, RuleEffect.DENY.getName(), logger) || result;
+
+ String string = DOMUtil.getStringAttribute(elementRule, XACML3.ATTRIBUTE_EFFECT);
+ RuleEffect ruleEffect = RuleEffect.getRuleEffect(string);
+ if (ruleEffect == null) {
+ logger.warn("Setting invalid " + XACML3.ATTRIBUTE_EFFECT + " attribute " + string + " to " + RuleEffect.DENY.getName());
+ elementRule.setAttribute(XACML3.ATTRIBUTE_EFFECT, RuleEffect.DENY.getName());
+ result = true;
+ }
+
+ return result;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.java
new file mode 100755
index 0000000..732c8b5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.java
@@ -0,0 +1,123 @@
+/*
+ * 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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMAttributeValue;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.Rule;
+import com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter;
+
+/**
+ * DOMRuleCombinerParameters extends {@link com.att.research.xacmlatt.pdp.policy.TargetedCombinerParameter} with methods
+ * for creation from DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMRuleCombinerParameters extends TargetedCombinerParameter<String,Rule> {
+ private static final Log logger = LogFactory.getLog(DOMRuleCombinerParameters.class);
+
+ protected DOMRuleCombinerParameters() {
+ }
+
+ /**
+ * Creates a new <code>TargetedCombinerParameter</code> for {@link com.att.research.xacmlatt.pdp.policy.Rule}s by parsing the
+ * given <code>Node</code> representing a XACML RuleCombinerParameters element.
+ *
+ * @param nodeRuleCombinerParameters the <code>Node</code> representing the XACML RuleCombinerParameters element.
+ * @return a new <code>TargetedCombinerParameter</code> for <code>Rule</code>s parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>.
+ */
+ public static TargetedCombinerParameter<String,Rule> newInstance(Node nodeRuleCombinerParameters) throws DOMStructureException {
+ Element elementRuleCombinerParameters = DOMUtil.getElement(nodeRuleCombinerParameters);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMRuleCombinerParameters domRuleCombinerParameters = new DOMRuleCombinerParameters();
+
+ try {
+ NodeList children = elementRuleCombinerParameters.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+ if (domRuleCombinerParameters.getAttributeValue() != null) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeRuleCombinerParameters);
+ }
+ domRuleCombinerParameters.setAttributeValue(DOMAttributeValue.newInstance(child, null));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeRuleCombinerParameters);
+ }
+ }
+ }
+ }
+ if (domRuleCombinerParameters.getAttributeValue() == null && !bLenient) {
+ throw DOMUtil.newMissingElementException(nodeRuleCombinerParameters, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+ }
+ domRuleCombinerParameters.setName(DOMUtil.getStringAttribute(elementRuleCombinerParameters, XACML3.ATTRIBUTE_PARAMETERNAME, !bLenient));
+ domRuleCombinerParameters.setTargetId(DOMUtil.getStringAttribute(elementRuleCombinerParameters, XACML3.ATTRIBUTE_RULEIDREF, !bLenient));
+ } catch (DOMStructureException ex) {
+ domRuleCombinerParameters.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+ return domRuleCombinerParameters;
+ }
+
+ public static boolean repair(Node nodeRuleCombinerParameters) throws DOMStructureException {
+ Element elementRuleCombinerParameters = DOMUtil.getElement(nodeRuleCombinerParameters);
+ boolean result = false;
+
+ NodeList children = elementRuleCombinerParameters.getChildNodes();
+ int numChildren;
+ boolean sawAttributeValue = false;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ATTRIBUTEVALUE.equals(child.getLocalName())) {
+ if (sawAttributeValue) {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementRuleCombinerParameters.removeChild(child);
+ result = true;
+ } else {
+ sawAttributeValue = true;
+ result = result || DOMAttributeValue.repair(child);
+ }
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementRuleCombinerParameters.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+ if (!sawAttributeValue) {
+ throw DOMUtil.newMissingElementException(nodeRuleCombinerParameters, XACML3.XMLNS, XACML3.ELEMENT_ATTRIBUTEVALUE);
+ }
+ result = result || DOMUtil.repairStringAttribute(elementRuleCombinerParameters, XACML3.ATTRIBUTE_PARAMETERNAME, "parameter", logger);
+ result = result || DOMUtil.repairIdentifierAttribute(elementRuleCombinerParameters, XACML3.ATTRIBUTE_RULEIDREF, logger);
+
+ return result;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.java
new file mode 100755
index 0000000..599dfa5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.java
@@ -0,0 +1,102 @@
+/*
+ * 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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.Target;
+
+/**
+ * DOMTarget extends {@link com.att.research.xacmlatt.pdp.policy.Target} with methods for creation from
+ * DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class DOMTarget extends Target {
+ private static final Log logger = LogFactory.getLog(DOMTarget.class);
+
+ /**
+ * Creates an empty <code>DOMTarget</code>.
+ */
+ protected DOMTarget() {
+ }
+
+ /**
+ * Creates a new <code>DOMTarget</code> by parsing the given <code>Node</code> representing a XACML Target element.
+ *
+ * @param nodeTarget the <code>Node</code> representing the XACML Target element
+ * @return a new <code>DOMTarget</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static Target newInstance(Node nodeTarget) throws DOMStructureException {
+ Element elementTarget = DOMUtil.getElement(nodeTarget);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMTarget domTarget = new DOMTarget();
+ try {
+ NodeList children = elementTarget.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ANYOF.equals(child.getLocalName())) {
+ domTarget.addAnyOf(DOMAnyOf.newInstance(child));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(child, nodeTarget);
+ }
+ }
+ }
+ }
+ } catch (DOMStructureException ex) {
+ domTarget.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+
+ return domTarget;
+ }
+
+ public static boolean repair(Node nodeTarget) throws DOMStructureException {
+ Element elementTarget = DOMUtil.getElement(nodeTarget);
+ boolean result = false;
+
+ NodeList children = elementTarget.getChildNodes();
+ int numChildren;
+ if (children != null && (numChildren = children.getLength()) > 0) {
+ for (int i = 0 ; i < numChildren ; i++) {
+ Node child = children.item(i);
+ if (DOMUtil.isElement(child)) {
+ if (DOMUtil.isInNamespace(child, XACML3.XMLNS) && XACML3.ELEMENT_ANYOF.equals(child.getLocalName())) {
+ result = DOMAnyOf.repair(child) || result;
+ } else {
+ logger.warn("Unexpected element " + child.getNodeName());
+ elementTarget.removeChild(child);
+ result = true;
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.java
new file mode 100755
index 0000000..d1d32f3
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.java
@@ -0,0 +1,94 @@
+/*
+ * 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.policy.dom;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.VariableDefinition;
+
+/**
+ * DOMVariableDefinition extends {@link com.att.research.xacmlatt.pdp.policy.VariableDefinition} with methods
+ * for creation from DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class DOMVariableDefinition extends VariableDefinition {
+ private static final Log logger = LogFactory.getLog(DOMVariableDefinition.class);
+
+ protected DOMVariableDefinition() {
+ }
+
+ /**
+ * Creates a new <code>VariableDefinition</code> by parsing the given <code>Node</code> representing a XACML VariableDefinition element.
+ *
+ * @param nodeVariableDefinition the <code>Node</code> representing the XACML VariableDefinition element
+ * @param policy the <code>Policy</code> encompassing the VariableDefinition element
+ * @return a new <code>VariableDefinition</code> parsed from the given <code>Node</code>
+ * @throws DOMStructureException if there is an error parsing the <code>Node</code>
+ */
+ public static VariableDefinition newInstance(Node nodeVariableDefinition, Policy policy) throws DOMStructureException {
+ Element elementVariableDefinition = DOMUtil.getElement(nodeVariableDefinition);
+ boolean bLenient = DOMProperties.isLenient();
+
+ DOMVariableDefinition domVariableDefinition = new DOMVariableDefinition();
+
+ try {
+ Element elementExpression = DOMUtil.getFirstChildElement(elementVariableDefinition);
+ if (elementExpression != null) {
+ if (DOMExpression.isExpression(elementExpression)) {
+ domVariableDefinition.setExpression(DOMExpression.newInstance(elementExpression, policy));
+ } else if (!bLenient) {
+ throw DOMUtil.newUnexpectedElementException(elementExpression, elementVariableDefinition);
+ }
+ } else if (!bLenient) {
+ throw DOMUtil.newMissingElementException(elementVariableDefinition, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION);
+ }
+ domVariableDefinition.setId(DOMUtil.getStringAttribute(elementVariableDefinition, XACML3.ATTRIBUTE_VARIABLEID, !bLenient));
+ } catch (DOMStructureException ex) {
+ domVariableDefinition.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ if (DOMProperties.throwsExceptions()) {
+ throw ex;
+ }
+ }
+ return domVariableDefinition;
+ }
+
+ public static boolean repair(Node nodeVariableDefinition) throws DOMStructureException {
+ Element elementVariableDefinition = DOMUtil.getElement(nodeVariableDefinition);
+ boolean result = false;
+
+ Element elementExpression = DOMUtil.getFirstChildElement(elementVariableDefinition);
+ if (elementExpression != null) {
+ if (DOMExpression.isExpression(elementExpression)) {
+ result = result || DOMExpression.repair(elementExpression);
+ } else {
+ logger.warn("Unexpected element " + elementExpression.getNodeName());
+ elementVariableDefinition.removeChild(elementExpression);
+ result = true;
+ }
+ } else {
+ throw DOMUtil.newMissingElementException(elementVariableDefinition, XACML3.XMLNS, XACML3.ELEMENT_EXPRESSION);
+ }
+
+ result = result || DOMUtil.repairStringAttribute(elementVariableDefinition, XACML3.ATTRIBUTE_VARIABLEID, "variable", logger);
+ return result;
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/package-info.java
new file mode 100755
index 0000000..f42ce1e
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.policy.dom;
+
+/**
+ * com.att.research.xacmlatt.pdp.policy.dom contains class definitions that extend {@link com.att.research.xacmlatt.pdp.policy} classes
+ * with methods for creation from DOM {@link org.w3c.dom.Node}s.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Apply.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Apply.java
new file mode 100755
index 0000000..08064fd
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Apply.java
@@ -0,0 +1,170 @@
+/*
+ * 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.policy.expressions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.policy.Expression;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentExpression;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinitionFactory;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+
+/**
+ * Apply extends {@link com.att.research.xacmlatt.pdp.policy.Expression} to implement the XACML Apply Expression element.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class Apply extends Expression {
+ private Identifier functionId;
+ private FunctionDefinition functionDefinition;
+ private String description;
+ private List<Expression> arguments = new ArrayList<Expression>();
+
+ protected List<Expression> getArgumentList() {
+ return this.arguments;
+ }
+
+ protected void clearArgumentList() {
+ this.getArgumentList().clear();
+ }
+
+ public Apply(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public Apply(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public Apply() {
+ }
+
+ public Apply(Identifier functionIdIn, String descriptionIn, Collection<Expression> argumentsIn) {
+ this.functionId = functionIdIn;
+ this.description = descriptionIn;
+ if (argumentsIn != null) {
+ this.arguments.addAll(argumentsIn);
+ }
+ }
+
+ public Identifier getFunctionId() {
+ return this.functionId;
+ }
+
+ public void setFunctionId(Identifier identifier) {
+ this.functionId = identifier;
+ this.functionDefinition = null;
+ }
+
+ /**
+ * Gets and caches the {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} matching the
+ * <code>Identifier</code> for the FunctionId in this <code>Apply</code>.
+ *
+ * @return the <code>FunctionDefinition</code> for the <code>Identifier</code> for the Function Id for this <code>Apply</code>
+ */
+ public FunctionDefinition getFunctionDefinition() {
+ if (this.functionDefinition == null) {
+ Identifier thisFunctionId = this.getFunctionId();
+ if (thisFunctionId != null) {
+ try {
+ this.functionDefinition = FunctionDefinitionFactory.newInstance().getFunctionDefinition(thisFunctionId);
+ } catch (FactoryException ex) {
+ this.setStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "FactoryException getting FunctionDefinition");
+ }
+ }
+ }
+ return this.functionDefinition;
+ }
+
+ public String getDescription() {
+ return this.description;
+ }
+
+ public void setDescription(String string) {
+ this.description = string;
+ }
+
+ public Iterator<Expression> getArguments() {
+ return this.getArgumentList().iterator();
+ }
+
+ public void setArguments(Collection<Expression> listExpressions) {
+ this.clearArgumentList();
+ if (listExpressions != null) {
+ this.addArguments(listExpressions);
+ }
+ }
+
+ public void addArgument(Expression expression) {
+ this.getArgumentList().add(expression);
+ }
+
+ public void addArguments(Collection<Expression> listExpressions) {
+ this.getArgumentList().addAll(listExpressions);
+ }
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+ if (!this.validate()) {
+ return ExpressionResult.newError(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+
+ /*
+ * Get the FunctionDefinition
+ */
+ FunctionDefinition thisFunctionDefinition = this.getFunctionDefinition();
+ if (thisFunctionDefinition == null) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Unknown Function \"" + this.getFunctionId().toString() + "\""));
+ }
+
+ /*
+ * Get all of the arguments and convert them into FunctionArgument objects.
+ */
+ List<FunctionArgument> listFunctionArguments = new ArrayList<FunctionArgument>();
+ Iterator<Expression> iterExpressionArguments = this.getArguments();
+ if (iterExpressionArguments != null) {
+ while (iterExpressionArguments.hasNext()) {
+ listFunctionArguments.add(new FunctionArgumentExpression(iterExpressionArguments.next(), evaluationContext, policyDefaults));
+ }
+ }
+
+ /*
+ * Apply the FunctionDefinition to the arguments
+ */
+ return thisFunctionDefinition.evaluate(evaluationContext, listFunctionArguments);
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (this.getFunctionId() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing FunctionId");
+ return false;
+ } else {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.java
new file mode 100755
index 0000000..2a3e530
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.java
@@ -0,0 +1,215 @@
+/*
+ * 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.policy.expressions;
+
+import java.util.Collection;
+
+import com.att.research.xacml.api.Attribute;
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.MissingAttributeDetail;
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.StatusDetail;
+import com.att.research.xacml.api.pip.PIPException;
+import com.att.research.xacml.api.pip.PIPRequest;
+import com.att.research.xacml.api.pip.PIPResponse;
+import com.att.research.xacml.std.StdMutableMissingAttributeDetail;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.StdStatusDetail;
+import com.att.research.xacml.std.pip.StdPIPRequest;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.policy.Bag;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+
+/**
+ * AttributeDesignator extends {@link com.att.research.xacmlatt.pdp.policy.expression.AttributeRetrievalBase} to represent the
+ * XACML AttributeDesignator element.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class AttributeDesignator extends AttributeRetrievalBase {
+ private Identifier attributeId;
+ private String issuer;
+ private PIPRequest pipRequestCached;
+ private MissingAttributeDetail missingAttributeDetail;
+ private StatusDetail statusDetail;
+
+ protected PIPRequest getPIPRequest() {
+ if (this.pipRequestCached == null) {
+ this.pipRequestCached = new StdPIPRequest(this.getCategory(), this.getAttributeId(), this.getDataTypeId(), this.getIssuer());
+ }
+ return this.pipRequestCached;
+ }
+
+ protected MissingAttributeDetail getMissingAttributeDetail() {
+ if (this.missingAttributeDetail == null) {
+ this.missingAttributeDetail = new StdMutableMissingAttributeDetail(this.getCategory(), this.getAttributeId(), this.getDataTypeId(), this.getIssuer());
+ }
+ return this.missingAttributeDetail;
+ }
+
+ protected StatusDetail getStatusDetail() {
+ if (this.statusDetail == null) {
+ this.statusDetail = new StdStatusDetail(this.getMissingAttributeDetail());
+ }
+ return this.statusDetail;
+ }
+
+ public AttributeDesignator(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public AttributeDesignator(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public AttributeDesignator() {
+ }
+
+ public Identifier getAttributeId() {
+ return this.attributeId;
+ }
+
+ public void setAttributeId(Identifier identifierAttributeId) {
+ this.attributeId = identifierAttributeId;
+ }
+
+ public String getIssuer() {
+ return this.issuer;
+ }
+
+ public void setIssuer(String issuerIn) {
+ this.issuer = issuerIn;
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (!super.validateComponent()) {
+ return false;
+ } else if (this.getAttributeId() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AttributeId");
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Determines if the given <code>Attribute</code> has the same category, attribute id, and issuer as this
+ * <code>AttributeDesignator</code>.
+ *
+ * @param attribute the <code>Attribute</code> to test
+ * @return true if the <code>Attribute</code> matches, else false
+ */
+ protected boolean match(Attribute attribute) {
+ if (!this.getCategory().equals(attribute.getCategory())) {
+ return false;
+ } else if (!this.getAttributeId().equals(attribute.getAttributeId())) {
+ return false;
+ } else if (this.getIssuer() != null && !this.getIssuer().equals(attribute.getIssuer())) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Determines if the given <code>AttributeValue</code> has the same data type id as this
+ * <code>AttributeDesignator</code>.
+ *
+ * @param attributeValue the <code>AttributeValue</code> to test
+ * @return true if the <code>AttributeValue</code> maches, else false
+ */
+ protected boolean match(AttributeValue<?> attributeValue) {
+ if (!this.getDataTypeId().equals(attributeValue.getDataTypeId())) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+ if (!this.validate()) {
+ return ExpressionResult.newInstance(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+
+ /*
+ * Set up the PIPRequest representing this
+ */
+ PIPRequest pipRequest = this.getPIPRequest();
+ assert(pipRequest != null);
+
+ /*
+ * Query the evaluation context for results
+ */
+ PIPResponse pipResponse = null;
+ try {
+ pipResponse = evaluationContext.getAttributes(pipRequest);
+ } catch (PIPException ex) {
+ throw new EvaluationException("PIPException getting Attributes", ex);
+ }
+ assert(pipResponse != null);
+
+ /*
+ * See if the request was successful
+ */
+ Status pipStatus = pipResponse.getStatus();
+ if (pipStatus != null && !pipStatus.getStatusCode().equals(StdStatusCode.STATUS_CODE_OK)) {
+ return ExpressionResult.newInstance(pipStatus);
+ }
+
+ /*
+ * See if there were any results
+ */
+ Bag bagAttributeValues = new Bag();
+ Collection<Attribute> listAttributes = pipResponse.getAttributes();
+ for (Attribute attribute : listAttributes) {
+ if (this.match(attribute)) {
+ for (AttributeValue<?> attributeValue: attribute.getValues()) {
+ if (this.match(attributeValue)) {
+ bagAttributeValues.add(attributeValue);
+ }
+ }
+ }
+ }
+ if (this.getMustBePresent() && bagAttributeValues.size() == 0) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE, "Missing required attribute", new StdStatusDetail(this.getMissingAttributeDetail())));
+ } else {
+ return ExpressionResult.newBag(bagAttributeValues);
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ Object objectToDump;
+ if ((objectToDump = this.getAttributeId()) != null) {
+ stringBuilder.append(",attributeId=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ if ((objectToDump = this.getIssuer()) != null) {
+ stringBuilder.append(",issuer=");
+ stringBuilder.append((String)objectToDump);
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.java
new file mode 100755
index 0000000..21ac724
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.java
@@ -0,0 +1,170 @@
+/*
+ * 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.policy.expressions;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.StatusDetail;
+import com.att.research.xacml.api.XACML;
+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.policy.Expression;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+
+/**
+ * AttributeRetrievalBase extends {@link com.att.research.xacmlatt.pdp.policy.PolicyComponent} and
+ * implements {@link com.att.research.xacmlatt.pdp.eval.Evaluatable} to serve as an abstract base class
+ * for the {@link com.att.research.xacmlatt.pdp.policy.AttributeSelector} and {@link com.att.research.xacmlatt.pdp.policy.AttributeDesignator}
+ * classes.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public abstract class AttributeRetrievalBase extends Expression {
+ private Identifier category;
+ private Identifier dataTypeId;
+ private Boolean mustBePresent;
+
+ protected AttributeRetrievalBase(StatusCode statusCodeIn,
+ String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ protected AttributeRetrievalBase(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ protected AttributeRetrievalBase() {
+ }
+
+ protected AttributeRetrievalBase(Identifier categoryIn, Identifier dataTypeIdIn, Boolean mustBePresentIn) {
+ this.category = categoryIn;
+ this.dataTypeId = dataTypeIdIn;
+ this.mustBePresent = mustBePresentIn;
+ }
+
+ /**
+ * Gets the {@link com.att.research.xacml.api.Identifier} for the category associated with this
+ * <code>AttributeRetrievalBase</code>.
+ *
+ * @return the <code>Identifier</code> for the category of this <code>AttributeRetrievalBase</code>.
+ */
+ public Identifier getCategory() {
+ return this.category;
+ }
+
+ /**
+ * Sets the <code>Identifier</code> for the category associated with this <code>AttributeRetrievalBase</code>.
+ *
+ * @param categoryIn the <code>Identifier</code> for the category associated with this <code>AttributeRetrievalBase</code>
+ */
+ public void setCategory(Identifier categoryIn) {
+ this.category = categoryIn;
+ }
+
+ /**
+ * Gets the <code>Identifier</code> for the data type associated with this <code>AttributeRetrievalBase</code>.
+ *
+ * @return the <code>Identifier</code> for the data type associated with this <code>AttributeRetrievalBase</code>
+ */
+ public Identifier getDataTypeId() {
+ return this.dataTypeId;
+ }
+
+ /**
+ * Sets the <code>Identifier</code> for the data type associated with this <code>AttributeRetrievalBase</code>.
+ *
+ * @param dataTypeIn the <code>Identifier</code> for the data type associated with this <code>AttributeRetrievalBase</code>
+ */
+ public void setDataTypeId(Identifier dataTypeIn) {
+ // allow old-style Ids for Durations since there is no structural or semantic changes, just a different Id.
+ if (dataTypeIn.equals(XACML.ID_DATATYPE_WD_DAYTIMEDURATION)) {
+ dataTypeIn = DataTypes.DT_DAYTIMEDURATION.getId();
+ } else if (dataTypeIn.equals(XACML.ID_DATATYPE_WD_YEARMONTHDURATION)) {
+ dataTypeIn = DataTypes.DT_YEARMONTHDURATION.getId();
+ }
+ this.dataTypeId = dataTypeIn;
+ }
+
+ /**
+ * Determines if a value must be found for this <code>AttributeRetrievalBase</code> when it is evaluated. If true,
+ * and no value is found, an indeterminate result is returned, otherwise an empty bag is returned.
+ *
+ * @return true if the value of this <code>AttributeRetrievalBase</code> must be found, else false
+ */
+ public Boolean getMustBePresent() {
+ return this.mustBePresent;
+ }
+
+ /**
+ * Sets the flag indicating whether a value must be found for this <code>AttributeRetrievalBase</code>.
+ *
+ * @param b the boolean value for the flag
+ */
+ public void setMustBePresent(boolean b) {
+ this.mustBePresent = b;
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (this.getCategory() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Category");
+ return false;
+ } else if (this.getDataTypeId() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing DataType");
+ return false;
+ } else if (this.getMustBePresent() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing MustBePresent");
+ return false;
+ } else {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+ }
+
+ @Override public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ Object objectToDump;
+ if ((objectToDump = this.getCategory()) != null) {
+ stringBuilder.append(",category=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ if ((objectToDump = this.getDataTypeId()) != null) {
+ stringBuilder.append(",dataType=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ if ((objectToDump = this.getMustBePresent()) != null) {
+ stringBuilder.append(",mustBePresent=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+ /**
+ * Creates the appropriate {@link com.att.research.xacmlatt.pdp.policy.ExpressionResult} for an empty list based
+ * on the <code>getMustBePresent</code> value.
+ *
+ * @return an appropriate <code>ExpressionResult</code>
+ */
+ protected ExpressionResult getEmptyResult(String statusMessage, StatusDetail statusDetail) {
+ if (this.getMustBePresent() != null && this.getMustBePresent().booleanValue()) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE, statusMessage, statusDetail));
+ } else {
+ return ExpressionResult.newEmpty();
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.java
new file mode 100755
index 0000000..d5f94e2
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.java
@@ -0,0 +1,283 @@
+/*
+ * 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.policy.expressions;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.att.research.xacml.api.Attribute;
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.DataTypeFactory;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.RequestAttributes;
+import com.att.research.xacml.api.StatusCode;
+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.NodeNamespaceContext;
+import com.att.research.xacml.std.datatypes.XPathExpressionWrapper;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.dom.DOMUtil;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.policy.Bag;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+
+/**
+ * AttributeSelector extends {@link com.att.research.xacmlatt.pdp.policy.expressions.AttributeRetrievalBase} to implement
+ * the XACML AttributeSelector element.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class AttributeSelector extends AttributeRetrievalBase {
+ private Identifier contextSelectorId;
+ private String path;
+ @SuppressWarnings("unused")
+ private DataType<?> dataType;
+
+ protected DataType<?> getDataType() {
+ Identifier dataTypeIdThis = this.getDataTypeId();
+ if (dataTypeIdThis == null) {
+ return null;
+ } else {
+ DataTypeFactory dataTypeFactory = null;
+ try {
+ dataTypeFactory = DataTypeFactory.newInstance();
+ if (dataTypeFactory == null) {
+ return null;
+ }
+ } catch (FactoryException ex) {
+ return null;
+ }
+ return (this.dataType = dataTypeFactory.getDataType(dataTypeIdThis));
+ }
+ }
+
+ public AttributeSelector(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public AttributeSelector(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public AttributeSelector() {
+ }
+
+ public Identifier getContextSelectorId() {
+ return this.contextSelectorId;
+ }
+
+ public void setContextSelectorId(Identifier identifier) {
+ this.contextSelectorId = identifier;
+ }
+
+ public String getPath() {
+ return this.path;
+ }
+
+ public void setPath(String pathIn) {
+ this.path = pathIn;
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (!super.validateComponent()) {
+ return false;
+ } else if (this.getPath() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Path");
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * If there is a context selector ID, get the attributes from the given <code>RequestAttributes</code> with that
+ * ID, ensure they are <code>XPathExpression</code>s and return them.
+ *
+ * @param requestAttributes
+ * @return
+ */
+ protected List<XPathExpression> getContextSelectorValues(RequestAttributes requestAttributes) {
+ Identifier thisContextSelectorId = this.getContextSelectorId();
+ if (thisContextSelectorId == null) {
+ return null;
+ }
+ List<XPathExpression> listXPathExpressions = null;
+ Iterator<Attribute> iterAttributes = requestAttributes.getAttributes(thisContextSelectorId);
+ if (iterAttributes != null) {
+ while (iterAttributes.hasNext()) {
+ Attribute attribute = iterAttributes.next();
+ Iterator<AttributeValue<XPathExpressionWrapper>> iterXPathExpressions = attribute.findValues(DataTypes.DT_XPATHEXPRESSION);
+ if (iterXPathExpressions != null && iterXPathExpressions.hasNext()) {
+ if (listXPathExpressions == null) {
+ listXPathExpressions = new ArrayList<XPathExpression>();
+ }
+ listXPathExpressions.add(iterXPathExpressions.next().getValue());
+ }
+ }
+ }
+ return listXPathExpressions;
+ }
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+ if (!this.validate()) {
+ return ExpressionResult.newError(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+
+ /*
+ * Get the DataType for this AttributeSelector for converting the resulting nodes into AttributeValues
+ */
+ DataType<?> thisDataType = this.getDataType();
+
+ /*
+ * Get the Request so we can find the XPathExpression to locate the root node and to find the Content element
+ * of the requested category.
+ */
+ Request request = evaluationContext.getRequest();
+ assert(request != null);
+
+ /*
+ * Get the RequestAttributes objects for our Category. If none are found, then we abort quickly with either
+ * an empty or indeterminate result.
+ */
+ Iterator<RequestAttributes> iterRequestAttributes = request.getRequestAttributes(this.getCategory());
+ if (iterRequestAttributes == null || !iterRequestAttributes.hasNext()) {
+ return this.getEmptyResult("No Attributes with Category " + this.getCategory().toString(), null);
+ }
+
+ /*
+ * Section 5.30 of the XACML 3.0 specification is a little vague about how to use the
+ * ContextSelectorId in the face of having multiple Attributes elements with the same CategoryId. My interpretation
+ * is that each is distinct, so we look for an attribute matching the ContextSelectorId in each matching Attributes element
+ * and use that to search the Content in that particular Attributes element. If either an Attribute matching the context selector id
+ * is not found or there is no Content, then that particular Attributes element is skipped.
+ */
+ Bag bagAttributeValues = new Bag();
+ StdStatus statusFirstError = null;
+ while (iterRequestAttributes.hasNext()) {
+ RequestAttributes requestAttributes = iterRequestAttributes.next();
+
+ /*
+ * See if we have a Content element to query.
+ */
+ Node nodeContentRoot = requestAttributes.getContentRoot();
+ if (nodeContentRoot != null) {
+ List<Node> listNodesToQuery = new ArrayList<Node>();
+ List<XPathExpression> listXPathExpressions = this.getContextSelectorValues(requestAttributes);
+ if (listXPathExpressions == null) {
+ listNodesToQuery.add(nodeContentRoot);
+ } else {
+ Iterator<XPathExpression> iterXPathExpressions = listXPathExpressions.iterator();
+ while (iterXPathExpressions.hasNext()) {
+ XPathExpression xpathExpression = iterXPathExpressions.next();
+ Node nodeContent = requestAttributes.getContentNodeByXpathExpression(xpathExpression);
+ if (nodeContent != null) {
+ listNodesToQuery.add(nodeContent);
+ }
+ }
+ }
+
+ /*
+ * If there are any nodes to query, do so now and add the results
+ */
+ if (listNodesToQuery.size() > 0) {
+ for (Node nodeToQuery : listNodesToQuery) {
+ NodeList nodeList = null;
+ try {
+ XPath xPath = XPathFactory.newInstance().newXPath();
+ xPath.setNamespaceContext(new NodeNamespaceContext(nodeToQuery.getOwnerDocument()));
+ XPathExpression xPathExpression = xPath.compile(this.getPath());
+ Node nodeToQueryDocumentRoot = null;
+ try {
+ nodeToQueryDocumentRoot = DOMUtil.getDirectDocumentChild(nodeToQuery);
+ } catch (DOMStructureException ex) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Exception processing context node: " + ex.getMessage()));
+ }
+ nodeList = (NodeList)xPathExpression.evaluate(nodeToQueryDocumentRoot, XPathConstants.NODESET);
+ } catch (XPathExpressionException ex) {
+ if (statusFirstError == null) {
+ statusFirstError = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "XPathExpressionException: " + ex.getMessage());
+ }
+ }
+ if (nodeList != null && nodeList.getLength() > 0) {
+ for (int i = 0 ; i < nodeList.getLength() ; i++) {
+ AttributeValue<?> attributeValueNode = null;
+ try {
+ attributeValueNode = thisDataType.createAttributeValue(nodeList.item(i));
+ } catch (DataTypeException ex) {
+ if (statusFirstError == null) {
+ statusFirstError = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage());
+ }
+ }
+ if (attributeValueNode != null) {
+ bagAttributeValues.add(attributeValueNode);
+ } else if (statusFirstError == null) {
+ statusFirstError = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Unable to convert node to " + this.getDataTypeId().toString());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ if (bagAttributeValues.size() == 0) {
+ if (statusFirstError == null) {
+ return this.getEmptyResult("No Content found", null);
+ } else {
+ return ExpressionResult.newError(statusFirstError);
+ }
+ } else {
+ return ExpressionResult.newBag(bagAttributeValues);
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ Object objectToDump;
+ if ((objectToDump = this.getContextSelectorId()) != null) {
+ stringBuilder.append(",contextSelectorId=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ if ((objectToDump = this.getPath()) != null) {
+ stringBuilder.append(",path=");
+ stringBuilder.append((String)objectToDump);
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.java
new file mode 100755
index 0000000..73cf5b8
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.java
@@ -0,0 +1,89 @@
+/*
+ * 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.policy.expressions;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.StatusCode;
+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.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.policy.Expression;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+
+/**
+ * AttributeValueExpression extends {@link com.att.research.xacmlatt.pdp.policy.Expression} to represent XACML
+ * AttributeValue elements in an Expression context.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class AttributeValueExpression extends Expression {
+ private AttributeValue<?> attributeValue;
+
+ public AttributeValueExpression(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public AttributeValueExpression(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public AttributeValueExpression() {
+ }
+
+ public AttributeValueExpression(AttributeValue<?> attributeValueIn) {
+ this.attributeValue = attributeValueIn;
+ }
+
+ public AttributeValue<?> getAttributeValue() {
+ return this.attributeValue;
+ }
+
+ public void setAttributeValue(AttributeValue<?> attributeValueIn) {
+ this.attributeValue = attributeValueIn;
+ }
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+ if (!this.validate()) {
+ return ExpressionResult.newError(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+
+ return ExpressionResult.newSingle(this.getAttributeValue());
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (this.getAttributeValue() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing AttributeValue");
+ return false;
+ } else {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+
+ Object objectToDump;
+ if ((objectToDump = this.getAttributeValue()) != null) {
+ stringBuilder.append("attributeValue=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Function.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Function.java
new file mode 100755
index 0000000..16cf506
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Function.java
@@ -0,0 +1,105 @@
+/*
+ * 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.policy.expressions;
+
+import java.net.URI;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.StatusCode;
+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.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.policy.Expression;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+
+/**
+ * Function extends {@link com.att.research.xacmlatt.pdp.policy.Expression} to implement the XACML Function element.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class Function extends Expression {
+ private Identifier functionId;
+ private AttributeValue<URI> attributeValue;
+ private ExpressionResult expressionResultOk;
+
+ protected ExpressionResult getExpressionResultOk() {
+ if (this.expressionResultOk == null) {
+ this.expressionResultOk = ExpressionResult.newSingle(this.getAttributeValue());
+ }
+ return this.expressionResultOk;
+ }
+
+ public Function(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public Function(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public Function() {
+ }
+
+ public Function(Identifier functionIdIn) {
+ this.functionId = functionIdIn;
+ }
+
+ public Identifier getFunctionId() {
+ return this.functionId;
+ }
+
+ public void setFunctionId(Identifier identifier) {
+ this.functionId = identifier;
+ this.attributeValue = null;
+ this.expressionResultOk = null;
+ }
+
+ public AttributeValue<URI> getAttributeValue() {
+ if (this.attributeValue == null) {
+ Identifier thisFunctionId = this.getFunctionId();
+ if (thisFunctionId != null) {
+ try {
+ this.attributeValue = DataTypes.DT_ANYURI.createAttributeValue(thisFunctionId);
+ } catch (DataTypeException ex) {
+ this.attributeValue = null;
+ }
+ }
+ }
+ return this.attributeValue;
+ }
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+ if (!this.validate()) {
+ return ExpressionResult.newError(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ } else {
+ return this.getExpressionResultOk();
+ }
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (this.getFunctionId() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing FunctionId");
+ return false;
+ } else {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.java
new file mode 100755
index 0000000..be322e9
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.java
@@ -0,0 +1,149 @@
+/*
+ * 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.policy.expressions;
+
+import com.att.research.xacml.api.StatusCode;
+import com.att.research.xacml.api.trace.Traceable;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.trace.StdTraceEvent;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.policy.Expression;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.PolicyDefaults;
+import com.att.research.xacmlatt.pdp.policy.VariableDefinition;
+
+/**
+ * VariableReference extends {@link com.att.research.xacmlatt.pdp.policy.Expression} to implement the XACML VariableReference
+ * element.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class VariableReference extends Expression implements Traceable {
+ private static final ExpressionResult ER_SE_NO_EXPRESSION = ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing Expression for VariableDefinition"));
+
+ private Policy policy;
+ private String variableId;
+ private VariableDefinition variableDefinition;
+
+ protected VariableDefinition getVariableDefinition() {
+ if (this.variableDefinition == null) {
+ Policy thisPolicy = this.getPolicy();
+ if (thisPolicy != null) {
+ String thisVariableId = this.getVariableId();
+ if (thisVariableId != null) {
+ this.variableDefinition = thisPolicy.getVariableDefinition(thisVariableId);
+ }
+ }
+ }
+ return this.variableDefinition;
+ }
+
+ public VariableReference(StatusCode statusCodeIn, String statusMessageIn) {
+ super(statusCodeIn, statusMessageIn);
+ }
+
+ public VariableReference(StatusCode statusCodeIn) {
+ super(statusCodeIn);
+ }
+
+ public VariableReference() {
+ }
+
+ public VariableReference(Policy policyIn, String variableIdIn) {
+ this.policy = policyIn;
+ this.variableId = variableIdIn;
+ }
+
+ public Policy getPolicy() {
+ return this.policy;
+ }
+
+ public void setPolicy(Policy policyIn) {
+ this.policy = policyIn;
+ }
+
+ public String getVariableId() {
+ return this.variableId;
+ }
+
+ public void setVariableId(String variableIdIn) {
+ this.variableId = variableIdIn;
+ }
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, PolicyDefaults policyDefaults) throws EvaluationException {
+ if (!this.validate()) {
+ return ExpressionResult.newError(new StdStatus(this.getStatusCode(), this.getStatusMessage()));
+ }
+
+ VariableDefinition variableDefinition = this.getVariableDefinition();
+ if (variableDefinition == null) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No VariableDefinition found for \"" + this.getVariableId() + "\""));
+ }
+ Expression expression = variableDefinition.getExpression();
+ if (expression == null) {
+ return ER_SE_NO_EXPRESSION;
+ }
+
+ ExpressionResult result = expression.evaluate(evaluationContext, policyDefaults);
+
+ if (evaluationContext.isTracing()) {
+ evaluationContext.trace(new StdTraceEvent<ExpressionResult>("Variable", this, result));
+ }
+
+ return result;
+ }
+
+ @Override
+ protected boolean validateComponent() {
+ if (this.getVariableId() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Missing VariableId");
+ return false;
+ } else if (this.getPolicy() == null) {
+ this.setStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "VariableReference not in a Policy");
+ return false;
+ } else {
+ this.setStatus(StdStatusCode.STATUS_CODE_OK, null);
+ return true;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+
+ stringBuilder.append("super=");
+ stringBuilder.append(super.toString());
+
+ String stringToDump;
+ if ((stringToDump = this.getVariableId()) != null) {
+ stringBuilder.append(",variableId=");
+ stringBuilder.append(stringToDump);
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+
+ @Override
+ public String getTraceId() {
+ return this.variableId;
+ }
+
+ @Override
+ public Traceable getCause() {
+ return this.policy;
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/package-info.java
new file mode 100755
index 0000000..0abd0ec
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.policy.expressions;
+
+/**
+ * com.att.research.xacmlatt.pdp.policy.expressions contains class definitions that represent specific XACML elements sub-typed from
+ * the Expression element.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/package-info.java
new file mode 100755
index 0000000..bb4a5ba
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.policy;
+
+/**
+ * com.att.research.xacmlatt.pdp.policy contains class definitions that represent a XACML 3.0 Policy such that it can be
+ * used to implement the {@link com.att.research.xacml.pdp.PDPEngine} <code>decide</code> method.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.java
new file mode 100755
index 0000000..9312e31
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.java
@@ -0,0 +1,89 @@
+/*
+ * 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;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+import com.att.research.xacmlatt.pdp.policy.Rule;
+
+/**
+ * StdCombiningAlgorithmFactory extends {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory} to implement
+ * a mapping from {@link com.att.research.xacml.api.Identifier}s to
+ * the standard {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm} implementations.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class StdCombiningAlgorithmFactory extends CombiningAlgorithmFactory {
+ private static Map<Identifier,CombiningAlgorithm<Rule>> mapRuleCombiningAlgorithms
+ = new HashMap<Identifier,CombiningAlgorithm<Rule>>();
+ private static Map<Identifier,CombiningAlgorithm<PolicySetChild>> mapPolicyCombiningAlgorithms
+ = new HashMap<Identifier,CombiningAlgorithm<PolicySetChild>>();
+ private static boolean needInit = true;
+
+ protected static void registerRuleCombiningAlgorithm(CombiningAlgorithm<Rule> ruleCombiningAlgorithm) {
+ mapRuleCombiningAlgorithms.put(ruleCombiningAlgorithm.getId(), ruleCombiningAlgorithm);
+ }
+
+ protected static void registerPolicyCombiningAlgorithm(CombiningAlgorithm<PolicySetChild> policyCombiningAlgorithm) {
+ mapPolicyCombiningAlgorithms.put(policyCombiningAlgorithm.getId(), policyCombiningAlgorithm);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static void initMap() {
+ if (needInit) {
+ synchronized(mapRuleCombiningAlgorithms) {
+ if (needInit) {
+ needInit = false;
+ Field[] declaredFields = StdCombiningAlgorithms.class.getFields();
+ for (Field field : declaredFields) {
+ if (Modifier.isStatic(field.getModifiers()) &&
+ Modifier.isPublic(field.getModifiers()) &&
+ field.getName().startsWith(StdCombiningAlgorithms.PREFIX_CA) &&
+ CombiningAlgorithm.class.isAssignableFrom(field.getType())
+ ) {
+ try {
+ if (field.getName().startsWith(StdCombiningAlgorithms.PREFIX_RULE)) {
+ registerRuleCombiningAlgorithm((CombiningAlgorithm<Rule>)field.get(null));
+ } else if (field.getName().startsWith(StdCombiningAlgorithms.PREFIX_POLICY)) {
+ registerPolicyCombiningAlgorithm((CombiningAlgorithm<PolicySetChild>)field.get(null));
+ }
+ } catch (IllegalAccessException ex) {
+
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public StdCombiningAlgorithmFactory() {
+ initMap();
+ }
+
+ @Override
+ public CombiningAlgorithm<Rule> getRuleCombiningAlgorithm(Identifier combiningAlgorithmId) {
+ return mapRuleCombiningAlgorithms.get(combiningAlgorithmId);
+ }
+
+ @Override
+ public CombiningAlgorithm<PolicySetChild> getPolicyCombiningAlgorithm(Identifier combiningAlgorithmId) {
+ return mapPolicyCombiningAlgorithms.get(combiningAlgorithmId);
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.java
new file mode 100755
index 0000000..450c1f2
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.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;
+
+import com.att.research.xacml.api.XACML1;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+import com.att.research.xacmlatt.pdp.policy.Rule;
+import com.att.research.xacmlatt.pdp.std.combiners.CombinedPermitOverrides;
+import com.att.research.xacmlatt.pdp.std.combiners.DenyOverrides;
+import com.att.research.xacmlatt.pdp.std.combiners.DenyUnlessPermit;
+import com.att.research.xacmlatt.pdp.std.combiners.FirstApplicable;
+import com.att.research.xacmlatt.pdp.std.combiners.LegacyDenyOverridesPolicy;
+import com.att.research.xacmlatt.pdp.std.combiners.LegacyDenyOverridesRule;
+import com.att.research.xacmlatt.pdp.std.combiners.LegacyPermitOverridesPolicy;
+import com.att.research.xacmlatt.pdp.std.combiners.LegacyPermitOverridesRule;
+import com.att.research.xacmlatt.pdp.std.combiners.OnlyOneApplicable;
+import com.att.research.xacmlatt.pdp.std.combiners.PermitOverrides;
+import com.att.research.xacmlatt.pdp.std.combiners.PermitUnlessDeny;
+import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
+
+/**
+ * StdCombiningAlgorithms contains single instances of each of the {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm}
+ * implementations in the {@link com.att.research.xacmlatt.pdp.std.combiners} package.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class StdCombiningAlgorithms {
+
+ protected StdCombiningAlgorithms() {
+ }
+
+ public static final String PREFIX_CA = "CA_";
+ public static final String PREFIX_RULE = PREFIX_CA + "RULE_";
+ public static final String PREFIX_POLICY = PREFIX_CA + "POLICY_";
+
+ // C.2 Deny-overrides
+ public static final CombiningAlgorithm<Rule> CA_RULE_DENY_OVERRIDES
+ = new DenyOverrides<Rule>(XACML3.ID_RULE_DENY_OVERRIDES);
+ public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_DENY_OVERRIDES
+ = new DenyOverrides<PolicySetChild>(XACML3.ID_POLICY_DENY_OVERRIDES);
+
+ // C.3 Ordered-deny-overrides
+ public static final CombiningAlgorithm<Rule> CA_RULE_ORDERED_DENY_OVERRIDES
+ = new DenyOverrides<Rule>(XACML3.ID_RULE_ORDERED_DENY_OVERRIDES);
+ public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_ORDERED_DENY_OVERRIDES
+ = new DenyOverrides<PolicySetChild>(XACML3.ID_POLICY_ORDERED_DENY_OVERRIDES);
+
+ // C.4 Permit-overrides
+ public static final CombiningAlgorithm<Rule> CA_RULE_PERMIT_OVERRIDES
+ = new PermitOverrides<Rule>(XACML3.ID_RULE_PERMIT_OVERRIDES);
+ public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_PERMIT_OVERRIDES
+ = new PermitOverrides<PolicySetChild>(XACML3.ID_POLICY_PERMIT_OVERRIDES);
+
+ // C.5 Ordered-permit-overrides
+ public static final CombiningAlgorithm<Rule> CA_RULE_ORDERED_PERMIT_OVERRIDES
+ = new PermitOverrides<Rule>(XACML3.ID_RULE_ORDERED_PERMIT_OVERRIDES);
+ public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_ORDERED_PERMIT_OVERRIDES
+ = new PermitOverrides<PolicySetChild>(XACML3.ID_POLICY_ORDERED_PERMIT_OVERRIDES);
+
+ // C.6 Deny-unless-permit
+ public static final CombiningAlgorithm<Rule> CA_RULE_DENY_UNLESS_PERMIT
+ = new DenyUnlessPermit<Rule>(XACML3.ID_RULE_DENY_UNLESS_PERMIT);
+ public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_DENY_UNLESS_PERMIT
+ = new DenyUnlessPermit<PolicySetChild>(XACML3.ID_POLICY_DENY_UNLESS_PERMIT);
+
+ // C.7 Permit-unles-deny
+ public static final CombiningAlgorithm<Rule> CA_RULE_PERMIT_UNLESS_DENY
+ = new PermitUnlessDeny<Rule>(XACML3.ID_RULE_PERMIT_UNLESS_DENY);
+ public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_PERMIT_UNLESS_DENY
+ = new PermitUnlessDeny<PolicySetChild>(XACML3.ID_POLICY_PERMIT_UNLESS_DENY);
+
+ // C.8 First-applicable
+ public static final CombiningAlgorithm<Rule> CA_RULE_FIRST_APPLICABLE
+ = new FirstApplicable<Rule>(XACML1.ID_RULE_FIRST_APPLICABLE);
+ public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_FIRST_APPLICABLE
+ = new FirstApplicable<PolicySetChild>(XACML1.ID_POLICY_FIRST_APPLICABLE);
+
+ // C.9 Only-one-applicable
+ //public static final CombiningAlgorithm<Rule> CA_RULE_ONLY_ONE_APPLICABLE
+ // = new OnlyOneApplicable<Rule>(XACML1.ID_RULE_ONLY_ONE_APPLICABLE);
+ public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_ONLY_ONE_APPLICABLE
+ = new OnlyOneApplicable(XACML1.ID_POLICY_ONLY_ONE_APPLICABLE);
+
+ // C.10 Legacy Deny-overrides
+ public static final CombiningAlgorithm<Rule> CA_RULE_LEGACY_DENY_OVERRIDES
+ = new LegacyDenyOverridesRule(XACML1.ID_RULE_DENY_OVERRIDES);
+ public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_LEGACY_DENY_OVERRIDES
+ = new LegacyDenyOverridesPolicy(XACML1.ID_POLICY_DENY_OVERRIDES);
+
+ // C.11 Legacy Ordered-deny-overrides
+ public static final CombiningAlgorithm<Rule> CA_RULE_LEGACY_ORDERED_DENY_OVERRIDES
+ = new LegacyDenyOverridesRule(XACML1.ID_RULE_ORDERED_DENY_OVERRIDES);
+ public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_LEGACY_ORDERED_DENY_OVERRIDES
+ = new LegacyDenyOverridesPolicy(XACML1.ID_POLICY_ORDERED_DENY_OVERRIDES);
+
+ // C.12 Legacy Permit-overrides
+ public static final CombiningAlgorithm<Rule> CA_RULE_LEGACY_PERMIT_OVERRIDES
+ = new LegacyPermitOverridesRule(XACML1.ID_RULE_PERMIT_OVERRIDES);
+ public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_LEGACY_PERMIT_OVERRIDES
+ = new LegacyPermitOverridesPolicy(XACML1.ID_POLICY_PERMIT_OVERRIDES);
+
+ // C.13 Legacy Ordered-permit-overrides
+ public static final CombiningAlgorithm<Rule> CA_RULE_LEGACY_ORDERED_PERMIT_OVERRIDES
+ = new LegacyPermitOverridesRule(XACML1.ID_RULE_ORDERED_PERMIT_OVERRIDES);
+ public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_LEGACY_ORDERED_PERMIT_OVERRIDES
+ = new LegacyPermitOverridesPolicy(XACML1.ID_POLICY_ORDERED_PERMIT_OVERRIDES);
+
+ //
+ // Custom AT&T Policy Combing Algorithms
+ //
+ public static final CombiningAlgorithm<PolicySetChild> CA_POLICY_COMBINED_PERMIT_OVERRIDES
+ = new CombinedPermitOverrides<PolicySetChild>(ATTPDPProperties.ID_POLICY_COMBINEDPERMITOVERRIDES);
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.java
new file mode 100755
index 0000000..7266227
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.java
@@ -0,0 +1,150 @@
+/*
+ * 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;
+
+import com.att.research.xacml.api.IdReferenceMatch;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.pip.*;
+import com.att.research.xacml.api.trace.TraceEngine;
+import com.att.research.xacml.api.trace.TraceEngineFactory;
+import com.att.research.xacml.api.trace.TraceEvent;
+import com.att.research.xacml.std.pip.engines.RequestEngine;
+import com.att.research.xacml.std.pip.finders.RequestFinder;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.*;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.Collection;
+import java.util.Properties;
+
+/**
+ * StdEvaluationContext implements the {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext} interface using
+ * default factories to load the XACML policies, and get the PIP engines.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class StdEvaluationContext implements EvaluationContext {
+ private Log logger = LogFactory.getLog(this.getClass());
+ private Properties properties;
+ private Request request;
+ private RequestFinder requestFinder;
+ private PolicyFinder policyFinder;
+ private TraceEngine traceEngine;
+
+ /**
+ * Creates a new <code>StdEvaluationContext</code> with the given {@link com.att.research.xacml.api.Request} and
+ * {@link com.att.research.xacmlatt.pdp.policy.PolicyDef}.
+ *
+ * @param requestIn the <code>Request</code>
+ * @param policyDef the <code>PolicyDef</code>
+ */
+ public StdEvaluationContext(Request requestIn, PolicyFinder policyFinderIn, PIPFinder pipFinder, TraceEngine traceEngineIn, Properties properties) {
+ this.properties = properties;
+ this.request = requestIn;
+ this.policyFinder = policyFinderIn;
+ if (traceEngineIn != null) {
+ this.traceEngine = traceEngineIn;
+ } else {
+ try {
+ if (this.properties == null) {
+ this.traceEngine = TraceEngineFactory.newInstance().getTraceEngine();
+ } else {
+ this.traceEngine = TraceEngineFactory.newInstance(this.properties).getTraceEngine(this.properties);
+ }
+ } catch (FactoryException ex) {
+ this.logger.error("FactoryException creating TraceEngine: " + ex.toString(), ex);
+ }
+ }
+
+ if (pipFinder == null) {
+ this.requestFinder = new RequestFinder(null, new RequestEngine(requestIn));
+ } else {
+ if (pipFinder instanceof RequestFinder) {
+ this.requestFinder = (RequestFinder)pipFinder;
+ } else {
+ this.requestFinder = new RequestFinder(pipFinder, new RequestEngine(requestIn));
+ }
+ }
+ }
+
+ public StdEvaluationContext(Request requestIn, PolicyFinder policyFinderIn, PIPFinder pipFinder, TraceEngine traceEngineIn) {
+ this(requestIn, policyFinderIn, pipFinder, traceEngineIn, null);
+ }
+
+ public StdEvaluationContext(Request requestIn, PolicyFinder policyFinderIn, PIPFinder pipFinder) {
+ this(requestIn, policyFinderIn, pipFinder, null);
+ }
+
+ @Override
+ public Request getRequest() {
+ return this.request;
+ }
+
+ @Override
+ public PIPResponse getAttributes(PIPRequest pipRequest) throws PIPException {
+ return this.requestFinder.getAttributes(pipRequest, null);
+ }
+
+ @Override
+ public PIPResponse getAttributes(PIPRequest pipRequest, PIPEngine exclude) throws PIPException {
+ return this.requestFinder.getAttributes(pipRequest, exclude);
+ }
+
+ @Override
+ public PIPResponse getAttributes(PIPRequest pipRequest, PIPEngine exclude, PIPFinder pipFinderRoot) throws PIPException {
+ return this.requestFinder.getAttributes(pipRequest, exclude, pipFinderRoot);
+ }
+
+ @Override
+ public PolicyFinderResult<PolicyDef> getRootPolicyDef() {
+ return this.policyFinder.getRootPolicyDef(this);
+ }
+
+ @Override
+ public PolicyFinderResult<Policy> getPolicy(IdReferenceMatch idReferenceMatch) {
+ return this.policyFinder.getPolicy(idReferenceMatch);
+ }
+
+ @Override
+ public PolicyFinderResult<PolicySet> getPolicySet(IdReferenceMatch idReferenceMatch) {
+ return this.policyFinder.getPolicySet(idReferenceMatch);
+ }
+
+ @Override
+ public void trace(TraceEvent<?> traceEvent) {
+ if (this.traceEngine != null) {
+ this.traceEngine.trace(traceEvent);
+ }
+ }
+
+ @Override
+ public boolean isTracing() {
+ return (this.traceEngine == null ? false : this.traceEngine.isTracing());
+ }
+
+ @Override
+ public PIPResponse getMatchingAttributes(PIPRequest pipRequest, PIPEngine exclude) throws PIPException {
+ return this.requestFinder.getMatchingAttributes(pipRequest, exclude);
+ }
+
+ @Override
+ public PIPResponse getMatchingAttributes(PIPRequest pipRequest, PIPEngine exclude, PIPFinder pipFinderParent) throws PIPException {
+ return this.requestFinder.getMatchingAttributes(pipRequest, exclude, pipFinderParent);
+ }
+
+ @Override
+ public Collection<PIPEngine> getPIPEngines() {
+ return this.requestFinder.getPIPEngines();
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.java
new file mode 100755
index 0000000..ea68162
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.java
@@ -0,0 +1,163 @@
+/*
+ * 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;
+
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.pip.PIPFinder;
+import com.att.research.xacml.api.pip.PIPFinderFactory;
+import com.att.research.xacml.api.trace.TraceEngine;
+import com.att.research.xacml.api.trace.TraceEngineFactory;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContextFactory;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinder;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory;
+
+/**
+ * StdEvaluationContextFactory extends {@link com.att.research.xacmlatt.pdp.eval.EvaluationContextFactory} to implement
+ * the <code>getEvaluationContext</code> method with a standard {@link com.att.research.xacmlatt.pdp.eval.EvaluationContext}.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class StdEvaluationContextFactory extends EvaluationContextFactory {
+ private Log logger = LogFactory.getLog(this.getClass());
+ private PolicyFinder policyFinder;
+ private PIPFinder pipFinder;
+ private TraceEngine traceEngine;
+
+ /**
+ * Should this properties file be passed onward when instantiating the PolicyFinder
+ * and the PIPFinder?
+ *
+ * If yes, then we are assuming that the given properties were not just meant to
+ * configure the evaluation context, but all the other engines that get created.
+ *
+ * If no, then we are assuming the given properties were only meant for the evaluation
+ * context. But this implementation as of 7/14 does not even need the properties for
+ * configuring itseof.
+ *
+ * The problem is, the caller does not have the ability to instantiate the PIPFinder
+ * and PolicyFinder engines. This is done internally by the evaluation context. So how
+ * can they have the ability to customize PIP/Policy factories with their own properties
+ * object if the properties file isn't passed on?
+ *
+ * Thus, this class will pass on the properties file if given in the constructor.
+ *
+ */
+ protected Properties properties = null;
+
+ protected PolicyFinder getPolicyFinder() {
+ if (this.policyFinder == null) {
+ synchronized(this) {
+ if (this.policyFinder == null) {
+ try {
+ if (this.properties == null) {
+ if (this.logger.isDebugEnabled()) {
+ this.logger.debug("getting Policy finder using default properties");
+ }
+ PolicyFinderFactory policyFinderFactory = PolicyFinderFactory.newInstance();
+ this.policyFinder = policyFinderFactory.getPolicyFinder();
+ } else {
+ if (this.logger.isDebugEnabled()) {
+ this.logger.debug("getting Policy finder using properties: " + this.properties);
+ }
+ PolicyFinderFactory policyFinderFactory = PolicyFinderFactory.newInstance(this.properties);
+ this.policyFinder = policyFinderFactory.getPolicyFinder(this.properties);
+ }
+ } catch (Exception ex) {
+ this.logger.error("Exception getting PolicyFinder: " + ex.getMessage(), ex);
+ }
+ }
+ }
+ }
+ return this.policyFinder;
+ }
+
+ protected PIPFinder getPIPFinder() {
+ if (this.pipFinder == null) {
+ synchronized(this) {
+ if (this.pipFinder == null) {
+ try {
+ if (this.properties == null) {
+ if (this.logger.isDebugEnabled()) {
+ this.logger.debug("getting PIP finder using default properties");
+ }
+ PIPFinderFactory pipFinderFactory = PIPFinderFactory.newInstance();
+ this.pipFinder = pipFinderFactory.getFinder();
+ } else {
+ if (this.logger.isDebugEnabled()) {
+ this.logger.debug("getting PIP finder using properties: " + this.properties);
+ }
+ PIPFinderFactory pipFinderFactory = PIPFinderFactory.newInstance(this.properties);
+ this.pipFinder = pipFinderFactory.getFinder(this.properties);
+ }
+ } catch (Exception ex) {
+ this.logger.error("Exception getting PIPFinder: " + ex.toString(), ex);
+ }
+ }
+ }
+ }
+ return this.pipFinder;
+ }
+
+ protected TraceEngine getTraceEngine() {
+ if (this.traceEngine == null) {
+ synchronized(this) {
+ if (this.traceEngine == null) {
+ try {
+ if (this.properties == null) {
+ TraceEngineFactory traceEngineFactory = TraceEngineFactory.newInstance();
+ this.traceEngine = traceEngineFactory.getTraceEngine();
+ } else {
+ TraceEngineFactory traceEngineFactory = TraceEngineFactory.newInstance(this.properties);
+ this.traceEngine = traceEngineFactory.getTraceEngine(this.properties);
+ }
+ } catch (Exception ex) {
+ this.logger.error("Exception getting TraceEngine: " + ex.toString(), ex);
+ }
+ }
+ }
+ }
+ return this.traceEngine;
+ }
+
+ public StdEvaluationContextFactory() {
+ }
+
+ public StdEvaluationContextFactory(Properties properties) {
+ this.properties = properties;
+ }
+
+ @Override
+ public EvaluationContext getEvaluationContext(Request request) {
+ if (this.properties == null) {
+ return new StdEvaluationContext(request, this.getPolicyFinder(), this.getPIPFinder(), this.getTraceEngine());
+ } else {
+ return new StdEvaluationContext(request, this.getPolicyFinder(), this.getPIPFinder(), this.getTraceEngine(), this.properties);
+ }
+ }
+
+ @Override
+ public void setPolicyFinder(PolicyFinder policyFinderIn) {
+ this.policyFinder = policyFinderIn;
+ }
+
+ @Override
+ public void setPIPFinder(PIPFinder pipFinderIn) {
+ this.pipFinder = pipFinderIn;
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.java
new file mode 100755
index 0000000..04f8001
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.java
@@ -0,0 +1,70 @@
+/*
+ * 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;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinitionFactory;
+
+/**
+ * StdFunctionDefinitionFactory is the default {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinitionFactory} implementation
+ * used if no other <code>FunctionDefinitionFactory</code> implementation is supplied. It contains all of the standard XACML 3.0
+ * functions.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class StdFunctionDefinitionFactory extends FunctionDefinitionFactory {
+ private static Map<Identifier,FunctionDefinition> mapFunctionDefinitions = new HashMap<Identifier,FunctionDefinition>();
+ private static boolean needMapInit = true;
+
+ private static void register(FunctionDefinition functionDefinition) {
+ mapFunctionDefinitions.put(functionDefinition.getId(), functionDefinition);
+ }
+
+ private static void initMap() {
+ if (needMapInit) {
+ synchronized(mapFunctionDefinitions) {
+ if (needMapInit) {
+ needMapInit = false;
+ Field[] declaredFields = StdFunctions.class.getDeclaredFields();
+ for (Field field : declaredFields) {
+ if (Modifier.isStatic(field.getModifiers()) &&
+ field.getName().startsWith(StdFunctions.FD_PREFIX) &&
+ FunctionDefinition.class.isAssignableFrom(field.getType()) &&
+ Modifier.isPublic(field.getModifiers())
+ ) {
+ try {
+ register((FunctionDefinition)(field.get(null)));
+ } catch (IllegalAccessException ex) {
+
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public StdFunctionDefinitionFactory() {
+ initMap();
+ }
+
+ @Override
+ public FunctionDefinition getFunctionDefinition(Identifier functionId) {
+ return mapFunctionDefinitions.get(functionId);
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctions.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctions.java
new file mode 100755
index 0000000..b46dab1
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctions.java
@@ -0,0 +1,479 @@
+/*
+ * 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;
+
+import java.math.BigInteger;
+import java.net.URI;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.att.research.xacml.api.XACML1;
+import com.att.research.xacml.api.XACML2;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.Base64Binary;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacml.std.datatypes.HexBinary;
+import com.att.research.xacml.std.datatypes.IPAddress;
+import com.att.research.xacml.std.datatypes.ISO8601Date;
+import com.att.research.xacml.std.datatypes.ISO8601DateTime;
+import com.att.research.xacml.std.datatypes.ISO8601Time;
+import com.att.research.xacml.std.datatypes.RFC2396DomainName;
+import com.att.research.xacml.std.datatypes.RFC822Name;
+import com.att.research.xacml.std.datatypes.XPathDayTimeDuration;
+import com.att.research.xacml.std.datatypes.XPathYearMonthDuration;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionAccessPermitted;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionArithmetic;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBag;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagIsIn;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagOneAndOnly;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagSize;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionComparison;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionDateTimeArithmetic;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionEquality;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHigherOrderBag;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionLogical;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionNumberTypeConversion;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionRFC822NameMatch;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionRegexpMatch;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionSet;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionStringConversion;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionStringEqualIgnoreCase;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionStringFunctions;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionStringNormalize;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionTimeInRange;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionURIStringConcatenate;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionX500NameMatch;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionXPath;
+
+/**
+ * StdFunctions contains the {@link com.att.research.xacml.api.Identifier} values for the standard XACML functions.
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+@SuppressWarnings("deprecation")
+public class StdFunctions {
+ protected StdFunctions() {
+ }
+
+ public static final String FD_PREFIX = "FD_";
+
+ /*
+ * A.3.1 Equality predicates
+ */
+
+ public static final FunctionDefinition FD_STRING_EQUAL = new FunctionDefinitionEquality<String>(XACML3.ID_FUNCTION_STRING_EQUAL, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_STRING_EQUAL_IGNORE_CASE = new FunctionDefinitionStringEqualIgnoreCase(XACML3.ID_FUNCTION_STRING_EQUAL_IGNORE_CASE);
+ public static final FunctionDefinition FD_BOOLEAN_EQUAL = new FunctionDefinitionEquality<Boolean>(XACML3.ID_FUNCTION_BOOLEAN_EQUAL, DataTypes.DT_BOOLEAN);
+ public static final FunctionDefinition FD_INTEGER_EQUAL = new FunctionDefinitionEquality<BigInteger>(XACML3.ID_FUNCTION_INTEGER_EQUAL, DataTypes.DT_INTEGER);
+ public static final FunctionDefinition FD_DOUBLE_EQUAL = new FunctionDefinitionEquality<Double>(XACML3.ID_FUNCTION_DOUBLE_EQUAL, DataTypes.DT_DOUBLE);
+ public static final FunctionDefinition FD_DATE_EQUAL = new FunctionDefinitionEquality<ISO8601Date>(XACML3.ID_FUNCTION_DATE_EQUAL, DataTypes.DT_DATE);
+ public static final FunctionDefinition FD_TIME_EQUAL = new FunctionDefinitionEquality<ISO8601Time>(XACML3.ID_FUNCTION_TIME_EQUAL, DataTypes.DT_TIME);
+ public static final FunctionDefinition FD_DATETIME_EQUAL = new FunctionDefinitionEquality<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_EQUAL, DataTypes.DT_DATETIME);
+
+ // only difference between R3 and older (R1) versions of durations seem to be the identifiers, so send calls to the same place in either case
+ public static final FunctionDefinition FD_DAYTIMEDURATION_EQUAL_VERSION1 = new FunctionDefinitionEquality<XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_EQUAL, DataTypes.DT_DAYTIMEDURATION);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_EQUAL = new FunctionDefinitionEquality<XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_EQUAL, DataTypes.DT_DAYTIMEDURATION);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_EQUAL_VERSION1 = new FunctionDefinitionEquality<XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_EQUAL, DataTypes.DT_YEARMONTHDURATION);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_EQUAL = new FunctionDefinitionEquality<XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_EQUAL, DataTypes.DT_YEARMONTHDURATION);
+
+ // continue on with latest versions
+ public static final FunctionDefinition FD_ANYURI_EQUAL = new FunctionDefinitionEquality<URI>(XACML3.ID_FUNCTION_ANYURI_EQUAL, DataTypes.DT_ANYURI);
+ public static final FunctionDefinition FD_X500NAME_EQUAL = new FunctionDefinitionEquality<X500Principal>(XACML3.ID_FUNCTION_X500NAME_EQUAL, DataTypes.DT_X500NAME);
+ public static final FunctionDefinition FD_RFC822NAME_EQUAL = new FunctionDefinitionEquality<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_EQUAL, DataTypes.DT_RFC822NAME);
+ public static final FunctionDefinition FD_HEXBINARY_EQUAL = new FunctionDefinitionEquality<HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_EQUAL, DataTypes.DT_HEXBINARY);
+ public static final FunctionDefinition FD_BASE64BINARY_EQUAL = new FunctionDefinitionEquality<Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_EQUAL, DataTypes.DT_BASE64BINARY);
+
+
+
+
+ /*
+ * Arithmetic Functions (See A.3.2)
+ */
+
+ public static final FunctionDefinition FD_INTEGER_ADD = new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_ADD, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.ADD, 2);
+ public static final FunctionDefinition FD_DOUBLE_ADD = new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_DOUBLE_ADD, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.ADD, 2);
+ public static final FunctionDefinition FD_INTEGER_SUBTRACT = new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_SUBTRACT, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.SUBTRACT, 2);
+ public static final FunctionDefinition FD_DOUBLE_SUBTRACT = new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_DOUBLE_SUBTRACT, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.SUBTRACT, 2);
+ public static final FunctionDefinition FD_INTEGER_MULTIPLY = new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_MULTIPLY, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.MULTIPLY, 2);
+ public static final FunctionDefinition FD_DOUBLE_MULTIPLY = new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_DOUBLE_MULTIPLY, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.MULTIPLY, 2);
+ public static final FunctionDefinition FD_INTEGER_DIVIDE = new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_DIVIDE, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.DIVIDE, 2);
+ public static final FunctionDefinition FD_DOUBLE_DIVIDE = new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_DOUBLE_DIVIDE, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.DIVIDE, 2);
+ public static final FunctionDefinition FD_INTEGER_MOD = new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_MOD, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.MOD, 2);
+ public static final FunctionDefinition FD_INTEGER_ABS = new FunctionDefinitionArithmetic<BigInteger>(XACML3.ID_FUNCTION_INTEGER_ABS, DataTypes.DT_INTEGER, FunctionDefinitionArithmetic.OPERATION.ABS, 1);
+ public static final FunctionDefinition FD_DOUBLE_ABS = new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_DOUBLE_ABS, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.ABS, 1);
+ public static final FunctionDefinition FD_ROUND = new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_ROUND, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.ROUND, 1);
+ public static final FunctionDefinition FD_FLOOR = new FunctionDefinitionArithmetic<Double>(XACML3.ID_FUNCTION_FLOOR, DataTypes.DT_DOUBLE, FunctionDefinitionArithmetic.OPERATION.FLOOR, 1);
+
+
+
+
+ /*
+ * String Conversion Functions (See A.3.3)
+ */
+ public static final FunctionDefinition FD_STRING_NORMALIZE_SPACE = new FunctionDefinitionStringNormalize(XACML3.ID_FUNCTION_STRING_NORMALIZE_SPACE, FunctionDefinitionStringNormalize.OPERATION.SPACE);
+ public static final FunctionDefinition FD_STRING_NORMALIZE_TO_LOWER_CASE = new FunctionDefinitionStringNormalize(XACML3.ID_FUNCTION_STRING_NORMALIZE_TO_LOWER_CASE, FunctionDefinitionStringNormalize.OPERATION.LOWER_CASE);
+
+ /*
+ * Numeric Data-Type Conversion Functions (See A.3.4)
+ */
+ public static final FunctionDefinition FD_DOUBLE_TO_INTEGER = new FunctionDefinitionNumberTypeConversion<BigInteger,Double>(XACML3.ID_FUNCTION_DOUBLE_TO_INTEGER, DataTypes.DT_INTEGER, DataTypes.DT_DOUBLE);
+ public static final FunctionDefinition FD_INTEGER_TO_DOUBLE = new FunctionDefinitionNumberTypeConversion<Double,BigInteger>(XACML3.ID_FUNCTION_INTEGER_TO_DOUBLE, DataTypes.DT_DOUBLE, DataTypes.DT_INTEGER);
+
+
+ /*
+ * Logical Functions (See A.3.5)
+ */
+ public static final FunctionDefinition FD_OR = new FunctionDefinitionLogical(XACML3.ID_FUNCTION_OR, FunctionDefinitionLogical.OPERATION.OR);
+ public static final FunctionDefinition FD_AND = new FunctionDefinitionLogical(XACML3.ID_FUNCTION_AND, FunctionDefinitionLogical.OPERATION.AND);
+ public static final FunctionDefinition FD_N_OF = new FunctionDefinitionLogical(XACML3.ID_FUNCTION_N_OF, FunctionDefinitionLogical.OPERATION.N_OF);
+ public static final FunctionDefinition FD_NOT = new FunctionDefinitionLogical(XACML3.ID_FUNCTION_NOT, FunctionDefinitionLogical.OPERATION.NOT);
+
+
+ /*
+ * Numeric Comparison Functions (See A.3.6 of xacml-3.0-core-spec-os-en.doc)
+ */
+ public static final FunctionDefinition FD_INTEGER_GREATER_THAN = new FunctionDefinitionComparison<BigInteger>(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN, DataTypes.DT_INTEGER, FunctionDefinitionComparison.OPERATION.GREATER_THAN);
+ public static final FunctionDefinition FD_INTEGER_GREATER_THAN_OR_EQUAL = new FunctionDefinitionComparison<BigInteger>(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL, DataTypes.DT_INTEGER, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL);
+ public static final FunctionDefinition FD_INTEGER_LESS_THAN = new FunctionDefinitionComparison<BigInteger>(XACML3.ID_FUNCTION_INTEGER_LESS_THAN, DataTypes.DT_INTEGER, FunctionDefinitionComparison.OPERATION.LESS_THAN);
+ public static final FunctionDefinition FD_INTEGER_LESS_THAN_OR_EQUAL = new FunctionDefinitionComparison<BigInteger>(XACML3.ID_FUNCTION_INTEGER_LESS_THAN_OR_EQUAL, DataTypes.DT_INTEGER, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL);
+ public static final FunctionDefinition FD_DOUBLE_GREATER_THAN = new FunctionDefinitionComparison<Double>(XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN, DataTypes.DT_DOUBLE, FunctionDefinitionComparison.OPERATION.GREATER_THAN);
+ public static final FunctionDefinition FD_DOUBLE_GREATER_THAN_OR_EQUAL = new FunctionDefinitionComparison<Double>(XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN_OR_EQUAL, DataTypes.DT_DOUBLE, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL);
+ public static final FunctionDefinition FD_DOUBLE_LESS_THAN = new FunctionDefinitionComparison<Double>(XACML3.ID_FUNCTION_DOUBLE_LESS_THAN, DataTypes.DT_DOUBLE, FunctionDefinitionComparison.OPERATION.LESS_THAN);
+ public static final FunctionDefinition FD_DOUBLE_LESS_THAN_OR_EQUAL = new FunctionDefinitionComparison<Double>(XACML3.ID_FUNCTION_DOUBLE_LESS_THAN_OR_EQUAL, DataTypes.DT_DOUBLE, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL);
+
+
+ /*
+ * Date and Time Arithmetic Functions (See A.3.7)
+ */
+ public static final FunctionDefinition FD_DATETIME_ADD_DAYTIMEDURATION = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DATETIME_ADD_DAYTIMEDURATION, DataTypes.DT_DATETIME, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD);
+ public static final FunctionDefinition FD_DATETIME_ADD_DAYTIMEDURATION_VERSION1 = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DATETIME_ADD_DAYTIMEDURATION, DataTypes.DT_DATETIME, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD);
+ public static final FunctionDefinition FD_DATETIME_ADD_YEARMONTHDURATION = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathYearMonthDuration>(XACML3.ID_FUNCTION_DATETIME_ADD_YEARMONTHDURATION, DataTypes.DT_DATETIME, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD);
+ public static final FunctionDefinition FD_DATETIME_ADD_YEARMONTHDURATION_VERSION1 = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathYearMonthDuration>(XACML1.ID_FUNCTION_DATETIME_ADD_YEARMONTHDURATION, DataTypes.DT_DATETIME, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD);
+
+ public static final FunctionDefinition FD_DATETIME_SUBTRACT_DAYTIMEDURATION = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_DAYTIMEDURATION, DataTypes.DT_DATETIME, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT);
+ public static final FunctionDefinition FD_DATETIME_SUBTRACT_DAYTIMEDURATION_VERSION1 = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DATETIME_SUBTRACT_DAYTIMEDURATION, DataTypes.DT_DATETIME, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT);
+ public static final FunctionDefinition FD_DATETIME_SUBTRACT_YEARMONTHDURATION = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathYearMonthDuration>(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_YEARMONTHDURATION, DataTypes.DT_DATETIME, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT);
+ public static final FunctionDefinition FD_DATETIME_SUBTRACT_YEARMONTHDURATION_VERSION1 = new FunctionDefinitionDateTimeArithmetic<ISO8601DateTime,XPathYearMonthDuration>(XACML1.ID_FUNCTION_DATETIME_SUBTRACT_YEARMONTHDURATION, DataTypes.DT_DATETIME, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT);
+
+ public static final FunctionDefinition FD_DATE_ADD_YEARMONTHDURATION = new FunctionDefinitionDateTimeArithmetic<ISO8601Date,XPathYearMonthDuration>(XACML3.ID_FUNCTION_DATE_ADD_YEARMONTHDURATION, DataTypes.DT_DATE, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD);
+ public static final FunctionDefinition FD_DATE_ADD_YEARMONTHDURATION_VERSION1 = new FunctionDefinitionDateTimeArithmetic<ISO8601Date,XPathYearMonthDuration>(XACML1.ID_FUNCTION_DATE_ADD_YEARMONTHDURATION, DataTypes.DT_DATE, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.ADD);
+ public static final FunctionDefinition FD_DATE_SUBTRACT_YEARMONTHDURATION = new FunctionDefinitionDateTimeArithmetic<ISO8601Date,XPathYearMonthDuration>(XACML3.ID_FUNCTION_DATE_SUBTRACT_YEARMONTHDURATION, DataTypes.DT_DATE, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT);
+ public static final FunctionDefinition FD_DATE_SUBTRACT_YEARMONTHDURATION_VERSION1 = new FunctionDefinitionDateTimeArithmetic<ISO8601Date,XPathYearMonthDuration>(XACML1.ID_FUNCTION_DATE_SUBTRACT_YEARMONTHDURATION, DataTypes.DT_DATE, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionDateTimeArithmetic.OPERATION.SUBTRACT);
+
+
+ /*
+ * Non Numeric Comparison Functions (See A.3.8)
+ */
+ public static final FunctionDefinition FD_STRING_GREATER_THAN = new FunctionDefinitionComparison<String>(XACML3.ID_FUNCTION_STRING_GREATER_THAN, DataTypes.DT_STRING, FunctionDefinitionComparison.OPERATION.GREATER_THAN);
+ public static final FunctionDefinition FD_STRING_GREATER_THAN_OR_EQUAL = new FunctionDefinitionComparison<String>(XACML3.ID_FUNCTION_STRING_GREATER_THAN_OR_EQUAL, DataTypes.DT_STRING, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL);
+ public static final FunctionDefinition FD_STRING_LESS_THAN = new FunctionDefinitionComparison<String>(XACML3.ID_FUNCTION_STRING_LESS_THAN, DataTypes.DT_STRING, FunctionDefinitionComparison.OPERATION.LESS_THAN);
+ public static final FunctionDefinition FD_STRING_LESS_THAN_OR_EQUAL = new FunctionDefinitionComparison<String>(XACML3.ID_FUNCTION_STRING_LESS_THAN_OR_EQUAL, DataTypes.DT_STRING, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL);
+ public static final FunctionDefinition FD_TIME_GREATER_THAN = new FunctionDefinitionComparison<ISO8601Time>(XACML3.ID_FUNCTION_TIME_GREATER_THAN, DataTypes.DT_TIME, FunctionDefinitionComparison.OPERATION.GREATER_THAN);
+ public static final FunctionDefinition FD_TIME_GREATER_THAN_OR_EQUAL = new FunctionDefinitionComparison<ISO8601Time>(XACML3.ID_FUNCTION_TIME_GREATER_THAN_OR_EQUAL, DataTypes.DT_TIME, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL);
+ public static final FunctionDefinition FD_TIME_LESS_THAN = new FunctionDefinitionComparison<ISO8601Time>(XACML3.ID_FUNCTION_TIME_LESS_THAN, DataTypes.DT_TIME, FunctionDefinitionComparison.OPERATION.LESS_THAN);
+ public static final FunctionDefinition FD_TIME_LESS_THAN_OR_EQUAL = new FunctionDefinitionComparison<ISO8601Time>(XACML3.ID_FUNCTION_TIME_LESS_THAN_OR_EQUAL, DataTypes.DT_TIME, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL);
+ public static final FunctionDefinition FD_TIME_IN_RANGE = new FunctionDefinitionTimeInRange<ISO8601Time>(XACML3.ID_FUNCTION_TIME_IN_RANGE, DataTypes.DT_TIME);
+ public static final FunctionDefinition FD_DATE_GREATER_THAN = new FunctionDefinitionComparison<ISO8601Date>(XACML3.ID_FUNCTION_DATE_GREATER_THAN, DataTypes.DT_DATE, FunctionDefinitionComparison.OPERATION.GREATER_THAN);
+ public static final FunctionDefinition FD_DATE_GREATER_THAN_OR_EQUAL = new FunctionDefinitionComparison<ISO8601Date>(XACML3.ID_FUNCTION_DATE_GREATER_THAN_OR_EQUAL, DataTypes.DT_DATE, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL);
+ public static final FunctionDefinition FD_DATE_LESS_THAN = new FunctionDefinitionComparison<ISO8601Date>(XACML3.ID_FUNCTION_DATE_LESS_THAN, DataTypes.DT_DATE, FunctionDefinitionComparison.OPERATION.LESS_THAN);
+ public static final FunctionDefinition FD_DATE_LESS_THAN_OR_EQUAL = new FunctionDefinitionComparison<ISO8601Date>(XACML3.ID_FUNCTION_DATE_LESS_THAN_OR_EQUAL, DataTypes.DT_DATE, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL);
+ public static final FunctionDefinition FD_DATETIME_GREATER_THAN = new FunctionDefinitionComparison<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_GREATER_THAN, DataTypes.DT_DATETIME, FunctionDefinitionComparison.OPERATION.GREATER_THAN);
+ public static final FunctionDefinition FD_DATETIME_GREATER_THAN_OR_EQUAL = new FunctionDefinitionComparison<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_GREATER_THAN_OR_EQUAL, DataTypes.DT_DATETIME, FunctionDefinitionComparison.OPERATION.GREATER_THAN_EQUAL);
+ public static final FunctionDefinition FD_DATETIME_LESS_THAN = new FunctionDefinitionComparison<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_LESS_THAN, DataTypes.DT_DATETIME, FunctionDefinitionComparison.OPERATION.LESS_THAN);
+ public static final FunctionDefinition FD_DATETIME_LESS_THAN_OR_EQUAL = new FunctionDefinitionComparison<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_LESS_THAN_OR_EQUAL, DataTypes.DT_DATETIME, FunctionDefinitionComparison.OPERATION.LESS_THAN_EQUAL);
+
+
+
+ /*
+ * String functions (See A.3.9 of xacml-3.0-core-spec-os-en.doc)
+ */
+ public static final FunctionDefinition FD_BOOLEAN_FROM_STRING = new FunctionDefinitionStringConversion<Boolean,String>(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_STRING_FROM_BOOLEAN = new FunctionDefinitionStringConversion<String,Boolean>(XACML3.ID_FUNCTION_STRING_FROM_BOOLEAN, DataTypes.DT_STRING, DataTypes.DT_BOOLEAN);
+ public static final FunctionDefinition FD_INTEGER_FROM_STRING = new FunctionDefinitionStringConversion<BigInteger,String>(XACML3.ID_FUNCTION_INTEGER_FROM_STRING, DataTypes.DT_INTEGER, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_STRING_FROM_INTEGER = new FunctionDefinitionStringConversion<String,BigInteger>(XACML3.ID_FUNCTION_STRING_FROM_INTEGER, DataTypes.DT_STRING, DataTypes.DT_INTEGER);
+ public static final FunctionDefinition FD_DOUBLE_FROM_STRING = new FunctionDefinitionStringConversion<Double,String>(XACML3.ID_FUNCTION_DOUBLE_FROM_STRING, DataTypes.DT_DOUBLE, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_STRING_FROM_DOUBLE = new FunctionDefinitionStringConversion<String,Double>(XACML3.ID_FUNCTION_STRING_FROM_DOUBLE, DataTypes.DT_STRING, DataTypes.DT_DOUBLE);
+ public static final FunctionDefinition FD_TIME_FROM_STRING = new FunctionDefinitionStringConversion<ISO8601Time,String>(XACML3.ID_FUNCTION_TIME_FROM_STRING, DataTypes.DT_TIME, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_STRING_FROM_TIME = new FunctionDefinitionStringConversion<String,ISO8601Time>(XACML3.ID_FUNCTION_STRING_FROM_TIME, DataTypes.DT_STRING, DataTypes.DT_TIME);
+ public static final FunctionDefinition FD_DATE_FROM_STRING = new FunctionDefinitionStringConversion<ISO8601Date,String>(XACML3.ID_FUNCTION_DATE_FROM_STRING, DataTypes.DT_DATE, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_STRING_FROM_DATE = new FunctionDefinitionStringConversion<String,ISO8601Date>(XACML3.ID_FUNCTION_STRING_FROM_DATE, DataTypes.DT_STRING, DataTypes.DT_DATE);
+ public static final FunctionDefinition FD_DATETIME_FROM_STRING = new FunctionDefinitionStringConversion<ISO8601DateTime,String>(XACML3.ID_FUNCTION_DATETIME_FROM_STRING, DataTypes.DT_DATETIME, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_STRING_FROM_DATETIME = new FunctionDefinitionStringConversion<String,ISO8601DateTime>(XACML3.ID_FUNCTION_STRING_FROM_DATETIME, DataTypes.DT_STRING, DataTypes.DT_DATETIME);
+ public static final FunctionDefinition FD_ANYURI_FROM_STRING = new FunctionDefinitionStringConversion<URI,String>(XACML3.ID_FUNCTION_ANYURI_FROM_STRING, DataTypes.DT_ANYURI, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_STRING_FROM_ANYURI = new FunctionDefinitionStringConversion<String,URI>(XACML3.ID_FUNCTION_STRING_FROM_ANYURI, DataTypes.DT_STRING, DataTypes.DT_ANYURI);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_FROM_STRING = new FunctionDefinitionStringConversion<XPathDayTimeDuration,String>(XACML3.ID_FUNCTION_DAYTIMEDURATION_FROM_STRING, DataTypes.DT_DAYTIMEDURATION, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_STRING_FROM_DAYTIMEDURATION = new FunctionDefinitionStringConversion<String,XPathDayTimeDuration>(XACML3.ID_FUNCTION_STRING_FROM_DAYTIMEDURATION, DataTypes.DT_STRING, DataTypes.DT_DAYTIMEDURATION);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_FROM_STRING = new FunctionDefinitionStringConversion<XPathYearMonthDuration,String>(XACML3.ID_FUNCTION_YEARMONTHDURATION_FROM_STRING, DataTypes.DT_YEARMONTHDURATION, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_STRING_FROM_YEARMONTHDURATION = new FunctionDefinitionStringConversion<String,XPathYearMonthDuration>(XACML3.ID_FUNCTION_STRING_FROM_YEARMONTHDURATION, DataTypes.DT_STRING, DataTypes.DT_YEARMONTHDURATION);
+ public static final FunctionDefinition FD_X500NAME_FROM_STRING = new FunctionDefinitionStringConversion<X500Principal,String>(XACML3.ID_FUNCTION_X500NAME_FROM_STRING, DataTypes.DT_X500NAME, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_STRING_FROM_X500NAME = new FunctionDefinitionStringConversion<String,X500Principal>(XACML3.ID_FUNCTION_STRING_FROM_X500NAME, DataTypes.DT_STRING, DataTypes.DT_X500NAME);
+ public static final FunctionDefinition FD_RFC822NAME_FROM_STRING = new FunctionDefinitionStringConversion<RFC822Name,String>(XACML3.ID_FUNCTION_RFC822NAME_FROM_STRING, DataTypes.DT_RFC822NAME, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_STRING_FROM_RFC822NAME = new FunctionDefinitionStringConversion<String,RFC822Name>(XACML3.ID_FUNCTION_STRING_FROM_RFC822NAME, DataTypes.DT_STRING, DataTypes.DT_RFC822NAME);
+ public static final FunctionDefinition FD_IPADDRESS_FROM_STRING = new FunctionDefinitionStringConversion<IPAddress,String>(XACML3.ID_FUNCTION_IPADDRESS_FROM_STRING, DataTypes.DT_IPADDRESS, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_STRING_FROM_IPADDRESS = new FunctionDefinitionStringConversion<String,IPAddress>(XACML3.ID_FUNCTION_STRING_FROM_IPADDRESS, DataTypes.DT_STRING, DataTypes.DT_IPADDRESS);
+ public static final FunctionDefinition FD_DNSNAME_FROM_STRING = new FunctionDefinitionStringConversion<RFC2396DomainName,String>(XACML3.ID_FUNCTION_DNSNAME_FROM_STRING, DataTypes.DT_DNSNAME, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_STRING_FROM_DNSNAME = new FunctionDefinitionStringConversion<String,RFC2396DomainName>(XACML3.ID_FUNCTION_STRING_FROM_DNSNAME, DataTypes.DT_STRING, DataTypes.DT_DNSNAME);
+
+ // String Functions not converting Strings to/from DataType objects
+ public static final FunctionDefinition FD_STRING_CONCATENATE = new FunctionDefinitionStringFunctions<String,String>(XACML3.ID_FUNCTION_STRING_CONCATENATE, DataTypes.DT_STRING, DataTypes.DT_STRING, FunctionDefinitionStringFunctions.OPERATION.CONCATENATE);
+ public static final FunctionDefinition FD_STRING_STARTS_WITH = new FunctionDefinitionStringFunctions<Boolean,String>(XACML3.ID_FUNCTION_STRING_STARTS_WITH, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionStringFunctions.OPERATION.STARTS_WITH);
+ public static final FunctionDefinition FD_ANYURI_STARTS_WITH = new FunctionDefinitionStringFunctions<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_STARTS_WITH, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionStringFunctions.OPERATION.STARTS_WITH);
+ public static final FunctionDefinition FD_STRING_ENDS_WITH = new FunctionDefinitionStringFunctions<Boolean,String>(XACML3.ID_FUNCTION_STRING_ENDS_WITH, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionStringFunctions.OPERATION.ENDS_WITH);
+ public static final FunctionDefinition FD_ANYURI_ENDS_WITH = new FunctionDefinitionStringFunctions<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_ENDS_WITH, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionStringFunctions.OPERATION.ENDS_WITH);
+ public static final FunctionDefinition FD_STRING_CONTAINS = new FunctionDefinitionStringFunctions<Boolean,String>(XACML3.ID_FUNCTION_STRING_CONTAINS, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionStringFunctions.OPERATION.CONTAINS);
+ public static final FunctionDefinition FD_ANYURI_CONTAINS = new FunctionDefinitionStringFunctions<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_CONTAINS, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionStringFunctions.OPERATION.CONTAINS);
+ public static final FunctionDefinition FD_STRING_SUBSTRING = new FunctionDefinitionStringFunctions<String,String>(XACML3.ID_FUNCTION_STRING_SUBSTRING, DataTypes.DT_STRING, DataTypes.DT_STRING, FunctionDefinitionStringFunctions.OPERATION.SUBSTRING);
+ public static final FunctionDefinition FD_ANYURI_SUBSTRING = new FunctionDefinitionStringFunctions<String, URI>(XACML3.ID_FUNCTION_ANYURI_SUBSTRING, DataTypes.DT_STRING, DataTypes.DT_ANYURI, FunctionDefinitionStringFunctions.OPERATION.SUBSTRING);
+
+ /*
+ * Bag functions (See A.3.10)
+ */
+ public static final FunctionDefinition FD_STRING_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<String>(XACML3.ID_FUNCTION_STRING_ONE_AND_ONLY, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_BOOLEAN_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<Boolean>(XACML3.ID_FUNCTION_BOOLEAN_ONE_AND_ONLY, DataTypes.DT_BOOLEAN);
+ public static final FunctionDefinition FD_INTEGER_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<BigInteger>(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY, DataTypes.DT_INTEGER);
+ public static final FunctionDefinition FD_DOUBLE_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<Double>(XACML3.ID_FUNCTION_DOUBLE_ONE_AND_ONLY, DataTypes.DT_DOUBLE);
+ public static final FunctionDefinition FD_TIME_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<ISO8601Time>(XACML3.ID_FUNCTION_TIME_ONE_AND_ONLY, DataTypes.DT_TIME);
+ public static final FunctionDefinition FD_DATE_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<ISO8601Date>(XACML3.ID_FUNCTION_DATE_ONE_AND_ONLY, DataTypes.DT_DATE);
+ public static final FunctionDefinition FD_DATETIME_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_ONE_AND_ONLY, DataTypes.DT_DATETIME);
+ public static final FunctionDefinition FD_ANYURI_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<URI>(XACML3.ID_FUNCTION_ANYURI_ONE_AND_ONLY, DataTypes.DT_ANYURI);
+ public static final FunctionDefinition FD_HEXBINARY_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_ONE_AND_ONLY, DataTypes.DT_HEXBINARY);
+ public static final FunctionDefinition FD_BASE64BINARY_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_ONE_AND_ONLY, DataTypes.DT_BASE64BINARY);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_ONE_AND_ONLY, DataTypes.DT_DAYTIMEDURATION);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_ONE_AND_ONLY_VERSION1 = new FunctionDefinitionBagOneAndOnly<XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_ONE_AND_ONLY, DataTypes.DT_DAYTIMEDURATION);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_ONE_AND_ONLY, DataTypes.DT_YEARMONTHDURATION);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_ONE_AND_ONLY_VERSION1 = new FunctionDefinitionBagOneAndOnly<XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_ONE_AND_ONLY, DataTypes.DT_YEARMONTHDURATION);
+ public static final FunctionDefinition FD_X500NAME_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<X500Principal>(XACML3.ID_FUNCTION_X500NAME_ONE_AND_ONLY, DataTypes.DT_X500NAME);
+ public static final FunctionDefinition FD_RFC822NAME_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_ONE_AND_ONLY, DataTypes.DT_RFC822NAME);
+ public static final FunctionDefinition FD_IPADDRESS_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<IPAddress>(XACML3.ID_FUNCTION_IPADDRESS_ONE_AND_ONLY, DataTypes.DT_IPADDRESS);
+ public static final FunctionDefinition FD_DNSNAME_ONE_AND_ONLY = new FunctionDefinitionBagOneAndOnly<RFC2396DomainName>(XACML3.ID_FUNCTION_DNSNAME_ONE_AND_ONLY, DataTypes.DT_DNSNAME);
+
+ public static final FunctionDefinition FD_STRING_BAG_SIZE = new FunctionDefinitionBagSize<String>(XACML3.ID_FUNCTION_STRING_BAG_SIZE, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_BOOLEAN_BAG_SIZE = new FunctionDefinitionBagSize<Boolean>(XACML3.ID_FUNCTION_BOOLEAN_BAG_SIZE, DataTypes.DT_BOOLEAN);
+ public static final FunctionDefinition FD_INTEGER_BAG_SIZE = new FunctionDefinitionBagSize<BigInteger>(XACML3.ID_FUNCTION_INTEGER_BAG_SIZE, DataTypes.DT_INTEGER);
+ public static final FunctionDefinition FD_DOUBLE_BAG_SIZE = new FunctionDefinitionBagSize<Double>(XACML3.ID_FUNCTION_DOUBLE_BAG_SIZE, DataTypes.DT_DOUBLE);
+ public static final FunctionDefinition FD_TIME_BAG_SIZE = new FunctionDefinitionBagSize<ISO8601Time>(XACML3.ID_FUNCTION_TIME_BAG_SIZE, DataTypes.DT_TIME);
+ public static final FunctionDefinition FD_DATE_BAG_SIZE = new FunctionDefinitionBagSize<ISO8601Date>(XACML3.ID_FUNCTION_DATE_BAG_SIZE, DataTypes.DT_DATE);
+ public static final FunctionDefinition FD_DATETIME_BAG_SIZE = new FunctionDefinitionBagSize<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_BAG_SIZE, DataTypes.DT_DATETIME);
+ public static final FunctionDefinition FD_ANYURI_BAG_SIZE = new FunctionDefinitionBagSize<URI>(XACML3.ID_FUNCTION_ANYURI_BAG_SIZE, DataTypes.DT_ANYURI);
+ public static final FunctionDefinition FD_HEXBINARY_BAG_SIZE = new FunctionDefinitionBagSize<HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_BAG_SIZE, DataTypes.DT_HEXBINARY);
+ public static final FunctionDefinition FD_BASE64BINARY_BAG_SIZE = new FunctionDefinitionBagSize<Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_BAG_SIZE, DataTypes.DT_BASE64BINARY);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_BAG_SIZE = new FunctionDefinitionBagSize<XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_BAG_SIZE, DataTypes.DT_DAYTIMEDURATION);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_BAG_SIZE_VERSION1 = new FunctionDefinitionBagSize<XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_BAG_SIZE, DataTypes.DT_DAYTIMEDURATION);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_BAG_SIZE = new FunctionDefinitionBagSize<XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_BAG_SIZE, DataTypes.DT_YEARMONTHDURATION);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_BAG_SIZE_VERSION1 = new FunctionDefinitionBagSize<XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_BAG_SIZE, DataTypes.DT_YEARMONTHDURATION);
+ public static final FunctionDefinition FD_X500NAME_BAG_SIZE = new FunctionDefinitionBagSize<X500Principal>(XACML3.ID_FUNCTION_X500NAME_BAG_SIZE, DataTypes.DT_X500NAME);
+ public static final FunctionDefinition FD_RFC822NAME_BAG_SIZE = new FunctionDefinitionBagSize<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_BAG_SIZE, DataTypes.DT_RFC822NAME);
+ public static final FunctionDefinition FD_IPADDRESS_BAG_SIZE = new FunctionDefinitionBagSize<IPAddress>(XACML3.ID_FUNCTION_IPADDRESS_BAG_SIZE, DataTypes.DT_IPADDRESS);
+ public static final FunctionDefinition FD_DNSNAME_BAG_SIZE = new FunctionDefinitionBagSize<RFC2396DomainName>(XACML3.ID_FUNCTION_DNSNAME_BAG_SIZE, DataTypes.DT_DNSNAME);
+
+ public static final FunctionDefinition FD_STRING_IS_IN = new FunctionDefinitionBagIsIn<String>(XACML3.ID_FUNCTION_STRING_IS_IN, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_BOOLEAN_IS_IN = new FunctionDefinitionBagIsIn<Boolean>(XACML3.ID_FUNCTION_BOOLEAN_IS_IN, DataTypes.DT_BOOLEAN);
+ public static final FunctionDefinition FD_INTEGER_IS_IN = new FunctionDefinitionBagIsIn<BigInteger>(XACML3.ID_FUNCTION_INTEGER_IS_IN, DataTypes.DT_INTEGER);
+ public static final FunctionDefinition FD_DOUBLE_IS_IN = new FunctionDefinitionBagIsIn<Double>(XACML3.ID_FUNCTION_DOUBLE_IS_IN, DataTypes.DT_DOUBLE);
+ public static final FunctionDefinition FD_TIME_IS_IN = new FunctionDefinitionBagIsIn<ISO8601Time>(XACML3.ID_FUNCTION_TIME_IS_IN, DataTypes.DT_TIME);
+ public static final FunctionDefinition FD_DATE_IS_IN = new FunctionDefinitionBagIsIn<ISO8601Date>(XACML3.ID_FUNCTION_DATE_IS_IN, DataTypes.DT_DATE);
+ public static final FunctionDefinition FD_DATETIME_IS_IN = new FunctionDefinitionBagIsIn<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_IS_IN, DataTypes.DT_DATETIME);
+ public static final FunctionDefinition FD_ANYURI_IS_IN = new FunctionDefinitionBagIsIn<URI>(XACML3.ID_FUNCTION_ANYURI_IS_IN, DataTypes.DT_ANYURI);
+ public static final FunctionDefinition FD_HEXBINARY_IS_IN = new FunctionDefinitionBagIsIn<HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_IS_IN, DataTypes.DT_HEXBINARY);
+ public static final FunctionDefinition FD_BASE64BINARY_IS_IN = new FunctionDefinitionBagIsIn<Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_IS_IN, DataTypes.DT_BASE64BINARY);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_IS_IN = new FunctionDefinitionBagIsIn<XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_IS_IN, DataTypes.DT_DAYTIMEDURATION);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_IS_IN_VERSION1 = new FunctionDefinitionBagIsIn<XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_IS_IN, DataTypes.DT_DAYTIMEDURATION);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_IS_IN = new FunctionDefinitionBagIsIn<XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_IS_IN, DataTypes.DT_YEARMONTHDURATION);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_IS_IN_VERSION1 = new FunctionDefinitionBagIsIn<XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_IS_IN, DataTypes.DT_YEARMONTHDURATION);
+ public static final FunctionDefinition FD_X500NAME_IS_IN = new FunctionDefinitionBagIsIn<X500Principal>(XACML3.ID_FUNCTION_X500NAME_IS_IN, DataTypes.DT_X500NAME);
+ public static final FunctionDefinition FD_RFC822NAME_IS_IN = new FunctionDefinitionBagIsIn<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_IS_IN, DataTypes.DT_RFC822NAME);
+ public static final FunctionDefinition FD_IPADDRESS_IS_IN = new FunctionDefinitionBagIsIn<IPAddress>(XACML3.ID_FUNCTION_IPADDRESS_IS_IN, DataTypes.DT_IPADDRESS);
+ public static final FunctionDefinition FD_DNSNAME_IS_IN = new FunctionDefinitionBagIsIn<RFC2396DomainName>(XACML3.ID_FUNCTION_DNSNAME_IS_IN, DataTypes.DT_DNSNAME);
+
+ public static final FunctionDefinition FD_STRING_BAG = new FunctionDefinitionBag<String>(XACML3.ID_FUNCTION_STRING_BAG, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_BOOLEAN_BAG = new FunctionDefinitionBag<Boolean>(XACML3.ID_FUNCTION_BOOLEAN_BAG, DataTypes.DT_BOOLEAN);
+ public static final FunctionDefinition FD_INTEGER_BAG = new FunctionDefinitionBag<BigInteger>(XACML3.ID_FUNCTION_INTEGER_BAG, DataTypes.DT_INTEGER);
+ public static final FunctionDefinition FD_DOUBLE_BAG = new FunctionDefinitionBag<Double>(XACML3.ID_FUNCTION_DOUBLE_BAG, DataTypes.DT_DOUBLE);
+ public static final FunctionDefinition FD_TIME_BAG = new FunctionDefinitionBag<ISO8601Time>(XACML3.ID_FUNCTION_TIME_BAG, DataTypes.DT_TIME);
+ public static final FunctionDefinition FD_DATE_BAG = new FunctionDefinitionBag<ISO8601Date>(XACML3.ID_FUNCTION_DATE_BAG, DataTypes.DT_DATE);
+ public static final FunctionDefinition FD_DATETIME_BAG = new FunctionDefinitionBag<ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_BAG, DataTypes.DT_DATETIME);
+ public static final FunctionDefinition FD_ANYURI_BAG = new FunctionDefinitionBag<URI>(XACML3.ID_FUNCTION_ANYURI_BAG, DataTypes.DT_ANYURI);
+ public static final FunctionDefinition FD_HEXBINARY_BAG = new FunctionDefinitionBag<HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_BAG, DataTypes.DT_HEXBINARY);
+ public static final FunctionDefinition FD_BASE64BINARY_BAG = new FunctionDefinitionBag<Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_BAG, DataTypes.DT_BASE64BINARY);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_BAG = new FunctionDefinitionBag<XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_BAG, DataTypes.DT_DAYTIMEDURATION);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_BAG_VERSION1 = new FunctionDefinitionBag<XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_BAG, DataTypes.DT_DAYTIMEDURATION);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_BAG = new FunctionDefinitionBag<XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_BAG, DataTypes.DT_YEARMONTHDURATION);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_BAG_VERSION1 = new FunctionDefinitionBag<XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_BAG, DataTypes.DT_YEARMONTHDURATION);
+ public static final FunctionDefinition FD_X500NAME_BAG = new FunctionDefinitionBag<X500Principal>(XACML3.ID_FUNCTION_X500NAME_BAG, DataTypes.DT_X500NAME);
+ public static final FunctionDefinition FD_RFC822NAME_BAG = new FunctionDefinitionBag<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_BAG, DataTypes.DT_RFC822NAME);
+ public static final FunctionDefinition FD_IPADDRESS_BAG = new FunctionDefinitionBag<IPAddress>(XACML3.ID_FUNCTION_IPADDRESS_BAG, DataTypes.DT_IPADDRESS);
+ public static final FunctionDefinition FD_DNSNAME_BAG = new FunctionDefinitionBag<RFC2396DomainName>(XACML3.ID_FUNCTION_DNSNAME_BAG, DataTypes.DT_DNSNAME);
+
+
+ /*
+ * Set Functions (See A.3.11)
+ *
+ * (According to section 10.2.8, this doesn't seem to include
+ * IPAddress or DNSName datatype). This is because Xacml 3.0 did NOT
+ * define an equality operator for these 2 types. See discussion:
+ *
+ * https://lists.oasis-open.org/archives/xacml/201104/msg00014.html
+ *
+ * Also section 10.2.8 is missing XPathExpression versions of these functions.
+ *
+ */
+ public static final FunctionDefinition FD_STRING_INTERSECTION = new FunctionDefinitionSet<String,String>(XACML3.ID_FUNCTION_STRING_INTERSECTION, DataTypes.DT_STRING, DataTypes.DT_STRING, FunctionDefinitionSet.OPERATION.INTERSECTION);
+ public static final FunctionDefinition FD_BOOLEAN_INTERSECTION = new FunctionDefinitionSet<Boolean,Boolean>(XACML3.ID_FUNCTION_BOOLEAN_INTERSECTION, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, FunctionDefinitionSet.OPERATION.INTERSECTION);
+ public static final FunctionDefinition FD_INTEGER_INTERSECTION = new FunctionDefinitionSet<BigInteger,BigInteger>(XACML3.ID_FUNCTION_INTEGER_INTERSECTION, DataTypes.DT_INTEGER, DataTypes.DT_INTEGER, FunctionDefinitionSet.OPERATION.INTERSECTION);
+ public static final FunctionDefinition FD_DOUBLE_INTERSECTION = new FunctionDefinitionSet<Double,Double>(XACML3.ID_FUNCTION_DOUBLE_INTERSECTION, DataTypes.DT_DOUBLE, DataTypes.DT_DOUBLE, FunctionDefinitionSet.OPERATION.INTERSECTION);
+ public static final FunctionDefinition FD_TIME_INTERSECTION = new FunctionDefinitionSet<ISO8601Time,ISO8601Time>(XACML3.ID_FUNCTION_TIME_INTERSECTION, DataTypes.DT_TIME, DataTypes.DT_TIME, FunctionDefinitionSet.OPERATION.INTERSECTION);
+ public static final FunctionDefinition FD_DATE_INTERSECTION = new FunctionDefinitionSet<ISO8601Date,ISO8601Date>(XACML3.ID_FUNCTION_DATE_INTERSECTION, DataTypes.DT_DATE, DataTypes.DT_DATE, FunctionDefinitionSet.OPERATION.INTERSECTION);
+ public static final FunctionDefinition FD_DATETIME_INTERSECTION = new FunctionDefinitionSet<ISO8601DateTime, ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_INTERSECTION, DataTypes.DT_DATETIME, DataTypes.DT_DATETIME, FunctionDefinitionSet.OPERATION.INTERSECTION);
+ public static final FunctionDefinition FD_ANYURI_INTERSECTION = new FunctionDefinitionSet<URI, URI>(XACML3.ID_FUNCTION_ANYURI_INTERSECTION, DataTypes.DT_ANYURI, DataTypes.DT_ANYURI, FunctionDefinitionSet.OPERATION.INTERSECTION);
+ public static final FunctionDefinition FD_HEXBINARY_INTERSECTION = new FunctionDefinitionSet<HexBinary,HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_INTERSECTION, DataTypes.DT_HEXBINARY, DataTypes.DT_HEXBINARY, FunctionDefinitionSet.OPERATION.INTERSECTION);
+ public static final FunctionDefinition FD_BASE64BINARY_INTERSECTION = new FunctionDefinitionSet<Base64Binary,Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_INTERSECTION, DataTypes.DT_BASE64BINARY, DataTypes.DT_BASE64BINARY, FunctionDefinitionSet.OPERATION.INTERSECTION);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_INTERSECTION = new FunctionDefinitionSet<XPathDayTimeDuration,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_INTERSECTION, DataTypes.DT_DAYTIMEDURATION, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.INTERSECTION);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_INTERSECTION_VERSION1 = new FunctionDefinitionSet<XPathDayTimeDuration,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_INTERSECTION, DataTypes.DT_DAYTIMEDURATION, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.INTERSECTION);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_INTERSECTION = new FunctionDefinitionSet<XPathYearMonthDuration,XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_INTERSECTION, DataTypes.DT_YEARMONTHDURATION, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.INTERSECTION);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_INTERSECTION_VERSION1 = new FunctionDefinitionSet<XPathYearMonthDuration,XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_INTERSECTION, DataTypes.DT_YEARMONTHDURATION, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.INTERSECTION);
+ public static final FunctionDefinition FD_X500NAME_INTERSECTION = new FunctionDefinitionSet<X500Principal,X500Principal>(XACML3.ID_FUNCTION_X500NAME_INTERSECTION, DataTypes.DT_X500NAME, DataTypes.DT_X500NAME, FunctionDefinitionSet.OPERATION.INTERSECTION);
+ public static final FunctionDefinition FD_RFC822NAME_INTERSECTION = new FunctionDefinitionSet<RFC822Name,RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_INTERSECTION, DataTypes.DT_RFC822NAME, DataTypes.DT_RFC822NAME, FunctionDefinitionSet.OPERATION.INTERSECTION);
+
+ public static final FunctionDefinition FD_STRING_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,String>(XACML3.ID_FUNCTION_STRING_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+ public static final FunctionDefinition FD_BOOLEAN_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,Boolean>(XACML3.ID_FUNCTION_BOOLEAN_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+ public static final FunctionDefinition FD_INTEGER_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,BigInteger>(XACML3.ID_FUNCTION_INTEGER_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_INTEGER, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+ public static final FunctionDefinition FD_DOUBLE_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,Double>(XACML3.ID_FUNCTION_DOUBLE_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_DOUBLE, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+ public static final FunctionDefinition FD_TIME_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,ISO8601Time>(XACML3.ID_FUNCTION_TIME_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_TIME, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+ public static final FunctionDefinition FD_DATE_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,ISO8601Date>(XACML3.ID_FUNCTION_DATE_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_DATE, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+ public static final FunctionDefinition FD_DATETIME_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean, ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_DATETIME, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+ public static final FunctionDefinition FD_ANYURI_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+ public static final FunctionDefinition FD_HEXBINARY_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_HEXBINARY, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+ public static final FunctionDefinition FD_BASE64BINARY_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_BASE64BINARY, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF_VERSION1 = new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF_VERSION1 = new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+ public static final FunctionDefinition FD_X500NAME_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,X500Principal>(XACML3.ID_FUNCTION_X500NAME_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_X500NAME, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+ public static final FunctionDefinition FD_RFC822NAME_AT_LEAST_ONE_MEMBER_OF = new FunctionDefinitionSet<Boolean,RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_AT_LEAST_ONE_MEMBER_OF, DataTypes.DT_BOOLEAN, DataTypes.DT_RFC822NAME, FunctionDefinitionSet.OPERATION.AT_LEAST_ONE_MEMBER_OF);
+
+ public static final FunctionDefinition FD_STRING_UNION = new FunctionDefinitionSet<String,String>(XACML3.ID_FUNCTION_STRING_UNION, DataTypes.DT_STRING, DataTypes.DT_STRING, FunctionDefinitionSet.OPERATION.UNION);
+ public static final FunctionDefinition FD_BOOLEAN_UNION = new FunctionDefinitionSet<Boolean,Boolean>(XACML3.ID_FUNCTION_BOOLEAN_UNION, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, FunctionDefinitionSet.OPERATION.UNION);
+ public static final FunctionDefinition FD_INTEGER_UNION = new FunctionDefinitionSet<BigInteger,BigInteger>(XACML3.ID_FUNCTION_INTEGER_UNION, DataTypes.DT_INTEGER, DataTypes.DT_INTEGER, FunctionDefinitionSet.OPERATION.UNION);
+ public static final FunctionDefinition FD_DOUBLE_UNION = new FunctionDefinitionSet<Double,Double>(XACML3.ID_FUNCTION_DOUBLE_UNION, DataTypes.DT_DOUBLE, DataTypes.DT_DOUBLE, FunctionDefinitionSet.OPERATION.UNION);
+ public static final FunctionDefinition FD_TIME_UNION = new FunctionDefinitionSet<ISO8601Time,ISO8601Time>(XACML3.ID_FUNCTION_TIME_UNION, DataTypes.DT_TIME, DataTypes.DT_TIME, FunctionDefinitionSet.OPERATION.UNION);
+ public static final FunctionDefinition FD_DATE_UNION = new FunctionDefinitionSet<ISO8601Date,ISO8601Date>(XACML3.ID_FUNCTION_DATE_UNION, DataTypes.DT_DATE, DataTypes.DT_DATE, FunctionDefinitionSet.OPERATION.UNION);
+ public static final FunctionDefinition FD_DATETIME_UNION = new FunctionDefinitionSet<ISO8601DateTime, ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_UNION, DataTypes.DT_DATETIME, DataTypes.DT_DATETIME, FunctionDefinitionSet.OPERATION.UNION);
+ public static final FunctionDefinition FD_ANYURI_UNION = new FunctionDefinitionSet<URI, URI>(XACML3.ID_FUNCTION_ANYURI_UNION, DataTypes.DT_ANYURI, DataTypes.DT_ANYURI, FunctionDefinitionSet.OPERATION.UNION);
+ public static final FunctionDefinition FD_HEXBINARY_UNION = new FunctionDefinitionSet<HexBinary,HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_UNION, DataTypes.DT_HEXBINARY, DataTypes.DT_HEXBINARY, FunctionDefinitionSet.OPERATION.UNION);
+ public static final FunctionDefinition FD_BASE64BINARY_UNION = new FunctionDefinitionSet<Base64Binary,Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_UNION, DataTypes.DT_BASE64BINARY, DataTypes.DT_BASE64BINARY, FunctionDefinitionSet.OPERATION.UNION);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_UNION = new FunctionDefinitionSet<XPathDayTimeDuration,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_UNION, DataTypes.DT_DAYTIMEDURATION, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.UNION);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_UNION_VERSION1 = new FunctionDefinitionSet<XPathDayTimeDuration,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_UNION, DataTypes.DT_DAYTIMEDURATION, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.UNION);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_UNION = new FunctionDefinitionSet<XPathYearMonthDuration,XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_UNION, DataTypes.DT_YEARMONTHDURATION, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.UNION);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_UNION_VERSION1 = new FunctionDefinitionSet<XPathYearMonthDuration,XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_UNION, DataTypes.DT_YEARMONTHDURATION, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.UNION);
+ public static final FunctionDefinition FD_X500NAME_UNION = new FunctionDefinitionSet<X500Principal,X500Principal>(XACML3.ID_FUNCTION_X500NAME_UNION, DataTypes.DT_X500NAME, DataTypes.DT_X500NAME, FunctionDefinitionSet.OPERATION.UNION);
+ public static final FunctionDefinition FD_RFC822NAME_UNION = new FunctionDefinitionSet<RFC822Name,RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_UNION, DataTypes.DT_RFC822NAME, DataTypes.DT_RFC822NAME, FunctionDefinitionSet.OPERATION.UNION);
+
+ public static final FunctionDefinition FD_STRING_SUBSET = new FunctionDefinitionSet<Boolean,String>(XACML3.ID_FUNCTION_STRING_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionSet.OPERATION.SUBSET);
+ public static final FunctionDefinition FD_BOOLEAN_SUBSET = new FunctionDefinitionSet<Boolean,Boolean>(XACML3.ID_FUNCTION_BOOLEAN_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, FunctionDefinitionSet.OPERATION.SUBSET);
+ public static final FunctionDefinition FD_INTEGER_SUBSET = new FunctionDefinitionSet<Boolean,BigInteger>(XACML3.ID_FUNCTION_INTEGER_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_INTEGER, FunctionDefinitionSet.OPERATION.SUBSET);
+ public static final FunctionDefinition FD_DOUBLE_SUBSET = new FunctionDefinitionSet<Boolean,Double>(XACML3.ID_FUNCTION_DOUBLE_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_DOUBLE, FunctionDefinitionSet.OPERATION.SUBSET);
+ public static final FunctionDefinition FD_TIME_SUBSET = new FunctionDefinitionSet<Boolean,ISO8601Time>(XACML3.ID_FUNCTION_TIME_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_TIME, FunctionDefinitionSet.OPERATION.SUBSET);
+ public static final FunctionDefinition FD_DATE_SUBSET = new FunctionDefinitionSet<Boolean,ISO8601Date>(XACML3.ID_FUNCTION_DATE_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_DATE, FunctionDefinitionSet.OPERATION.SUBSET);
+ public static final FunctionDefinition FD_DATETIME_SUBSET = new FunctionDefinitionSet<Boolean, ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_DATETIME, FunctionDefinitionSet.OPERATION.SUBSET);
+ public static final FunctionDefinition FD_ANYURI_SUBSET = new FunctionDefinitionSet<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionSet.OPERATION.SUBSET);
+ public static final FunctionDefinition FD_HEXBINARY_SUBSET = new FunctionDefinitionSet<Boolean,HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_HEXBINARY, FunctionDefinitionSet.OPERATION.SUBSET);
+ public static final FunctionDefinition FD_BASE64BINARY_SUBSET = new FunctionDefinitionSet<Boolean,Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_BASE64BINARY, FunctionDefinitionSet.OPERATION.SUBSET);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_SUBSET = new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.SUBSET);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_SUBSET_VERSION1 = new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.SUBSET);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_SUBSET = new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.SUBSET);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_SUBSET_VERSION1 = new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.SUBSET);
+ public static final FunctionDefinition FD_X500NAME_SUBSET = new FunctionDefinitionSet<Boolean,X500Principal>(XACML3.ID_FUNCTION_X500NAME_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_X500NAME, FunctionDefinitionSet.OPERATION.SUBSET);
+ public static final FunctionDefinition FD_RFC822NAME_SUBSET = new FunctionDefinitionSet<Boolean,RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_SUBSET, DataTypes.DT_BOOLEAN, DataTypes.DT_RFC822NAME, FunctionDefinitionSet.OPERATION.SUBSET);
+
+ public static final FunctionDefinition FD_STRING_SET_EQUALS = new FunctionDefinitionSet<Boolean,String>(XACML3.ID_FUNCTION_STRING_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_STRING, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+ public static final FunctionDefinition FD_BOOLEAN_SET_EQUALS = new FunctionDefinitionSet<Boolean,Boolean>(XACML3.ID_FUNCTION_BOOLEAN_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_BOOLEAN, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+ public static final FunctionDefinition FD_INTEGER_SET_EQUALS = new FunctionDefinitionSet<Boolean,BigInteger>(XACML3.ID_FUNCTION_INTEGER_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_INTEGER, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+ public static final FunctionDefinition FD_DOUBLE_SET_EQUALS = new FunctionDefinitionSet<Boolean,Double>(XACML3.ID_FUNCTION_DOUBLE_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_DOUBLE, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+ public static final FunctionDefinition FD_TIME_SET_EQUALS = new FunctionDefinitionSet<Boolean,ISO8601Time>(XACML3.ID_FUNCTION_TIME_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_TIME, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+ public static final FunctionDefinition FD_DATE_SET_EQUALS = new FunctionDefinitionSet<Boolean,ISO8601Date>(XACML3.ID_FUNCTION_DATE_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_DATE, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+ public static final FunctionDefinition FD_DATETIME_SET_EQUALS = new FunctionDefinitionSet<Boolean, ISO8601DateTime>(XACML3.ID_FUNCTION_DATETIME_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_DATETIME, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+ public static final FunctionDefinition FD_ANYURI_SET_EQUALS = new FunctionDefinitionSet<Boolean, URI>(XACML3.ID_FUNCTION_ANYURI_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+ public static final FunctionDefinition FD_HEXBINARY_SET_EQUALS = new FunctionDefinitionSet<Boolean,HexBinary>(XACML3.ID_FUNCTION_HEXBINARY_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_HEXBINARY, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+ public static final FunctionDefinition FD_BASE64BINARY_SET_EQUALS = new FunctionDefinitionSet<Boolean,Base64Binary>(XACML3.ID_FUNCTION_BASE64BINARY_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_BASE64BINARY, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_SET_EQUALS = new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML3.ID_FUNCTION_DAYTIMEDURATION_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+ public static final FunctionDefinition FD_DAYTIMEDURATION_SET_EQUALS_VERSION1 = new FunctionDefinitionSet<Boolean,XPathDayTimeDuration>(XACML1.ID_FUNCTION_DAYTIMEDURATION_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_DAYTIMEDURATION, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_SET_EQUALS = new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML3.ID_FUNCTION_YEARMONTHDURATION_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+ public static final FunctionDefinition FD_YEARMONTHDURATION_SET_EQUALS_VERSION1 = new FunctionDefinitionSet<Boolean,XPathYearMonthDuration>(XACML1.ID_FUNCTION_YEARMONTHDURATION_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_YEARMONTHDURATION, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+ public static final FunctionDefinition FD_X500NAME_SET_EQUALS = new FunctionDefinitionSet<Boolean,X500Principal>(XACML3.ID_FUNCTION_X500NAME_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_X500NAME, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+ public static final FunctionDefinition FD_RFC822NAME_SET_EQUALS = new FunctionDefinitionSet<Boolean,RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_SET_EQUALS, DataTypes.DT_BOOLEAN, DataTypes.DT_RFC822NAME, FunctionDefinitionSet.OPERATION.SET_EQUALS);
+
+
+ /*
+ * Higher Order Bag functions (See A.3.12)
+ */
+ public static final FunctionDefinition FD_ANY_OF = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ANY_OF, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ANY_OF);
+ public static final FunctionDefinition FD_ANY_OF_VERSION1 = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML1.ID_FUNCTION_ANY_OF, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ANY_OF);
+ public static final FunctionDefinition FD_ALL_OF = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ALL_OF, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ALL_OF);
+ public static final FunctionDefinition FD_ALL_OF_VERSION1 = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML1.ID_FUNCTION_ALL_OF, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ALL_OF);
+ public static final FunctionDefinition FD_ANY_OF_ANY = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ANY_OF_ANY, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ANY_OF_ANY);
+ public static final FunctionDefinition FD_ANY_OF_ANY_VERSION1 = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML1.ID_FUNCTION_ANY_OF_ANY, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ANY_OF_ANY);
+ public static final FunctionDefinition FD_ALL_OF_ANY = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ALL_OF_ANY, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ALL_OF_ANY);
+ public static final FunctionDefinition FD_ANY_OF_ALL = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ANY_OF_ALL, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ANY_OF_ALL);
+ public static final FunctionDefinition FD_ALL_OF_ALL = new FunctionDefinitionHigherOrderBag<Boolean,Object>(XACML3.ID_FUNCTION_ALL_OF_ALL, DataTypes.DT_BOOLEAN, null, FunctionDefinitionHigherOrderBag.OPERATION.ALL_OF_ALL);
+ public static final FunctionDefinition FD_MAP = new FunctionDefinitionHigherOrderBag<Object,Object>(XACML3.ID_FUNCTION_MAP, null, null, FunctionDefinitionHigherOrderBag.OPERATION.MAP);
+ public static final FunctionDefinition FD_MAP_VERSION1 = new FunctionDefinitionHigherOrderBag<Object,Object>(XACML1.ID_FUNCTION_MAP, null, null, FunctionDefinitionHigherOrderBag.OPERATION.MAP);
+
+
+ /*
+ * Regular Expression functions (See A.3.13)
+ */
+ public static final FunctionDefinition FD_STRING_REGEXP_MATCH = new FunctionDefinitionRegexpMatch<String>(XACML3.ID_FUNCTION_STRING_REGEXP_MATCH, DataTypes.DT_STRING);
+ public static final FunctionDefinition FD_ANYURI_REGEXP_MATCH = new FunctionDefinitionRegexpMatch<URI>(XACML3.ID_FUNCTION_ANYURI_REGEXP_MATCH, DataTypes.DT_ANYURI);
+ public static final FunctionDefinition FD_IPADDRESS_REGEXP_MATCH = new FunctionDefinitionRegexpMatch<IPAddress>(XACML3.ID_FUNCTION_IPADDRESS_REGEXP_MATCH, DataTypes.DT_IPADDRESS);
+ public static final FunctionDefinition FD_DNSNAME_REGEXP_MATCH = new FunctionDefinitionRegexpMatch<RFC2396DomainName>(XACML3.ID_FUNCTION_DNSNAME_REGEXP_MATCH, DataTypes.DT_DNSNAME);
+ public static final FunctionDefinition FD_RFC822NAME_REGEXP_MATCH = new FunctionDefinitionRegexpMatch<RFC822Name>(XACML3.ID_FUNCTION_RFC822NAME_REGEXP_MATCH, DataTypes.DT_RFC822NAME);
+ public static final FunctionDefinition FD_X500NAME_REGEXP_MATCH = new FunctionDefinitionRegexpMatch<X500Principal>(XACML3.ID_FUNCTION_X500NAME_REGEXP_MATCH, DataTypes.DT_X500NAME);
+
+
+ /*
+ * Special Match functions (See A.3.14)
+ */
+ public static final FunctionDefinition FD_X500NAME_MATCH = new FunctionDefinitionX500NameMatch(XACML3.ID_FUNCTION_X500NAME_MATCH);
+ public static final FunctionDefinition FD_RFC822NAME_MATCH = new FunctionDefinitionRFC822NameMatch(XACML3.ID_FUNCTION_RFC822NAME_MATCH);
+
+ /*
+ * XPath based functions (See A.3.15)
+ *
+ * THESE ARE OPTIONAL
+ *
+ */
+ public static final FunctionDefinition FD_XPATH_NODE_COUNT = new FunctionDefinitionXPath<BigInteger>(XACML3.ID_FUNCTION_XPATH_NODE_COUNT, DataTypes.DT_INTEGER, FunctionDefinitionXPath.OPERATION.COUNT);
+// public static final FunctionDefinition FD_XPATH_NODE_COUNT_VERSION1 = new FunctionDefinitionXPath<BigInteger>(XACML1.ID_FUNCTION_XPATH_NODE_COUNT, DataTypes.DT_INTEGER, FunctionDefinitionXPath.OPERATION.COUNT);
+ public static final FunctionDefinition FD_XPATH_NODE_EQUAL = new FunctionDefinitionXPath<Boolean>(XACML3.ID_FUNCTION_XPATH_NODE_EQUAL, DataTypes.DT_BOOLEAN, FunctionDefinitionXPath.OPERATION.EQUAL);
+// public static final FunctionDefinition FD_XPATH_NODE_EQUAL_VERSION1 = new FunctionDefinitionXPath<Boolean>(XACML1.ID_FUNCTION_XPATH_NODE_EQUAL, DataTypes.DT_BOOLEAN, FunctionDefinitionXPath.OPERATION.EQUAL);
+ public static final FunctionDefinition FD_XPATH_NODE_MATCH = new FunctionDefinitionXPath<Boolean>(XACML3.ID_FUNCTION_XPATH_NODE_MATCH, DataTypes.DT_BOOLEAN, FunctionDefinitionXPath.OPERATION.MATCH);
+// public static final FunctionDefinition FD_XPATH_NODE_MATCH_VERSION1 = new FunctionDefinitionXPath<Boolean>(XACML1.ID_FUNCTION_XPATH_NODE_MATCH, DataTypes.DT_BOOLEAN, FunctionDefinitionXPath.OPERATION.MATCH);
+
+
+ /*
+ * Other functions (See A.3.16)
+ *
+ * THIS ONE IS OPTIONAL
+ *
+ */
+ public static final FunctionDefinition FD_ACCESS_PERMITTED = new FunctionDefinitionAccessPermitted(XACML3.ID_FUNCTION_ACCESS_PERMITTED);
+
+
+ /*
+ * Deprecated functions (See A.4)
+ *
+ */
+ public static final FunctionDefinition FD_URI_STRING_CONCATENATE = new FunctionDefinitionURIStringConcatenate(XACML2.ID_FUNCTION_URI_STRING_CONCATENATE);
+
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.java
new file mode 100755
index 0000000..4463fba
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.java
@@ -0,0 +1,373 @@
+/*
+ * 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;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.IdReferenceMatch;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Version;
+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.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinder;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinderResult;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef;
+
+/**
+ * StdPolicyFinder implements the {@link com.att.research.xacmlatt.pdp.policy.PolicyFinder} interface to look up policies
+ * by their internal ID or an externally visible ID.
+ *
+ * @author car
+ * @version $Revision: 1.4 $
+ */
+public class StdPolicyFinder implements PolicyFinder {
+ private static final PolicyFinderResult<PolicyDef> PFR_MULTIPLE = new StdPolicyFinderResult<PolicyDef>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Multiple applicable root policies"));
+ private static final PolicyFinderResult<PolicyDef> PFR_NOT_FOUND = new StdPolicyFinderResult<PolicyDef>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No matching root policy found"));
+
+ private static final PolicyFinderResult<Policy> PFR_POLICY_NOT_FOUND = new StdPolicyFinderResult<Policy>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No matching policy found"));
+ private static final PolicyFinderResult<Policy> PFR_NOT_A_POLICY = new StdPolicyFinderResult<Policy>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Not a policy"));
+ private static final PolicyFinderResult<PolicySet> PFR_POLICYSET_NOT_FOUND = new StdPolicyFinderResult<PolicySet>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "No matching policy set found"));
+ private static final PolicyFinderResult<PolicySet> PFR_NOT_A_POLICYSET = new StdPolicyFinderResult<PolicySet>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Not a policy set"));
+
+ private Log logger = LogFactory.getLog(this.getClass());
+ private List<PolicyDef> listRoots = new ArrayList<PolicyDef>();
+ private Map<Identifier,List<PolicyDef>> mapPolicies = new HashMap<Identifier,List<PolicyDef>>();
+
+ public static class StdPolicyFinderException extends Exception {
+ private static final long serialVersionUID = -8969282995787463288L;
+ public StdPolicyFinderException(String msg) {
+ super(msg);
+ }
+ public StdPolicyFinderException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+ }
+
+ private void storeInPolicyMap(PolicyDef policyDef) {
+ List<PolicyDef> listPolicyDefs = this.mapPolicies.get(policyDef.getIdentifier());
+ if (listPolicyDefs == null) {
+ listPolicyDefs = new ArrayList<PolicyDef>();
+ this.mapPolicies.put(policyDef.getIdentifier(), listPolicyDefs);
+ }
+ listPolicyDefs.add(policyDef);
+ }
+
+ private <T extends PolicyDef> List<T> getFromPolicyMap(IdReferenceMatch idReferenceMatch, Class<T> classPolicyDef) {
+ /*
+ * Get all of the PolicyDefs for the Identifier in the reference match
+ */
+ List<PolicyDef> listPolicyDefForId = this.mapPolicies.get(idReferenceMatch.getId());
+ if (listPolicyDefForId == null) {
+ return null;
+ }
+
+ /*
+ * Iterate over all of the PolicyDefs that were found and select only the ones that match
+ * the version request and the isPolicySet
+ */
+ List<T> listPolicyDefMatches = null;
+ Iterator<PolicyDef> iterPolicyDefs = listPolicyDefForId.iterator();
+ while (iterPolicyDefs.hasNext()) {
+ PolicyDef policyDef = iterPolicyDefs.next();
+ if (classPolicyDef.isInstance(policyDef) && policyDef.matches(idReferenceMatch)) {
+ if (listPolicyDefMatches == null) {
+ listPolicyDefMatches = new ArrayList<T>();
+ }
+ listPolicyDefMatches.add(classPolicyDef.cast(policyDef));
+ }
+ }
+
+ return listPolicyDefMatches;
+ }
+
+ private <T extends PolicyDef> T getBestMatchN(List<T> matches) {
+ T bestMatch = null;
+ Version bestVersion = null;
+ Iterator<T> iterMatches = matches.iterator();
+
+ while (iterMatches.hasNext()) {
+ T match = iterMatches.next();
+ if (bestMatch == null) {
+ bestMatch = match;
+ bestVersion = match.getVersion();
+ } else {
+ Version matchVersion = match.getVersion();
+ if (matchVersion != null) {
+ if (matchVersion.compareTo(bestVersion) > 0) {
+ bestMatch = match;
+ bestVersion = matchVersion;
+ }
+ }
+ }
+ }
+ return bestMatch;
+ }
+
+ private <T extends PolicyDef> T getBestMatch(List<T> matches) {
+ switch(matches.size()) {
+ case 0:
+ return null;
+ case 1:
+ return matches.get(0);
+ default:
+ return this.getBestMatchN(matches);
+ }
+ }
+
+ private PolicyDef loadPolicyDefFromURI(URI uri) throws StdPolicyFinderException {
+ PolicyDef policyDef = null;
+ InputStream inputStream = null;
+ try {
+ this.logger.info("Loading policy from URI " + uri.toString());
+ URL url = uri.toURL();
+ this.logger.debug("Loading policy from URL " + url.toString());
+
+ inputStream = url.openStream();
+ policyDef = DOMPolicyDef.load(inputStream);
+ } catch (MalformedURLException ex) {
+ this.logger.debug("Unknown protocol for URI " + uri.toString());
+ return null;
+ } catch (Exception ex) {
+ this.logger.error("Exception loading policy definition", ex);
+ throw new StdPolicyFinderException("Exception loading policy def from \"" + uri.toString() + "\": " + ex.getMessage(), ex);
+ } finally {
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (Exception ex) {
+
+ }
+ }
+ }
+ return policyDef;
+ }
+
+ /**
+ * Looks up the given {@link com.att.research.xacml.api.Identifier} in the map first. If not found, and the <code>Identifier</code> contains
+ * a URL, then attempts to retrieve the document from the URL and caches it.
+ *
+ * @param idReferenceMatch the <code>IdReferenceMatch</code> to look up
+ * @return a <code>PolicyFinderResult</code> with the requested <code>Policy</code> or an error status
+ */
+ private PolicyFinderResult<Policy> lookupPolicyByIdentifier(IdReferenceMatch idReferenceMatch) {
+ List<Policy> listCachedPolicies = this.getFromPolicyMap(idReferenceMatch, Policy.class);
+ if (listCachedPolicies == null) {
+ Identifier id = idReferenceMatch.getId();
+ if (id != null) {
+ URI uri = id.getUri();
+ if (uri != null && uri.isAbsolute()) {
+ PolicyDef policyDef = null;
+ try {
+ policyDef = this.loadPolicyDefFromURI(uri);
+ } catch (StdPolicyFinderException ex) {
+ return new StdPolicyFinderResult<Policy>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage()));
+ }
+ if (policyDef != null) {
+ if (policyDef instanceof Policy) {
+ List<PolicyDef> listPolicyDefs = new ArrayList<PolicyDef>();
+ listPolicyDefs.add(policyDef);
+ this.mapPolicies.put(id, listPolicyDefs);
+ this.mapPolicies.put(policyDef.getIdentifier(), listPolicyDefs);
+ return new StdPolicyFinderResult<Policy>((Policy)policyDef);
+ } else {
+ return PFR_NOT_A_POLICY;
+ }
+ } else {
+ return PFR_POLICY_NOT_FOUND;
+ }
+ }
+ }
+ }
+ if (listCachedPolicies != null) {
+ return new StdPolicyFinderResult<Policy>(this.getBestMatch(listCachedPolicies));
+ } else {
+ return PFR_POLICY_NOT_FOUND;
+ }
+ }
+
+ /**
+ * Looks up the given {@link com.att.research.xacml.api.Identifier} in the map first. If not found, and the <code>Identifier</code> contains
+ * a URL, then attempts to retrieve the document from the URL and caches it.
+ *
+ * @param idReferenceMatch the <code>IdReferenceMatch</code> to look up
+ * @return a <code>PolicyFinderResult</code> with the requested <code>PolicySet</code> or an error status
+ */
+ private PolicyFinderResult<PolicySet> lookupPolicySetByIdentifier(IdReferenceMatch idReferenceMatch) {
+ List<PolicySet> listCachedPolicySets = this.getFromPolicyMap(idReferenceMatch, PolicySet.class);
+ if (listCachedPolicySets == null) {
+ Identifier id = idReferenceMatch.getId();
+ if (id != null) {
+ URI uri = id.getUri();
+ if (uri != null && uri.isAbsolute()) {
+ PolicyDef policyDef = null;
+ try {
+ policyDef = this.loadPolicyDefFromURI(uri);
+ } catch (StdPolicyFinderException ex) {
+ return new StdPolicyFinderResult<PolicySet>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage()));
+ }
+ if (policyDef != null) {
+ if (policyDef instanceof PolicySet) {
+ List<PolicyDef> listPolicyDefs = new ArrayList<PolicyDef>();
+ listPolicyDefs.add(policyDef);
+ this.mapPolicies.put(id, listPolicyDefs);
+ this.mapPolicies.put(policyDef.getIdentifier(), listPolicyDefs);
+ return new StdPolicyFinderResult<PolicySet>((PolicySet)policyDef);
+ } else {
+ return PFR_NOT_A_POLICYSET;
+ }
+ } else {
+ return PFR_POLICYSET_NOT_FOUND;
+ }
+ }
+ }
+ }
+ if (listCachedPolicySets != null) {
+ return new StdPolicyFinderResult<PolicySet>(this.getBestMatch(listCachedPolicySets));
+ } else {
+ return PFR_POLICYSET_NOT_FOUND;
+ }
+ }
+
+ /**
+ * Adds the given <code>PolicyDef</code> to the map of loaded <code>PolicyDef</code>s and adds
+ * its child <code>PolicyDef</code>s recursively.
+ *
+ * @param policyDef the <code>PolicyDef</code> to add
+ */
+ private void updatePolicyMap(PolicyDef policyDef) {
+ this.storeInPolicyMap(policyDef);
+ if (policyDef instanceof PolicySet) {
+ Iterator<PolicySetChild> iterChildren = ((PolicySet)policyDef).getChildren();
+ if (iterChildren != null) {
+ while (iterChildren.hasNext()) {
+ PolicySetChild policySetChild = iterChildren.next();
+ if (policySetChild instanceof PolicyDef) {
+ this.updatePolicyMap((PolicyDef)policySetChild);
+ }
+ }
+ }
+ }
+ }
+
+ public StdPolicyFinder(Collection<PolicyDef> listRootPolicies, Collection<PolicyDef> referencedPolicyDefs) {
+ if (listRootPolicies != null) {
+ for (PolicyDef policyDef: listRootPolicies) {
+ this.listRoots.add(policyDef);
+ this.updatePolicyMap(policyDef);
+ }
+ }
+ if (referencedPolicyDefs != null) {
+ for (PolicyDef policyDef: referencedPolicyDefs) {
+ this.storeInPolicyMap(policyDef);
+ }
+ }
+ }
+
+ /**
+ * Creates a new <code>StdPolicyFinder</code> with the given <code>PolicyDef</code> as the root element.
+ *
+ * @param rootPolicyDef the <code>PolicyDef</code> acting as the root element
+ */
+ public StdPolicyFinder(PolicyDef rootPolicyDef, Collection<PolicyDef> referencedPolicyDefs) {
+ if (rootPolicyDef != null) {
+ this.listRoots.add(rootPolicyDef);
+ this.updatePolicyMap(rootPolicyDef);
+ }
+
+ if (referencedPolicyDefs != null) {
+ for (PolicyDef policyDef: referencedPolicyDefs) {
+ this.storeInPolicyMap(policyDef);
+ }
+ }
+ }
+
+ public StdPolicyFinder(List<PolicyDef> rootPolicies, List<PolicyDef> referencedPolicies, Properties properties) {
+ this(rootPolicies, referencedPolicies);
+ }
+
+ @Override
+ public PolicyFinderResult<PolicyDef> getRootPolicyDef(EvaluationContext evaluationContext) {
+ PolicyDef policyDefFirstMatch = null;
+ Iterator<PolicyDef> iterRootPolicies = this.listRoots.iterator();
+ PolicyFinderResult<PolicyDef> firstIndeterminate = null;
+ while (iterRootPolicies.hasNext()) {
+ PolicyDef policyDef = iterRootPolicies.next();
+ MatchResult matchResult = null;
+ try {
+ matchResult = policyDef.match(evaluationContext);
+ switch(matchResult.getMatchCode()) {
+ case INDETERMINATE:
+ if (firstIndeterminate == null) {
+ firstIndeterminate = new StdPolicyFinderResult<PolicyDef>(matchResult.getStatus());
+ }
+ break;
+ case MATCH:
+ if (policyDefFirstMatch == null) {
+ policyDefFirstMatch = policyDef;
+ } else {
+ return PFR_MULTIPLE;
+ }
+ break;
+ case NOMATCH:
+ break;
+ }
+ } catch (EvaluationException ex) {
+ if (firstIndeterminate == null) {
+ firstIndeterminate = new StdPolicyFinderResult<PolicyDef>(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, ex.getMessage()));
+ }
+ }
+ }
+
+ if (policyDefFirstMatch == null) {
+ if (firstIndeterminate != null) {
+ return firstIndeterminate;
+ } else {
+ return PFR_NOT_FOUND;
+ }
+ } else {
+ return new StdPolicyFinderResult<PolicyDef>(policyDefFirstMatch);
+ }
+ }
+
+ @Override
+ public PolicyFinderResult<Policy> getPolicy(IdReferenceMatch idReferenceMatch) {
+ return this.lookupPolicyByIdentifier(idReferenceMatch);
+ }
+
+ @Override
+ public PolicyFinderResult<PolicySet> getPolicySet(IdReferenceMatch idReferenceMatch) {
+ return this.lookupPolicySetByIdentifier(idReferenceMatch);
+ }
+
+ public void addReferencedPolicy(PolicyDef policyDef) {
+ this.updatePolicyMap(policyDef);
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.java
new file mode 100755
index 0000000..365c768
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.java
@@ -0,0 +1,224 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.UUID;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.StdVersion;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.XACMLProperties;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithmFactory;
+import com.att.research.xacmlatt.pdp.policy.Policy;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinder;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory;
+import com.att.research.xacmlatt.pdp.policy.PolicySet;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+import com.att.research.xacmlatt.pdp.policy.Target;
+import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef;
+import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
+import com.google.common.base.Splitter;
+
+/**
+ * StdPolicyFinderFactory extends {@link com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory} with the
+ * <code>getPolicyFinder</code> method to get a single instance of the {@link StdPolicyFinder}. The
+ * root {@link com.att.research.xacmlatt.pdp.policy.PolicyDef} is loaded from a file whose name is specified as a system property or
+ * in the $java.home/lib/xacml.properties property set.
+ *
+ * @author car
+ * @version $Revision: 1.3 $
+ */
+public class StdPolicyFinderFactory extends PolicyFinderFactory {
+ public static final String PROP_FILE = ".file";
+ public static final String PROP_URL = ".url";
+
+ private Log logger = LogFactory.getLog(this.getClass());
+ private List<PolicyDef> rootPolicies;
+ private List<PolicyDef> referencedPolicies;
+ private boolean needsInit = true;
+
+ /**
+ * Loads the <code>PolicyDef</code> for the given <code>String</code> identifier by looking first
+ * for a ".file" property associated with the ID and using that to load from a <code>File</code> and
+ * looking for a ".url" property associated with the ID and using that to load from a <code>URL</code>.
+ *
+ * @param policyId the <code>String</code> identifier for the policy
+ * @return a <code>PolicyDef</code> loaded from the given identifier
+ */
+ protected PolicyDef loadPolicyDef(String policyId, Properties properties) {
+ String propLocation = properties.getProperty(policyId + PROP_FILE);
+ if (propLocation != null) {
+ File fileLocation = new File(propLocation);
+ if (!fileLocation.exists()) {
+ this.logger.error("Policy file " + fileLocation.getAbsolutePath() + " does not exist.");
+ } else if (!fileLocation.canRead()) {
+ this.logger.error("Policy file " + fileLocation.getAbsolutePath() + " cannot be read.");
+ } else {
+ try {
+ this.logger.info("Loading policy file " + fileLocation);
+ PolicyDef policyDef = DOMPolicyDef.load(fileLocation);
+ if (policyDef != null) {
+ return policyDef;
+ }
+ } catch (DOMStructureException ex) {
+ this.logger.error("Error loading policy file " + fileLocation.getAbsolutePath() + ": " + ex.getMessage(), ex);
+ return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ }
+ }
+ }
+
+ if ((propLocation = properties.getProperty(policyId + PROP_URL)) != null) {
+ InputStream is = null;
+ try {
+ URL url = new URL(propLocation);
+ URLConnection urlConnection = url.openConnection();
+ this.logger.info("Loading policy file " + url.toString());
+ is = urlConnection.getInputStream();
+ PolicyDef policyDef = DOMPolicyDef.load(is);
+ if (policyDef != null) {
+ return policyDef;
+ }
+ } catch (MalformedURLException ex) {
+ this.logger.error("Invalid URL " + propLocation + ": " + ex.getMessage(), ex);
+ } catch (IOException ex) {
+ this.logger.error("IOException opening URL " + propLocation + ": " + ex.getMessage(), ex);
+ } catch (DOMStructureException ex) {
+ this.logger.error("Invalid Policy " + propLocation + ": " + ex.getMessage(), ex);
+ return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage());
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ this.logger.error("Exception closing InputStream for GET of url " + propLocation + " : " + e.getMessage() + " (May be memory leak)", e);
+ }
+ }
+ }
+ }
+
+ this.logger.error("No known location for Policy " + policyId);
+ return null;
+ }
+
+ /**
+ * Finds the identifiers for all of the policies referenced by the given property name in the
+ * <code>XACMLProperties</code> and loads them using the requested loading method.
+ *
+ * @param propertyName the <code>String</code> name of the property containing the list of policy identifiers
+ * @return a <code>List</code> of <code>PolicyDef</code>s loaded from the given property name
+ */
+ protected List<PolicyDef> getPolicyDefs(String propertyName, Properties properties) {
+ String policyIds = properties.getProperty(propertyName);
+ if (policyIds == null || policyIds.length() == 0) {
+ return null;
+ }
+
+ Iterable<String> policyIdArray = Splitter.on(',').trimResults().omitEmptyStrings().split(policyIds);
+ if (policyIdArray == null) {
+ return null;
+ }
+
+ List<PolicyDef> listPolicyDefs = new ArrayList<PolicyDef>();
+ for (String policyId : policyIdArray) {
+ PolicyDef policyDef = this.loadPolicyDef(policyId, properties);
+ if (policyDef != null) {
+ listPolicyDefs.add(policyDef);
+ }
+ }
+ return listPolicyDefs;
+ }
+
+ protected synchronized void init(Properties properties) {
+ if (this.needsInit) {
+ //
+ // Check for property that combines root policies into one policyset
+ //
+ String combiningAlgorithm = properties.getProperty(ATTPDPProperties.PROP_POLICYFINDERFACTORY_COMBINEROOTPOLICIES);
+ if (combiningAlgorithm != null) {
+ try {
+ logger.info("Combining root policies with " + combiningAlgorithm);
+ //
+ // Find the combining algorithm
+ //
+ CombiningAlgorithm<PolicySetChild> algorithm = CombiningAlgorithmFactory.newInstance().getPolicyCombiningAlgorithm(new IdentifierImpl(combiningAlgorithm));
+ //
+ // Create our root policy
+ //
+ PolicySet root = new PolicySet();
+ root.setIdentifier(new IdentifierImpl(UUID.randomUUID().toString()));
+ root.setVersion(StdVersion.newInstance("1.0"));
+ root.setTarget(new Target());
+ //
+ // Set the algorithm
+ //
+ root.setPolicyCombiningAlgorithm(algorithm);
+ //
+ // Load all our root policies
+ //
+ for (PolicyDef policy : this.getPolicyDefs(XACMLProperties.PROP_ROOTPOLICIES, properties)) {
+ root.addChild(policy);
+ }
+ //
+ // Set this policy as the root
+ //
+ this.rootPolicies = new ArrayList<>();
+ this.rootPolicies.add(root);
+ } catch (FactoryException | ParseException e) {
+ logger.error("Failed to load Combining Algorithm Factory: " + e.getLocalizedMessage());
+ }
+ } else {
+ this.rootPolicies = this.getPolicyDefs(XACMLProperties.PROP_ROOTPOLICIES, properties);
+ }
+
+ this.referencedPolicies = this.getPolicyDefs(XACMLProperties.PROP_REFERENCEDPOLICIES, properties);
+ this.needsInit = false;
+ }
+ }
+
+ public StdPolicyFinderFactory() {
+ }
+
+ public StdPolicyFinderFactory(Properties properties) {
+ }
+
+ @Override
+ public PolicyFinder getPolicyFinder() throws FactoryException {
+ try {
+ this.init(XACMLProperties.getProperties());
+ } catch (IOException e) {
+ throw new FactoryException(e);
+ }
+ return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies);
+ }
+
+ @Override
+ public PolicyFinder getPolicyFinder(Properties properties) throws FactoryException {
+ this.init(properties);
+ return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies, properties);
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.java
new file mode 100755
index 0000000..0749a8e
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.java
@@ -0,0 +1,52 @@
+/*
+ * 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;
+
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.PolicyFinderResult;
+
+/**
+ * StdPolicyFinderResult implements the {@link com.att.research.xacmlatt.pdp.policy.PolicyFinderResult} interface.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ * @param <T> the java class extending {@link com.att.research.xacmlatt.pdp.policy.PolicyDef} held by the <code>StdPolicyFinderResult</code>
+ */
+public class StdPolicyFinderResult<T extends PolicyDef> implements PolicyFinderResult<T> {
+ private Status status;
+ private T policyDef;
+
+ public StdPolicyFinderResult(Status statusIn, T policyDefIn) {
+ this.status = (statusIn == null ? StdStatus.STATUS_OK : statusIn);
+ this.policyDef = policyDefIn;
+ }
+
+ public StdPolicyFinderResult(Status statusIn) {
+ this(statusIn, null);
+ }
+
+ public StdPolicyFinderResult(T policyDefIn) {
+ this(null, policyDefIn);
+ }
+
+ @Override
+ public Status getStatus() {
+ return this.status;
+ }
+
+ @Override
+ public T getPolicyDef() {
+ return this.policyDef;
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdProperties.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdProperties.java
new file mode 100755
index 0000000..ff394ee
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdProperties.java
@@ -0,0 +1,19 @@
+/*
+ * 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;
+
+import com.att.research.xacmlatt.pdp.util.ATTPDPProperties;
+
+public class StdProperties extends ATTPDPProperties {
+ protected StdProperties() {
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.java
new file mode 100755
index 0000000..c24d2c2
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.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) 2015 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.std.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+
+/**
+ * @author pameladragosh
+ *
+ * This algorithm was created to support combining a collection of policies in which the permit's are combined into one decision. PermitOverrides
+ * itself will stop once a Permit is found. However, some policy makers want every policy in a policy set to be visited by the PDP engine.
+ * The result of all the Permits that were found are then combined and returned. If no Permits were found then the result is the same semantics as
+ * the PermitOverrides combining algorithm.
+ *
+ * @param <T>
+ */
+public class CombinedPermitOverrides<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> {
+
+ public CombinedPermitOverrides(Identifier identifierIn) {
+ super(identifierIn);
+ }
+
+ @Override
+ public EvaluationResult combine(EvaluationContext evaluationContext,
+ List<CombiningElement<T>> elements,
+ List<CombinerParameter> combinerParameters)
+ throws EvaluationException {
+ boolean atLeastOneDeny = false;
+ boolean atLeastOnePermit = false;
+
+ EvaluationResult combinedResultDeny = new EvaluationResult(Decision.DENY);
+ EvaluationResult combinedResultPermit = new EvaluationResult(Decision.PERMIT);
+
+ EvaluationResult firstIndeterminateD = null;
+ EvaluationResult firstIndeterminateP = null;
+ EvaluationResult firstIndeterminateDP = null;
+
+ Iterator<CombiningElement<T>> iterElements = elements.iterator();
+ while (iterElements.hasNext()) {
+ CombiningElement<T> combiningElement = iterElements.next();
+ EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext);
+
+ assert(evaluationResultElement != null);
+ switch(evaluationResultElement.getDecision()) {
+ case DENY:
+ atLeastOneDeny = true;
+ combinedResultDeny.merge(evaluationResultElement);
+ break;
+ case INDETERMINATE:
+ case INDETERMINATE_DENYPERMIT:
+ if (firstIndeterminateDP == null) {
+ firstIndeterminateDP = evaluationResultElement;
+ } else {
+ firstIndeterminateDP.merge(evaluationResultElement);
+ }
+ break;
+ case INDETERMINATE_DENY:
+ if (firstIndeterminateD == null) {
+ firstIndeterminateD = evaluationResultElement;
+ } else {
+ firstIndeterminateD.merge(evaluationResultElement);
+ }
+ break;
+ case INDETERMINATE_PERMIT:
+ if (firstIndeterminateP == null) {
+ firstIndeterminateP = evaluationResultElement;
+ } else {
+ firstIndeterminateP.merge(evaluationResultElement);
+ }
+ break;
+ case NOTAPPLICABLE:
+ break;
+ case PERMIT:
+ atLeastOnePermit = true;
+ combinedResultPermit.merge(evaluationResultElement);
+ break;
+ default:
+ throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+ }
+ }
+
+ if (atLeastOnePermit) {
+ return combinedResultPermit;
+ }
+ if (firstIndeterminateDP != null) {
+ return firstIndeterminateDP;
+ } else if (firstIndeterminateP != null && (firstIndeterminateD != null || atLeastOneDeny)) {
+ return new EvaluationResult(Decision.INDETERMINATE_DENYPERMIT, firstIndeterminateD.getStatus());
+ } else if (firstIndeterminateP != null) {
+ return firstIndeterminateP;
+ } else if (atLeastOneDeny) {
+ return combinedResultDeny;
+ } else if (firstIndeterminateD != null) {
+ return firstIndeterminateD;
+ } else {
+ return new EvaluationResult(Decision.NOTAPPLICABLE);
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.java
new file mode 100755
index 0000000..4993a98
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.java
@@ -0,0 +1,40 @@
+/*
+ * 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.combiners;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm;
+
+public abstract class CombiningAlgorithmBase<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> implements CombiningAlgorithm<T> {
+ private Identifier id;
+
+ public CombiningAlgorithmBase(Identifier identifierIn) {
+ this.id = identifierIn;
+ }
+
+ @Override
+ public Identifier getId() {
+ return this.id;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("{");
+
+ Object objectToDump;
+ if ((objectToDump = this.getId()) != null) {
+ stringBuilder.append("id=");
+ stringBuilder.append(objectToDump.toString());
+ }
+ stringBuilder.append('}');
+ return stringBuilder.toString();
+ }
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.java
new file mode 100755
index 0000000..207ec61
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.java
@@ -0,0 +1,105 @@
+/*
+ * 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.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+
+/**
+ * DenyOverrides implements the XACML 3.0 "deny-overrides" combining algorithm for both policies and rules.
+ *
+ * @author car
+ *
+ * @param <T> the java class for the {@link com.att.research.xacmlatt.pdp.eval.Evaluatable}
+ * @param <U> the java class for the identifier
+ */
+public class DenyOverrides<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> {
+
+ public DenyOverrides(Identifier identifierIn) {
+ super(identifierIn);
+ }
+
+ @Override
+ public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<T>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException {
+ boolean atLeastOnePermit = false;
+
+ EvaluationResult combinedResult = new EvaluationResult(Decision.PERMIT);
+
+ EvaluationResult firstIndeterminateD = null;
+ EvaluationResult firstIndeterminateP = null;
+ EvaluationResult firstIndeterminateDP = null;
+
+ Iterator<CombiningElement<T>> iterElements = elements.iterator();
+ while (iterElements.hasNext()) {
+ CombiningElement<T> combiningElement = iterElements.next();
+ EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext);
+
+ assert(evaluationResultElement != null);
+ switch(evaluationResultElement.getDecision()) {
+ case DENY:
+ return evaluationResultElement;
+ case INDETERMINATE:
+ case INDETERMINATE_DENYPERMIT:
+ if (firstIndeterminateDP == null) {
+ firstIndeterminateDP = evaluationResultElement;
+ } else {
+ firstIndeterminateDP.merge(evaluationResultElement);
+ }
+ break;
+ case INDETERMINATE_DENY:
+ if (firstIndeterminateD == null) {
+ firstIndeterminateD = evaluationResultElement;
+ } else {
+ firstIndeterminateD.merge(evaluationResultElement);
+ }
+ break;
+ case INDETERMINATE_PERMIT:
+ if (firstIndeterminateP == null) {
+ firstIndeterminateP = evaluationResultElement;
+ } else {
+ firstIndeterminateP.merge(evaluationResultElement);
+ }
+ break;
+ case NOTAPPLICABLE:
+ break;
+ case PERMIT:
+ atLeastOnePermit = true;
+ combinedResult.merge(evaluationResultElement);
+ break;
+ default:
+ throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+ }
+ }
+
+ if (firstIndeterminateDP != null) {
+ return firstIndeterminateDP;
+ } else if (firstIndeterminateD != null && (firstIndeterminateP != null || atLeastOnePermit)) {
+ return new EvaluationResult(Decision.INDETERMINATE_DENYPERMIT, firstIndeterminateD.getStatus());
+ } else if (firstIndeterminateD != null) {
+ return firstIndeterminateD;
+ } else if (atLeastOnePermit) {
+ return combinedResult;
+ } else if (firstIndeterminateP != null) {
+ return firstIndeterminateP;
+ } else {
+ return new EvaluationResult(Decision.NOTAPPLICABLE);
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.java
new file mode 100755
index 0000000..4c241e6
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.java
@@ -0,0 +1,68 @@
+/*
+ * 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.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+
+/**
+ * DenyUnlessPermit implements the XACML 3.0 "deny-unless-permit" combining algorithm for both policies and rules.
+ *
+ * @author car
+ *
+ * @param <T> the java class for the {@link com.att.research.xacmlatt.pdp.eval.Evaluatable}
+ * @param <U> the java class for the identifier
+ */
+public class DenyUnlessPermit<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> {
+
+ public DenyUnlessPermit(Identifier identifierIn) {
+ super(identifierIn);
+ }
+
+ @Override
+ public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<T>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException {
+ EvaluationResult combinedResult = new EvaluationResult(Decision.DENY);
+
+ Iterator<CombiningElement<T>> iterElements = elements.iterator();
+ while (iterElements.hasNext()) {
+ CombiningElement<T> combiningElement = iterElements.next();
+ EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext);
+
+ assert(evaluationResultElement != null);
+ switch(evaluationResultElement.getDecision()) {
+ case DENY:
+ combinedResult.merge(evaluationResultElement);
+ break;
+ case INDETERMINATE:
+ case INDETERMINATE_DENYPERMIT:
+ case INDETERMINATE_DENY:
+ case INDETERMINATE_PERMIT:
+ case NOTAPPLICABLE:
+ break;
+ case PERMIT:
+ return evaluationResultElement;
+ default:
+ throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+ }
+ }
+
+ return combinedResult;
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.java
new file mode 100755
index 0000000..02402a5
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.java
@@ -0,0 +1,58 @@
+/*
+ * 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.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+
+/**
+ * PermitOverrides extends {@link com.att.research.xacmlatt.pdp.std.combiners.CombiningAlgorithmBase} to implement the
+ * XACML 1.0 "first-applicable" combining algorithm for policies and rules.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ *
+ * @param <T> the java class of the object to be combined
+ */
+public class FirstApplicable<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> {
+
+ public FirstApplicable(Identifier identifierIn) {
+ super(identifierIn);
+ }
+
+ @Override
+ public EvaluationResult combine(EvaluationContext evaluationContext,
+ List<CombiningElement<T>> elements,
+ List<CombinerParameter> combinerParameters)
+ throws EvaluationException {
+ Iterator<CombiningElement<T>> iterElements = elements.iterator();
+ while (iterElements.hasNext()) {
+ CombiningElement<T> combiningElement = iterElements.next();
+ EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext);
+
+ assert(evaluationResultElement != null);
+ if (evaluationResultElement.getDecision() != Decision.NOTAPPLICABLE) {
+ return evaluationResultElement;
+ }
+ }
+
+ return new EvaluationResult(Decision.NOTAPPLICABLE);
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.java
new file mode 100755
index 0000000..e990b6a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.java
@@ -0,0 +1,78 @@
+/*
+ * 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.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+
+/**
+ * DenyOverrides implements the XACML 1.0 "deny-overrides" combining algorithm for policies and policy sets.
+ *
+ * @author car
+ *
+ * @param <T> the java class for the {@link com.att.research.xacmlatt.pdp.eval.Evaluatable}
+ * @param <U> the java class for the identifier
+ */
+public class LegacyDenyOverridesPolicy extends CombiningAlgorithmBase<PolicySetChild> {
+
+ public LegacyDenyOverridesPolicy(Identifier identifierIn) {
+ super(identifierIn);
+ }
+
+ @Override
+ public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<PolicySetChild>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException {
+ boolean atLeastOnePermit = false;
+
+ EvaluationResult combinedResult = new EvaluationResult(Decision.PERMIT);
+
+ Iterator<CombiningElement<PolicySetChild>> iterElements = elements.iterator();
+ while (iterElements.hasNext()) {
+ CombiningElement<PolicySetChild> combiningElement = iterElements.next();
+ EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext);
+
+ assert(evaluationResultElement != null);
+ switch(evaluationResultElement.getDecision()) {
+ case DENY:
+ return evaluationResultElement;
+ case INDETERMINATE:
+ case INDETERMINATE_DENYPERMIT:
+ case INDETERMINATE_DENY:
+ case INDETERMINATE_PERMIT:
+ return new EvaluationResult(Decision.DENY, StdStatus.STATUS_OK);
+ case NOTAPPLICABLE:
+ break;
+ case PERMIT:
+ atLeastOnePermit = true;
+ combinedResult.merge(evaluationResultElement);
+ break;
+ default:
+ throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+ }
+ }
+
+ if (atLeastOnePermit) {
+ return combinedResult;
+ } else {
+ return new EvaluationResult(Decision.NOTAPPLICABLE);
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.java
new file mode 100755
index 0000000..68e156a
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.java
@@ -0,0 +1,91 @@
+/*
+ * 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.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+import com.att.research.xacmlatt.pdp.policy.Rule;
+import com.att.research.xacmlatt.pdp.policy.RuleEffect;
+
+/**
+ * DenyOverrides implements the XACML 1.0 "deny-overrides" combining algorithm for rules.
+ *
+ * @author car
+ *
+ * @param <T> the java class for the {@link com.att.research.xacmlatt.pdp.eval.Evaluatable}
+ * @param <U> the java class for the identifier
+ */
+public class LegacyDenyOverridesRule extends CombiningAlgorithmBase<Rule> {
+
+ public LegacyDenyOverridesRule(Identifier identifierIn) {
+ super(identifierIn);
+ }
+
+ @Override
+ public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<Rule>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException {
+ boolean atLeastOnePermit = false;
+ boolean potentialDeny = false;
+
+ EvaluationResult combinedResult = new EvaluationResult(Decision.PERMIT);
+ EvaluationResult evaluationResultIndeterminate = null;
+
+ Iterator<CombiningElement<Rule>> iterElements = elements.iterator();
+ while (iterElements.hasNext()) {
+ CombiningElement<Rule> combiningElement = iterElements.next();
+ EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext);
+
+ assert(evaluationResultElement != null);
+ switch(evaluationResultElement.getDecision()) {
+ case DENY:
+ return evaluationResultElement;
+ case INDETERMINATE:
+ case INDETERMINATE_DENYPERMIT:
+ case INDETERMINATE_DENY:
+ case INDETERMINATE_PERMIT:
+ if (evaluationResultIndeterminate == null) {
+ evaluationResultIndeterminate = evaluationResultElement;
+ } else {
+ evaluationResultIndeterminate.merge(evaluationResultElement);
+ }
+ if (combiningElement.getEvaluatable().getRuleEffect() == RuleEffect.DENY) {
+ potentialDeny = true;
+ }
+ case NOTAPPLICABLE:
+ break;
+ case PERMIT:
+ atLeastOnePermit = true;
+ combinedResult.merge(evaluationResultElement);
+ break;
+ default:
+ throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+ }
+ }
+
+ if (potentialDeny) {
+ return evaluationResultIndeterminate;
+ } else if (atLeastOnePermit) {
+ return combinedResult;
+ } else if (evaluationResultIndeterminate != null) {
+ return evaluationResultIndeterminate;
+ } else {
+ return new EvaluationResult(Decision.NOTAPPLICABLE);
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.java
new file mode 100755
index 0000000..43ed569
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.java
@@ -0,0 +1,85 @@
+/*
+ * 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.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+
+/**
+ * LegacyPermitOverridesPolicy extends {@link com.att.research.xacmlatt.pdp.policy.combiners.CombiningAlgorithmBase} for
+ * {@link com.att.research.xacmlatt.pdp.policy.PolicySetChild} elements implementing the XACML 1.0 permit-overrides policy combining algorithm.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class LegacyPermitOverridesPolicy extends CombiningAlgorithmBase<PolicySetChild> {
+
+ public LegacyPermitOverridesPolicy(Identifier identifierIn) {
+ super(identifierIn);
+ }
+
+ @Override
+ public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<PolicySetChild>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException {
+ boolean atLeastOneDeny = false;
+
+ EvaluationResult evaluationResultCombined = new EvaluationResult(Decision.DENY);
+ EvaluationResult evaluationResultIndeterminate = null;
+
+ Iterator<CombiningElement<PolicySetChild>> iterElements = elements.iterator();
+ while (iterElements.hasNext()) {
+ CombiningElement<PolicySetChild> combiningElement = iterElements.next();
+ EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext);
+
+ assert(evaluationResultElement != null);
+ switch(evaluationResultElement.getDecision()) {
+ case DENY:
+ atLeastOneDeny = true;
+ evaluationResultCombined.merge(evaluationResultElement);
+ break;
+ case INDETERMINATE:
+ case INDETERMINATE_DENY:
+ case INDETERMINATE_DENYPERMIT:
+ case INDETERMINATE_PERMIT:
+ if (evaluationResultIndeterminate == null) {
+ evaluationResultIndeterminate = evaluationResultElement;
+ } else {
+ evaluationResultIndeterminate.merge(evaluationResultElement);
+ }
+ break;
+ case NOTAPPLICABLE:
+ break;
+ case PERMIT:
+ return evaluationResultElement;
+ default:
+ throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+ }
+
+ }
+
+ if (atLeastOneDeny) {
+ return evaluationResultCombined;
+ } else if (evaluationResultIndeterminate != null) {
+ return evaluationResultIndeterminate;
+ } else {
+ return new EvaluationResult(Decision.NOTAPPLICABLE);
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.java
new file mode 100755
index 0000000..446ff35
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.java
@@ -0,0 +1,91 @@
+/*
+ * 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.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+import com.att.research.xacmlatt.pdp.policy.Rule;
+import com.att.research.xacmlatt.pdp.policy.RuleEffect;
+
+/**
+ * LegacyPermitOverridesRule extends {@link com.att.research.xacmlatt.pdp.policy.combiners.CombiningAlgorithmBase} for
+ * {@link com.att.research.xacmlatt.pdp.policy.Rule}s to implement the XACML 1.0 permit-overrides rule combining algorithm.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class LegacyPermitOverridesRule extends CombiningAlgorithmBase<Rule> {
+
+ public LegacyPermitOverridesRule(Identifier identifierIn) {
+ super(identifierIn);
+ }
+
+ @Override
+ public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<Rule>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException {
+ boolean atLeastOneDeny = false;
+ boolean potentialPermit = false;
+
+ EvaluationResult evaluationResultCombined = new EvaluationResult(Decision.DENY);
+ EvaluationResult evaluationResultIndeterminate = null;
+
+ Iterator<CombiningElement<Rule>> iterElements = elements.iterator();
+ while (iterElements.hasNext()) {
+ CombiningElement<Rule> combiningElement = iterElements.next();
+ EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext);
+
+ assert(evaluationResultElement != null);
+ switch(evaluationResultElement.getDecision()) {
+ case DENY:
+ atLeastOneDeny = true;
+ evaluationResultCombined.merge(evaluationResultElement);
+ break;
+ case INDETERMINATE:
+ case INDETERMINATE_DENYPERMIT:
+ case INDETERMINATE_DENY:
+ case INDETERMINATE_PERMIT:
+ if (evaluationResultIndeterminate == null) {
+ evaluationResultIndeterminate = evaluationResultElement;
+ } else {
+ evaluationResultIndeterminate.merge(evaluationResultElement);
+ }
+ if (combiningElement.getEvaluatable().getRuleEffect() == RuleEffect.PERMIT) {
+ potentialPermit = true;
+ }
+ break;
+ case NOTAPPLICABLE:
+ break;
+ case PERMIT:
+ return evaluationResultElement;
+ default:
+ throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+ }
+ }
+
+ if (potentialPermit) {
+ return evaluationResultIndeterminate;
+ } else if (atLeastOneDeny) {
+ return evaluationResultCombined;
+ } else if (evaluationResultIndeterminate != null) {
+ return evaluationResultIndeterminate;
+ } else {
+ return new EvaluationResult(Decision.NOTAPPLICABLE);
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.java
new file mode 100755
index 0000000..f5f8f35
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.java
@@ -0,0 +1,78 @@
+/*
+ * 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.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+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.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.eval.MatchResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+import com.att.research.xacmlatt.pdp.policy.PolicySetChild;
+
+/**
+ * OnlyOneApplicable extends {@link com.att.research.xacmlatt.pdp.std.combiners.CombiningAlgorithmBase} to implement the
+ * XACML 1.0 "only-one-applicable" combining algorithm for policies and rules.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ *
+ * @param <T> the java class of the object to be combined
+ */
+public class OnlyOneApplicable extends CombiningAlgorithmBase<PolicySetChild> {
+
+ public OnlyOneApplicable(Identifier identifierIn) {
+ super(identifierIn);
+ }
+
+ @Override
+ public EvaluationResult combine(EvaluationContext evaluationContext,
+ List<CombiningElement<PolicySetChild>> elements,
+ List<CombinerParameter> combinerParameters)
+ throws EvaluationException {
+ Iterator<CombiningElement<PolicySetChild>> iterElements = elements.iterator();
+ PolicySetChild policySetChildApplicable = null;
+ while (iterElements.hasNext()) {
+ CombiningElement<PolicySetChild> combiningElement = iterElements.next();
+ MatchResult matchResultElement = combiningElement.getEvaluatable().match(evaluationContext);
+
+ switch(matchResultElement.getMatchCode()) {
+ case INDETERMINATE:
+ return new EvaluationResult(Decision.INDETERMINATE, matchResultElement.getStatus());
+ case MATCH:
+ if (policySetChildApplicable == null) {
+ policySetChildApplicable = combiningElement.getEvaluatable();
+ } else {
+ return new EvaluationResult(Decision.INDETERMINATE, new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "More than one applicable policy"));
+ }
+ break;
+ case NOMATCH:
+ break;
+ default:
+ throw new EvaluationException("Illegal Decision: \"" + matchResultElement.getMatchCode().toString());
+ }
+ }
+
+ if (policySetChildApplicable != null) {
+ return policySetChildApplicable.evaluate(evaluationContext);
+ } else {
+ return new EvaluationResult(Decision.NOTAPPLICABLE);
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.java
new file mode 100755
index 0000000..ef34403
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.java
@@ -0,0 +1,109 @@
+/*
+ * 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.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+
+/**
+ * PermitOverrides extends {@link com.att.research.xacmlatt.pdp.std.combiners.CombiningAlgorithmBase} to implement the
+ * XACML 3.0 Permit-overrides combining algorithm for policies and rules.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ *
+ * @param <T> the java class of the object to be combined
+ */
+public class PermitOverrides<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> {
+
+ public PermitOverrides(Identifier identifierIn) {
+ super(identifierIn);
+ }
+
+ @Override
+ public EvaluationResult combine(EvaluationContext evaluationContext,
+ List<CombiningElement<T>> elements,
+ List<CombinerParameter> combinerParameters)
+ throws EvaluationException {
+ boolean atLeastOneDeny = false;
+
+ EvaluationResult combinedResult = new EvaluationResult(Decision.DENY);
+
+ EvaluationResult firstIndeterminateD = null;
+ EvaluationResult firstIndeterminateP = null;
+ EvaluationResult firstIndeterminateDP = null;
+
+ Iterator<CombiningElement<T>> iterElements = elements.iterator();
+ while (iterElements.hasNext()) {
+ CombiningElement<T> combiningElement = iterElements.next();
+ EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext);
+
+ assert(evaluationResultElement != null);
+ switch(evaluationResultElement.getDecision()) {
+ case DENY:
+ atLeastOneDeny = true;
+ combinedResult.merge(evaluationResultElement);
+ break;
+ case INDETERMINATE:
+ case INDETERMINATE_DENYPERMIT:
+ if (firstIndeterminateDP == null) {
+ firstIndeterminateDP = evaluationResultElement;
+ } else {
+ firstIndeterminateDP.merge(evaluationResultElement);
+ }
+ break;
+ case INDETERMINATE_DENY:
+ if (firstIndeterminateD == null) {
+ firstIndeterminateD = evaluationResultElement;
+ } else {
+ firstIndeterminateD.merge(evaluationResultElement);
+ }
+ break;
+ case INDETERMINATE_PERMIT:
+ if (firstIndeterminateP == null) {
+ firstIndeterminateP = evaluationResultElement;
+ } else {
+ firstIndeterminateP.merge(evaluationResultElement);
+ }
+ break;
+ case NOTAPPLICABLE:
+ break;
+ case PERMIT:
+ return evaluationResultElement;
+ default:
+ throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+ }
+ }
+
+ if (firstIndeterminateDP != null) {
+ return firstIndeterminateDP;
+ } else if (firstIndeterminateP != null && (firstIndeterminateD != null || atLeastOneDeny)) {
+ return new EvaluationResult(Decision.INDETERMINATE_DENYPERMIT, firstIndeterminateD.getStatus());
+ } else if (firstIndeterminateP != null) {
+ return firstIndeterminateP;
+ } else if (atLeastOneDeny) {
+ return combinedResult;
+ } else if (firstIndeterminateD != null) {
+ return firstIndeterminateD;
+ } else {
+ return new EvaluationResult(Decision.NOTAPPLICABLE);
+ }
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.java
new file mode 100755
index 0000000..b1b0ee0
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.java
@@ -0,0 +1,69 @@
+/*
+ * 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.combiners;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Decision;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.eval.EvaluationException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationResult;
+import com.att.research.xacmlatt.pdp.policy.CombinerParameter;
+import com.att.research.xacmlatt.pdp.policy.CombiningElement;
+
+/**
+ * PermitUnlessDeny implements the XACML 3.0 "permit-unless-deny" combining algorithm for both policies and rules.
+ *
+ * @author car
+ *
+ * @param <T> the java class for the {@link com.att.research.xacmlatt.pdp.eval.Evaluatable}
+ * @param <U> the java class for the identifier
+ */
+public class PermitUnlessDeny<T extends com.att.research.xacmlatt.pdp.eval.Evaluatable> extends CombiningAlgorithmBase<T> {
+
+ public PermitUnlessDeny(Identifier identifierIn) {
+ super(identifierIn);
+ }
+
+ @Override
+ public EvaluationResult combine(EvaluationContext evaluationContext, List<CombiningElement<T>> elements, List<CombinerParameter> combinerParameters) throws EvaluationException {
+ EvaluationResult combinedResult = new EvaluationResult(Decision.PERMIT);
+
+ Iterator<CombiningElement<T>> iterElements = elements.iterator();
+ while (iterElements.hasNext()) {
+ CombiningElement<T> combiningElement = iterElements.next();
+ EvaluationResult evaluationResultElement = combiningElement.evaluate(evaluationContext);
+
+ assert(evaluationResultElement != null);
+ switch(evaluationResultElement.getDecision()) {
+ case DENY:
+ return evaluationResultElement;
+ case INDETERMINATE:
+ case INDETERMINATE_DENYPERMIT:
+ case INDETERMINATE_DENY:
+ case INDETERMINATE_PERMIT:
+ break;
+ case NOTAPPLICABLE:
+ break;
+ case PERMIT:
+ combinedResult.merge(evaluationResultElement);
+ break;
+ default:
+ throw new EvaluationException("Illegal Decision: \"" + evaluationResultElement.getDecision().toString());
+ }
+ }
+
+ return combinedResult;
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/package-info.java
new file mode 100755
index 0000000..db6b8f4
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.combiners;
+
+/**
+ * com.att.research.xacmlatt.pdp.std.combiners contains implementations of the {@link com.att.research.xacmlatt.pdp.policy.CombiningAlgorithm}
+ * interface.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.java
new file mode 100755
index 0000000..9b81539
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.java
@@ -0,0 +1,204 @@
+/*
+ * 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.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.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacmlatt.pdp.policy.Bag;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+/**
+ * A ConvertedArgument is the result of processing an {@link com.att.research.xacmlatt.pdp.policy.FunctionArgument}
+ * to validate its correctness and to convert it into an object of the required type.
+ * It is returned by the <code>validateArguments</code> method in
+ * {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple}
+ * and should only be used by other Functions in that same package.
+ * This is a data holder with no processing.
+ * It contains two elements:
+ * <UL>
+ * <LI>
+ * A {@link com.att.research.xacml.api.Status} object, and
+ * <LI>
+ * An object containing the value of the FunctionArgument processed by validateArguments.
+ * This object will only exist if status.isOk() (or the isOk() method in this class that calls status.isOk()) is true.
+ * </UL>
+ *
+ *
+ * @author glenngriffin
+ *
+ */
+public class ConvertedArgument<I> {
+
+ // When status != Status.OK, the value is null
+ private Status status;
+
+ // This is non-null when status == Status.OK
+ private I value = null;
+
+ /**
+ * Constructor ensures we have a non-null status, though value will be null if status is not ok.
+ *
+ * @param s
+ * @param v
+ */
+ public ConvertedArgument(Status s, I v) {
+ status = s;
+ if (s == null) {
+ throw new IllegalArgumentException("Status of argument cannot be null");
+ }
+ if (s.isOk()) {
+ // only set value if status is ok
+ value = v;
+ }
+ }
+
+ /**
+ * Get the Status object
+ *
+ * @return
+ */
+ public Status getStatus() {
+ return status;
+ }
+
+
+ /**
+ * Convenience method that directly returns the isOk() state from the status object.
+ *
+ * @return
+ */
+ public boolean isOk() {
+ return status.isOk();
+ }
+
+
+ /**
+ * Get the value object. This may be a Bag.
+ *
+ * @return
+ */
+ public I getValue() {
+ return value;
+ }
+
+
+ /**
+ * Get the value as a Bag. (convenience method)
+ *
+ * @return
+ */
+ public Bag getBag() {
+ return (Bag)value;
+ }
+
+
+ /**
+ * 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);
+ }
+ }
+
+
+
+ /**
+ * Evaluates the given <code>FunctionArgument</code> and validates that it has the correct <code>DataType</code>.
+ * The returned object will be either:
+ * <UL>
+ * <LI>
+ * A Status Object indicating an error condition, or
+ * <LI>
+ * An Object of the appropriate type containing the value of the function.
+ * In this case the caller should assume that the Status is Status.OK.
+ * Note that the object may be a bag if that is what the caller expected.
+ * </UL>
+ *
+ *
+ * @param listFunctionArguments the <code>List</code> of <code>FunctionArgument</code>s to validate
+ * @param convertedValues the <code>List</code> of <code>U</code> that the converted value is added to.
+ * @return a {@link com.att.research.xacml.api.Status} indication with an error if the arguments are not valid,
+ * or an object of the correct DataType containing the value.
+ */
+ @SuppressWarnings("unchecked") // to suppress warning on bag conversion
+ public ConvertedArgument(FunctionArgument functionArgument, DataType<I> expectedDataType, boolean expectBag) {
+
+ if (functionArgument == null ) {
+ status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Got null argument");
+ return;
+ }
+ if ( ! functionArgument.isOk()) {
+ status = functionArgument.getStatus();
+ return;
+ }
+
+ // bags are valid arguments for some functions
+ if (expectBag) {
+ if ( ! functionArgument.isBag()) {
+ status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Expected a bag, saw a simple value");
+ return;
+ }
+
+ Bag bag = functionArgument.getBag();
+ value = (I) bag;
+ status = StdStatus.STATUS_OK;
+ return;
+ }
+
+ // argument should not be a bag
+ if (functionArgument.isBag()) {
+ status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Expected a simple value, saw a bag");
+ return;
+ }
+ AttributeValue<?> attributeValue = functionArgument.getValue();
+ if (attributeValue == null || attributeValue.getValue() == null) {
+ status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Got null attribute");
+ return;
+ }
+ if ( ! attributeValue.getDataTypeId().equals(expectedDataType.getId())) {
+ status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Expected data type '" +
+ getShortDataTypeId(expectedDataType.getId()) + "' saw '" + getShortDataTypeId(attributeValue.getDataTypeId()) + "'");
+ return;
+ }
+
+ try {
+ value = expectedDataType.convert(attributeValue.getValue());
+ status = StdStatus.STATUS_OK;
+ } catch (Exception e) {
+ String message = e.getMessage();
+ if (e.getCause() != null) {
+ message = e.getCause().getMessage();
+ }
+ status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, message);
+ }
+ }
+
+
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.java
new file mode 100755
index 0000000..c8109ce
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.java
@@ -0,0 +1,198 @@
+/*
+ * 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.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Node;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.RequestAttributes;
+import com.att.research.xacml.std.StdRequest;
+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.dom.DOMRequestAttributes;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+/**
+ * FunctionDefinitionAccessPermitted implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to
+ * implement the XACML access-permitted predicate.
+ *
+ * WARNING: This code is unfinished. Initially we did not complete the implementation because we did not understand how to handle XML Namespaces
+ * (from the <Request> or <Policy>).
+ * Later we understood that any Namespaces used within this function must be explicitly listed in <Content> XML elemement passed to this function.
+ * However, it is not clear that anyone needs this function.
+ * The only use anyone has mentioned is in a recursive operation which requires a loop counter of some kind, which we do not have implemented.
+ * Therefore we have chosen to leave this unimplemented for now.
+ *
+ * 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:
+ * access-permitted
+ *
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ */
+public class FunctionDefinitionAccessPermitted extends FunctionDefinitionBase<Boolean, URI> {
+
+
+
+
+ /**
+ * Constructor - need dataTypeArgs input because of java Generic type-erasure during compilation.
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ */
+ public FunctionDefinitionAccessPermitted(Identifier idIn) {
+ super(idIn, DataTypes.DT_BOOLEAN, DataTypes.DT_ANYURI, 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, this.getShortFunctionId() +
+ " Expected 2 arguments, got " +
+ ((arguments == null) ? "null" : arguments.size()) ));
+ }
+
+ // first arg is URI
+ FunctionArgument functionArgument = arguments.get(0);
+ ConvertedArgument<URI> convertedArgument0 = new ConvertedArgument<URI>(functionArgument, DataTypes.DT_ANYURI, false);
+ if ( ! convertedArgument0.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedArgument0.getStatus()));
+ }
+ URI attributesURI = convertedArgument0.getValue();
+ // this must be a urn of an attribute category
+ if ( ! attributesURI.toString().startsWith("urn:") || ! attributesURI.toString().contains(":attribute-category:")) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() +
+ " First argument must be a urn for an attribute-category, not '" + attributesURI.toString() ));
+ }
+
+ // second argument is of input type
+ functionArgument = arguments.get(1);
+ ConvertedArgument<String> convertedArgument1 = new ConvertedArgument<String>(functionArgument, DataTypes.DT_STRING, 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
+ String xmlContent = convertedArgument1.getValue();
+
+ // The spec is fuzzy on whether this string includes the "<Content>" tags or not, so handle it either way
+ if ( ! xmlContent.trim().toLowerCase().startsWith("<content>") ) {
+ // incomming is not surrounded by <content> tags, so ad them
+ xmlContent = "<Content>" + xmlContent + "</Content>";
+ }
+
+//TODO - the next block needs to be uncommented and fixed
+//Request req = evaluationContext.getRequest();
+//List<String> xmlAttrList = req.getRequestXMLAttributes();
+//String attrString = " ";
+//for (String attr : xmlAttrList) {
+// attrString += " " + attr;
+//}
+//
+// // add the Attributes XML element
+// xmlContent = "<Attributes Category=\"" + attributesURI + "\" " + attrString + " >" + xmlContent + "</Attributes>";
+
+//java.util.Iterator<RequestAttributes> rait = req.getRequestAttributes();
+//while (rait.hasNext()) {
+// RequestAttributes ra = rait.next();
+// System.out.println(ra);
+//}
+
+
+
+ // convert the xmlContent into XML Nodes
+ Node newContentNode = null;
+//TODO - need to get Namespace info from original Request? How can I recover the original Namespace from the EvaluationContext?
+ try (InputStream is = new ByteArrayInputStream(xmlContent.getBytes())) {
+ DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
+ docBuilderFactory.setNamespaceAware(true);
+
+ newContentNode = docBuilderFactory
+ .newDocumentBuilder()
+ .parse(is)
+ .getDocumentElement();
+ } catch (Exception e) {
+ String message = e.getMessage();
+ if (e.getCause() != null) {
+ message = e.getCause().getMessage();
+ }
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() +
+ " Parsing of XML string failed. Cause='" + message + "'" ));
+ }
+ // convert the XML Node into a RequestAttributes object
+//TODO - If this code is ever completed, the following variable will be used. The annotation is to avoid warnings.
+@SuppressWarnings("unused")
+ RequestAttributes newRequestAttributes = null;
+ try {
+ newRequestAttributes = DOMRequestAttributes.newInstance(newContentNode);
+ } catch (DOMStructureException e) {
+ String message = e.getMessage();
+ if (e.getCause() != null) {
+ message = e.getCause().getMessage();
+ }
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() +
+ " Conversion of XML to RequestAttributes failed. Cause='" + message + "'" ));
+ }
+
+
+ // check the evaluationContext and Request for null
+ if (evaluationContext == null) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Got null EvaluationContext"));
+ }
+ if (evaluationContext.getRequest() == null) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Got null Request in EvaluationContext"));
+ }
+
+ // Create a new Request by:
+ // - copying the current request,
+ // - Dropping the Attributes section identified by the attributesURI argument
+ // - adding a new Attributes section identified by the attributesURI arg and with a Content section containing the xmlContent argument
+ Request originalRequest = evaluationContext.getRequest();
+
+//TODO - If this code is ever completed, the following variable will be used. The annotation is to avoid warnings.
+@SuppressWarnings("unused")
+ Request newRequest = new StdRequest(originalRequest);
+
+
+
+// ???? nameingContext????
+
+ // Now create a new EvaluationContext matching the one passed to this method except for the Request
+//TODO
+
+ // Run the PDP on the new EvaluationContext
+//TODO
+
+
+return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Not Implemented"));
+
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.java
new file mode 100755
index 0000000..03bd34f
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.java
@@ -0,0 +1,196 @@
+/*
+ * 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.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;
+
+/**
+ * FunctionDefinitionArithmetic extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to
+ * implement the XACML Arithmetic predicates as functions taking one or two arguments of the same data type and returning a single value of the same type.
+ *
+ * In Java there is no way to do arithmetic operations generically, so we need to have individual code for each operation on each class within this class.
+ *
+ * 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-add
+ * double-add
+ * integer-subtract
+ * double-subtract
+ * integer-multiply
+ * double-multiply
+ * integer-divide
+ * double-divide
+ * integer-mod
+ * integer-abs
+ * double-abs
+ * round
+ * floor
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ * @param <T> the java class for the data type of the function arguments
+ */
+public class FunctionDefinitionArithmetic<T extends Number> extends FunctionDefinitionHomogeneousSimple<T,T> {
+
+ /**
+ * List of arithmetic operations.
+ *
+ * @author glenngriffin
+ *
+ */
+ public enum OPERATION {ADD, SUBTRACT, MULTIPLY, DIVIDE, MOD, ABS, ROUND, FLOOR };
+
+ // operation to be used in this instance of the Arightmetic class
+ private final OPERATION operation;
+
+ // result variables used by all functions, one for each type
+ private AttributeValue<BigInteger> integerResult;
+ private AttributeValue<Double> doubleResult;
+
+ /**
+ * Constructor
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ * @param op
+ */
+ public FunctionDefinitionArithmetic(Identifier idIn, DataType<T> dataTypeArgsIn, OPERATION op, int nArgs) {
+ // for Arithmetic functions, the output type is the same as the input type (no mixing of Ints and Doubles!)
+ super(idIn, dataTypeArgsIn, dataTypeArgsIn, nArgs);
+
+ // save the operation to be used in this instance
+ operation = op;
+ }
+
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+ List<T> convertedArguments = new ArrayList<T>();
+ 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 perform the requested operation.
+ */
+ ExpressionResult expressionResult = null;
+
+ try {
+ switch (operation) {
+ case ADD:
+ if (this.getDataType() == DataTypes.DT_INTEGER) {
+ integerResult = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).add( (BigInteger)convertedArguments.get(1)) );
+ expressionResult = ExpressionResult.newSingle(integerResult);
+ } else {
+ doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, (Double)convertedArguments.get(0) + (Double)convertedArguments.get(1));
+ expressionResult = ExpressionResult.newSingle(doubleResult);
+ }
+ break;
+ case SUBTRACT:
+ if (this.getDataType() == DataTypes.DT_INTEGER) {
+ integerResult = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).subtract( (BigInteger)convertedArguments.get(1)) );
+ expressionResult = ExpressionResult.newSingle(integerResult);
+ } else {
+ doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, (Double)convertedArguments.get(0) - (Double)convertedArguments.get(1));
+ expressionResult = ExpressionResult.newSingle(doubleResult);
+ }
+ break;
+ case MULTIPLY:
+ if (this.getDataType() == DataTypes.DT_INTEGER) {
+ integerResult = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).multiply((BigInteger)convertedArguments.get(1)) );
+ expressionResult = ExpressionResult.newSingle(integerResult);
+ } else {
+ doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, (Double)convertedArguments.get(0) * (Double)convertedArguments.get(1));
+ expressionResult = ExpressionResult.newSingle(doubleResult);
+ }
+ break;
+ case DIVIDE:
+ if (this.getDataType() == DataTypes.DT_INTEGER) {
+ if ( ((BigInteger)convertedArguments.get(1)).equals(new BigInteger("0")) ) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +" Divide by 0 error: "+
+ arguments.get(0).getValue().getValue().toString() + ", " + arguments.get(1).getValue().getValue().toString()));
+ }
+ integerResult = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).divide((BigInteger)convertedArguments.get(1)) );
+ expressionResult = ExpressionResult.newSingle(integerResult);
+ } else {
+ if ((Double)convertedArguments.get(1) == 0) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +" Divide by 0 error: "+
+ arguments.get(0).getValue().getValue().toString() + ", " + arguments.get(1).getValue().getValue().toString()));
+ }
+ doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, (Double)convertedArguments.get(0) / (Double)convertedArguments.get(1));
+ expressionResult = ExpressionResult.newSingle(doubleResult);
+ }
+ break;
+ case MOD:
+ if ( ((BigInteger)convertedArguments.get(1)).equals(new BigInteger("0")) ) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +" Divide by 0 error: "+
+ arguments.get(0).getValue().getValue().toString() + ", " + arguments.get(1).getValue().getValue().toString()));
+ }
+ integerResult = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).remainder((BigInteger)convertedArguments.get(1)) );
+ expressionResult = ExpressionResult.newSingle(integerResult);
+ break;
+ case ABS:
+ if (this.getDataType() == DataTypes.DT_INTEGER) {
+ integerResult = new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, ((BigInteger)convertedArguments.get(0)).abs() );
+ expressionResult = ExpressionResult.newSingle(integerResult);
+ } else {
+ doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, Math.abs((Double)convertedArguments.get(0)));
+ expressionResult = ExpressionResult.newSingle(doubleResult);
+ }
+ break;
+ case ROUND:
+ doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, (double)(Math.round((Double)convertedArguments.get(0))) );
+ expressionResult = ExpressionResult.newSingle(doubleResult);
+ break;
+ case FLOOR:
+ doubleResult = new StdAttributeValue<Double>(XACML.ID_DATATYPE_DOUBLE, Math.floor((Double)convertedArguments.get(0)));
+ expressionResult = ExpressionResult.newSingle(doubleResult);
+ break;
+ }
+ } catch (Exception e) {
+ String message = e.getMessage();
+ if (e.getCause() != null) {
+ message = e.getCause().getMessage();
+ }
+ String args = arguments.get(0).getValue().toString();
+ if (arguments.size() > 1) {
+ args += ", " + arguments.get(1).getValue().toString();
+ }
+ expressionResult = ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message +
+ " args: " + args + " " + e.getMessage() ));
+ }
+
+ return expressionResult;
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.java
new file mode 100755
index 0000000..cbdb406
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.java
@@ -0,0 +1,107 @@
+/*
+ * 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.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;
+
+/**
+ * FunctionDefinitionBag implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to
+ * implement the XACML 'type'-bag predicates as functions taking 0, 1 or multiple arguments of the same data type and returning a <code>Bag</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-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
+ * ipAddress-bag
+ * dnsName-bag
+ *
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ * @param <I> the java class for the data type of the function Input arguments,
+ * which is also the "type" of the returned bag
+ */
+public class FunctionDefinitionBag<I> extends FunctionDefinitionBase<I, I> {
+
+
+ /**
+ * Constructor - need dataType input because of java Generic type-erasure during compilation.
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ */
+ public FunctionDefinitionBag(Identifier idIn, DataType<I> dataTypeArgsIn) {
+ super(idIn, dataTypeArgsIn, dataTypeArgsIn, true);
+ }
+
+ /**
+ * 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) {
+
+ // create a list to put the values into
+ Bag elementBag = new Bag();
+
+ // see if we have arguments
+ if (arguments != null && arguments.size() > 0) {
+
+ // for each arg, evaluate it, check type, and put on the list
+ for (FunctionArgument argument : arguments) {
+ // get the argument, evaluate it and check status
+ ConvertedArgument<I> convertedArgument = new ConvertedArgument<I>(argument, this.getDataTypeArgs(), false);
+
+ // check the status
+ if ( ! convertedArgument.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedArgument.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.
+ elementBag.add(argument.getValue());
+ }
+ }
+
+ // return it
+ return ExpressionResult.newBag(elementBag);
+ }
+
+
+
+
+}
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;
+ }
+
+
+
+
+}
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);
+ }
+
+
+
+
+
+}
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);
+ }
+
+
+
+}
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;
+ }
+
+
+
+}
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));
+
+ }
+
+
+
+}
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;
+ }
+
+}
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;
+ }
+ }
+
+}
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);
+ }
+ }
+
+
+
+
+
+
+
+
+}
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;
+ }
+
+
+
+
+}
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));
+
+ }
+
+
+
+}
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;
+ }
+
+}
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;
+ }
+ }
+
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.java
new file mode 100755
index 0000000..ad442ae
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.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.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.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;
+
+/**
+ * FunctionDefinitionRegexMatch implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to
+ * implement the XACML 'type'-regex-match predicates as functions taking two arguments, the first of <code>String</code>,
+ * representing a regular expression, and the second of the type for that specific predicate,
+ * and returning a <code>Boolean</code> for whether the regular expression matches the string representation of the second argument.
+ *
+ * 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-regexp-match
+ * anyURI-regexp-match
+ * x500Name-regexp-match
+ * rfc822Name-regexp-match (in sub-class {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition.FunctionDefinitionRegexpMatchRFC822} )
+ * ipAddress-regexp-match
+ * dnsName-regexp-match
+ *
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ * @param <I> the java class for the data type of the function Input arguments
+ */
+public class FunctionDefinitionRegexpMatch<I> extends FunctionDefinitionBase<Boolean, I> {
+
+
+ /**
+ * Constructor - need dataTypeArgs input because of java Generic type-erasure during compilation.
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ */
+ public FunctionDefinitionRegexpMatch(Identifier idIn, DataType<I> dataTypeArgsIn) {
+ super(idIn, DataTypes.DT_BOOLEAN, dataTypeArgsIn, 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, this.getShortFunctionId() + " Expected 2 arguments, got " +
+ ((arguments == null) ? "null" : arguments.size()) ));
+ }
+
+ // get the regular expression
+ FunctionArgument regexpArgument = arguments.get(0);
+
+ ConvertedArgument<String> convertedArgument = new ConvertedArgument<String>(regexpArgument, DataTypes.DT_STRING, false);
+ if ( ! convertedArgument.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedArgument.getStatus()));
+ }
+
+ // String regexpValue = (String)regexpArgument.getValue().getValue();
+ String regexpValue = convertedArgument.getValue();
+
+
+ // now get the element to match
+ FunctionArgument elementArgument = arguments.get(1);
+
+ ConvertedArgument<I> convertedElement = new ConvertedArgument<I>(elementArgument, this.getDataTypeArgs(), false);
+ if ( ! convertedElement.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedElement.getStatus()));
+ }
+
+ I elementValueObject = convertedElement.getValue();
+
+ String elementValueString;
+ try {
+ elementValueString = this.getDataTypeArgs().toStringValue(elementValueObject);
+ } 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));
+ }
+
+ // ConvertedArgument checks for null value, so do not need to do again here
+
+ if (elementValueString.matches(regexpValue)) {
+ return ER_TRUE;
+ } else {
+ return ER_FALSE;
+ }
+
+ }
+
+
+
+
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.java
new file mode 100755
index 0000000..1595a47
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.java
@@ -0,0 +1,230 @@
+/*
+ * 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.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;
+
+/**
+ * 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 FunctionDefinitionSet<O,I> extends FunctionDefinitionBase<O, I> {
+
+ /**
+ * List of comparison operations.
+ *
+ * @author glenngriffin
+ *
+ */
+ public enum OPERATION {INTERSECTION, AT_LEAST_ONE_MEMBER_OF, UNION, SUBSET, SET_EQUALS };
+
+ // 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 FunctionDefinitionSet(Identifier idIn, DataType<O> dataTypeIn, DataType<I> dataTypeArgsIn, OPERATION opIn) {
+ super(idIn, dataTypeIn, dataTypeArgsIn, ((opIn == OPERATION.INTERSECTION || opIn == OPERATION.UNION) ? true : false) );
+ operation = opIn;
+ }
+
+
+ @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 first bag
+ FunctionArgument bagArgument = arguments.get(0);
+ ConvertedArgument<Bag> convertedBagArgument = new ConvertedArgument<Bag>(bagArgument, null, true);
+
+ if ( ! convertedBagArgument.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedBagArgument.getStatus()));
+ }
+
+ Bag bag1 = convertedBagArgument.getBag();
+ List<AttributeValue<?>> list1 = (List<AttributeValue<?>>) bag1.getAttributeValueList();
+
+ // get second bag
+ bagArgument = arguments.get(1);
+ convertedBagArgument = new ConvertedArgument<Bag>(bagArgument, null, true);
+
+ if ( ! convertedBagArgument.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedBagArgument.getStatus()));
+ }
+
+ Bag bag2 = convertedBagArgument.getBag();
+ List<AttributeValue<?>> list2 = (List<AttributeValue<?>>) bag2.getAttributeValueList();
+
+ // arguments are ready BUT they have NOT had duplicates removed
+
+ ExpressionResult expressionResult = null;
+
+ // some functions return a bag rather than boolean
+ Bag outBag;
+ List<AttributeValue<?>> outList;
+
+
+ switch (operation) {
+ case INTERSECTION:
+ outList = new ArrayList<AttributeValue<?>>();
+
+ for (AttributeValue<?> element : list1) {
+ if (outList.contains(element)) {
+ continue;
+ }
+ if (list2.contains(element)) {
+ outList.add(element);
+ }
+ }
+
+ // now have the intersection; put it in a bag
+
+ outBag = new Bag();
+
+ for (AttributeValue<?> element : outList) {
+ outBag.add(element);
+ }
+
+ expressionResult = ExpressionResult.newBag(outBag);
+ return expressionResult;
+
+
+ case AT_LEAST_ONE_MEMBER_OF:
+ // look for elements from the first list in the second.
+ // duplicates do not matter because if the element is not there it does not matter that we look for it again,
+ // and if it is there we stop the first time we see it.
+ // If the first bag is empty, this should fail because no element from the first set can be found in the second set
+ // (because there IS no element in first set).
+ for (AttributeValue<?> element : list1) {
+ if (list2.contains(element)) {
+ return ER_TRUE;
+ }
+ }
+ // did not find any element from list 1 in list 2
+ return ER_FALSE;
+
+ case UNION:
+ outList = new ArrayList<AttributeValue<?>>();
+
+ for (AttributeValue<?> element : list1) {
+ if (outList.contains(element)) {
+ continue;
+ }
+ outList.add((AttributeValue<?>) element);
+ }
+ for (AttributeValue<?> element : list2) {
+ if (outList.contains(element)) {
+ continue;
+ }
+ outList.add((AttributeValue<?>) element);
+ }
+
+ // now have the intersection; put it in a bag
+
+ outBag = new Bag();
+
+ for (AttributeValue<?> element : outList) {
+ outBag.add(element);
+ }
+
+ expressionResult = ExpressionResult.newBag(outBag);
+ return expressionResult;
+
+
+ case SUBSET:
+ // all elements from list 1 must exist in list 2.
+ // duplicates do not matter because if an element is not found the first time we stop immediately,
+ // and if it is found the first time it will also be found for the duplicate.
+ // If the first set is empty we return TRUE because all elements (i.e. none) in the first set are in the second.
+ for (AttributeValue<?> element : list1) {
+ if ( ! list2.contains(element)) {
+ return ER_FALSE;
+ }
+ }
+ // all elements in list1 were found
+ return ER_TRUE;
+
+
+ case SET_EQUALS:
+ // we cannot do a direct one-to-one compare because the lists may contain duplicates. Also they may not be ordered the same.
+ // So we ask:
+ // are all elements in list 1 in list 2 (ignoring duplicates)
+ // are all elements in list 2 in list 1 (ignoring duplicates)
+ for (AttributeValue<?> element : list1) {
+ if ( ! list2.contains(element)) {
+ return ER_FALSE;
+ }
+ }
+ for (AttributeValue<?> element : list2) {
+ if ( ! list1.contains(element)) {
+ return ER_FALSE;
+ }
+ }
+ // all elements in each are part of the other
+ return ER_TRUE;
+ }
+
+ // 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 Set function " + operation));
+
+ }
+
+
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.java
new file mode 100755
index 0000000..bde0bbe
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.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.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.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.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+/**
+ * FunctionDefinitionNumberTypeConversion extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to
+ * implement the XACML predicates for converting <code>String</code> to <code>DataType<?></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:
+ * boolean-from-string
+ * string-from-boolean
+ * integer-from-string
+ * string-from-integer
+ * double-from-string
+ * string-from-double
+ * time-from-string
+ * string-from-time
+ * date-from-string
+ * string-from-date
+ * dateTime-from-string
+ * string-from-dateTime
+ * anyURI-from-string
+ * string-from-anyURI
+ * dayTimeDuration-from-string
+ * string-from-dayTimeDuration
+ * yearMonthDuration-from-string
+ * string-from-yearMonthDuration
+ * x500Name-from-string
+ * string-from-x500Name
+ * rfc822Name-from-string
+ * string-from-rfc822Name
+ * ipAddress-from-string
+ * string-from-ipAddress
+ * dnsName-from-string
+ * string-from-dnsName
+ *
+ * @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 FunctionDefinitionStringConversion<O,I> extends FunctionDefinitionHomogeneousSimple<O, I> {
+
+ public FunctionDefinitionStringConversion(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));
+ }
+
+ /*
+ * Do different conversion depending on which way we are going (to/from String)
+ */
+ if (this.getDataTypeId().equals(DataTypes.DT_STRING.getId())) {
+ // converting TO String
+ try {
+ String output = this.getDataTypeArgs().toStringValue(convertedArguments.get(0));
+ return ExpressionResult.newSingle(new StdAttributeValue<String>(this.getDataTypeId(), output));
+ } catch (Exception e) {
+ String message = e.getMessage();
+ if (e.getCause() != null) {
+ message = e.getCause().getMessage();
+ }
+ // untested - not clear how this could happen
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " + message));
+ }
+ } else {
+ // converting FROM String to object of DataType
+ try {
+ O output = this.getDataType().convert(convertedArguments.get(0));
+ return ExpressionResult.newSingle(new StdAttributeValue<O>(this.getDataTypeId(), output));
+ } catch (Exception e) {
+ String message = e.getMessage();
+ if (e.getCause() != null) {
+ message = e.getCause().getMessage();
+ }
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() + " " + message ));
+ }
+ }
+
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.java
new file mode 100755
index 0000000..b8aae7d
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.java
@@ -0,0 +1,55 @@
+/*
+ * 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.Identifier;
+import com.att.research.xacml.std.datatypes.DataTypes;
+
+/**
+ * FunctionDefinitionStringEqualIgnoreCase extends {@link FunctionDefinitionEquality} for
+ * <code>String</code> arguments by testing for equality without regard to case.
+ *
+ * The specification actually says that the strings are first converted to lower case using the string-normalize-to-lower-case function.
+ * This code ASSUMES that
+ * <UL>
+ * <LI> the normalize function just calls the Java toLowerCase() function, and
+ * <LI> the Java VM is consistent in that equalsIgnoreCase provides the same result as calling toLowerCase on each string and doing a compare.
+ * </UL>
+ *
+ * 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-ignore-case
+ *
+ *
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class FunctionDefinitionStringEqualIgnoreCase extends FunctionDefinitionEquality<String> {
+
+ /**
+ * ASSUMES that equalsIgnoreCase provides the same result as calling string-normalize-to-lower-case on both strings and then comparing.
+ */
+ @Override
+ protected boolean isEqual(String s1, String s2) {
+ return s1.equalsIgnoreCase(s2);
+ }
+
+ /**
+ * Creates a new <code>FunctionDefinitionStringEqualIgnoreCase</code> with the given <code>Identifier</code>.
+ *
+ * @param idIn the <code>Identifier</code> for the new <code>FunctionDefinitionStringEqualIgnoreCase</code>
+ */
+ public FunctionDefinitionStringEqualIgnoreCase(Identifier idIn) {
+ super(idIn, DataTypes.DT_STRING);
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.java
new file mode 100755
index 0000000..bc5515d
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.java
@@ -0,0 +1,256 @@
+/*
+ * 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.DataTypeException;
+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.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+/**
+ * FunctionDefinitionStringFunctions implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to
+ * implement the XACML String Functions predicates except for the conversions between <code>String</code> and <code>DataType</code>
+ * which are contained in <code>FunctionDefinitionStringConversion</code>.
+ * The functions in this file do not have a lot in common except that the return data type is known and the input argument types are
+ * either known or of the generic 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-concatenate
+ * string-starts-with
+ * anyURI-starts-with
+ * string-ends-with
+ * anyURI-ends-with
+ * string-contains
+ * anyURI-contains
+ * string-substring
+ * anyURI-substring
+ *
+ *
+ * @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 -
+ * needed because different functions within this class have different output types
+ */
+public class FunctionDefinitionStringFunctions<O, I> extends FunctionDefinitionBase<O, I> {
+
+ /**
+ * List of String operations.
+ *
+ * @author glenngriffin
+ *
+ */
+ public enum OPERATION {CONCATENATE, STARTS_WITH, ENDS_WITH, CONTAINS, SUBSTRING };
+
+ // operation to be used in this instance of the StringFunctions class
+ private final OPERATION operation;
+
+
+ /**
+ * Constructor - need dataTypeArgs input because of java Generic type-erasure during compilation.
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ */
+ public FunctionDefinitionStringFunctions(Identifier idIn, DataType<O> dataTypeIn, DataType<I> dataTypeArgsIn, OPERATION op) {
+ super(idIn, dataTypeIn, dataTypeArgsIn, false);
+ this.operation = op;
+ }
+
+
+ @SuppressWarnings("incomplete-switch")
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+
+ if (arguments == null ||
+ (operation == OPERATION.CONCATENATE && arguments.size() < 2) ||
+ (operation == OPERATION.SUBSTRING && arguments.size() != 3) ||
+ (operation != OPERATION.SUBSTRING && operation != OPERATION.CONCATENATE && arguments.size() != 2) ) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected " +
+ ((operation == OPERATION.SUBSTRING) ? 3 : (operation == OPERATION.CONCATENATE ? "2 or more " : 2)) + " arguments, got " +
+ ((arguments == null) ? "null" : arguments.size()) ));
+ }
+
+
+
+ ExpressionResult expressionResult = null;
+
+ String firstArgumentAsString = null;
+ String secondArgumentAsString = null;
+
+ Integer secondArgumentAsInteger = null;
+ Integer thirdArgumentAsInteger = null;
+
+ // most of the functions take 2 args, but SUBSTRING takes 3 AND concatenate takes 2 or more
+ if (operation == OPERATION.CONCATENATE) {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < arguments.size(); i++) {
+ FunctionArgument functionArgument = arguments.get(i);
+ ConvertedArgument<I> convertedArgument = new ConvertedArgument<I>(functionArgument, this.getDataTypeArgs(), false);
+ if ( ! convertedArgument.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedArgument.getStatus()));
+ }
+ try {
+ String argumentAsString = this.getDataTypeArgs().toStringValue( convertedArgument.getValue());
+ builder.append(argumentAsString);
+ } 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 ));
+ }
+ }
+ AttributeValue<String> stringResult = new StdAttributeValue<String>(XACML.ID_DATATYPE_STRING,
+ builder.toString() );
+ expressionResult = ExpressionResult.newSingle(stringResult);
+ return expressionResult;
+
+ } else if (operation == OPERATION.SUBSTRING) {
+ // first arg is of generic type
+ FunctionArgument functionArgument = arguments.get(0);
+ ConvertedArgument<I> convertedArgument0 = new ConvertedArgument<I>(functionArgument, this.getDataTypeArgs(), false);
+ if ( ! convertedArgument0.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedArgument0.getStatus()));
+ }
+ try {
+ firstArgumentAsString = this.getDataTypeArgs().toStringValue( convertedArgument0.getValue());
+ } 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 ));
+ }
+
+ functionArgument = arguments.get(1);
+ ConvertedArgument<BigInteger> convertedArgumentInt = new ConvertedArgument<BigInteger>(functionArgument, DataTypes.DT_INTEGER, false);
+ if ( ! convertedArgumentInt.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedArgumentInt.getStatus()));
+ }
+ secondArgumentAsInteger = convertedArgumentInt.getValue().intValue();
+ if (secondArgumentAsInteger < 0 || secondArgumentAsInteger > firstArgumentAsString.length()) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " +
+ "Start point '" + secondArgumentAsInteger + "' out of range 0-" + firstArgumentAsString.length() +
+ " for string='" + firstArgumentAsString + "'"));
+ }
+
+
+ functionArgument = arguments.get(2);
+ convertedArgumentInt = new ConvertedArgument<BigInteger>(functionArgument, DataTypes.DT_INTEGER, false);
+ if ( ! convertedArgumentInt.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedArgumentInt.getStatus()));
+ }
+ thirdArgumentAsInteger = convertedArgumentInt.getValue().intValue();
+ // special case: -1 means "to end of string"
+ if (thirdArgumentAsInteger < -1 || thirdArgumentAsInteger > firstArgumentAsString.length()) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " +
+ "End point '" + thirdArgumentAsInteger + "' out of range 0-" + firstArgumentAsString.length() +
+ " for string='" + firstArgumentAsString + "'"));
+ }
+ if (thirdArgumentAsInteger != -1 && thirdArgumentAsInteger < secondArgumentAsInteger) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " " +
+ "End point '" + thirdArgumentAsInteger + "' less than start point '" + secondArgumentAsString + "'" +
+ " for string='" + firstArgumentAsString + "'"));
+ }
+
+ } else {
+ // expect 2 args, one String and one of Generic type
+ FunctionArgument functionArgument = arguments.get(0);
+ ConvertedArgument<String> convertedArgument0 = new ConvertedArgument<String>(functionArgument, DataTypes.DT_STRING, false);
+ if ( ! convertedArgument0.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedArgument0.getStatus()));
+ }
+ firstArgumentAsString = convertedArgument0.getValue();
+
+
+ functionArgument = arguments.get(1);
+ ConvertedArgument<I> convertedArgument1 = new ConvertedArgument<I>(functionArgument, this.getDataTypeArgs(), false);
+ if ( ! convertedArgument1.isOk()) {
+ return ExpressionResult.newError(getFunctionStatus(convertedArgument1.getStatus()));
+ }
+ try {
+ secondArgumentAsString = this.getDataTypeArgs().toStringValue( convertedArgument1.getValue());
+ } 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 +
+ " " + message ));
+ }
+
+
+ }
+
+ // arguments are ready - do the operation
+
+ switch (operation) {
+ case STARTS_WITH:
+ if (secondArgumentAsString.startsWith(firstArgumentAsString)) {
+ return ER_TRUE;
+ } else {
+ return ER_FALSE;
+ }
+
+
+ case ENDS_WITH:
+ if (secondArgumentAsString.endsWith(firstArgumentAsString)) {
+ return ER_TRUE;
+ } else {
+ return ER_FALSE;
+ }
+
+ case CONTAINS:
+ if (secondArgumentAsString.contains(firstArgumentAsString)) {
+ return ER_TRUE;
+ } else {
+ return ER_FALSE;
+ }
+
+ case SUBSTRING:
+ String substring = null;
+ if (thirdArgumentAsInteger == -1) {
+ // from start point to end of string
+ substring = firstArgumentAsString.substring(secondArgumentAsInteger);
+ } else {
+ substring = firstArgumentAsString.substring(secondArgumentAsInteger, thirdArgumentAsInteger);
+ }
+ AttributeValue<String> stringResult = new StdAttributeValue<String>(XACML.ID_DATATYPE_STRING, substring);
+ expressionResult = ExpressionResult.newSingle(stringResult);
+ break;
+ }
+
+
+ return expressionResult;
+
+ }
+
+
+
+
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.java
new file mode 100755
index 0000000..11d6359
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.java
@@ -0,0 +1,108 @@
+/*
+ * 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.AttributeValue;
+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.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypeString;
+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;
+
+/**
+ * FunctionDefinitionStringNormalize extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to
+ * implement the XACML String normalization predicates as functions taking one <code>String</code> arg and returning a single value of the same 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-normalize-space
+ * string-normalize-to-lower-case
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ */
+public class FunctionDefinitionStringNormalize extends FunctionDefinitionHomogeneousSimple<String, String> {
+
+ /**
+ * List of string normalization operations.
+ *
+ * @author glenngriffin
+ *
+ */
+ public enum OPERATION {SPACE, LOWER_CASE };
+
+ // operation to be used in this instance of the Arightmetic class
+ private final OPERATION operation;
+
+
+ // result variables used by all functions
+ AttributeValue<String> result;
+
+
+ /**
+ * Constructor
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ * @param op
+ */
+ public FunctionDefinitionStringNormalize(Identifier idIn, OPERATION op) {
+ // for Arithmetic functions, the output type is the same as the input type (no mixing of Ints and Doubles!)
+ super(idIn, DataTypes.DT_STRING, DataTypeString.newInstance(), 1);
+
+ // save the operation and data type to be used in this instance
+ operation = op;
+
+ }
+
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+ List<String> convertedArguments = new ArrayList<String>();
+ 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 perform the requested operation.
+ */
+ ExpressionResult expressionResult = null;
+
+ switch (operation) {
+ case SPACE:
+ result = new StdAttributeValue<String>(XACML.ID_DATATYPE_STRING, convertedArguments.get(0).trim() );
+ break;
+ case LOWER_CASE:
+ result = new StdAttributeValue<String>(XACML.ID_DATATYPE_STRING, convertedArguments.get(0).toLowerCase() );
+ break;
+ }
+
+ expressionResult = ExpressionResult.newSingle(result);
+
+ return expressionResult;
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.java
new file mode 100755
index 0000000..bf7ba8b
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.java
@@ -0,0 +1,96 @@
+/*
+ * 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.xacml.std.datatypes.ISO8601Time;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+/**
+ * FunctionDefinitionTimeInRange implements {@link com.att.research.xacmlatt.pdp.policy.FunctionDefinition} to
+ * implement the XACML time-in-range predicates as a function taking three arguments of type <code>Time</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:
+ * time-in-range
+ *
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ * @param <I> the java class for the data type of the function Input arguments.
+ */
+public class FunctionDefinitionTimeInRange<I> extends FunctionDefinitionHomogeneousSimple<Boolean, I> {
+
+
+
+
+ /**
+ * Constructor - need dataType input because of java Generic type-erasure during compilation.
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ */
+ public FunctionDefinitionTimeInRange(Identifier idIn, DataType<I> dataTypeArgsIn) {
+ super(idIn, DataTypes.DT_BOOLEAN, dataTypeArgsIn, 3);
+ }
+
+
+ @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 compareResultLow;
+ int compareResultHigh;
+ try {
+
+ compareResultLow = ((ISO8601Time) convertedArguments.get(1)).compareTo((ISO8601Time)convertedArguments.get(0));
+ compareResultHigh = ((ISO8601Time)convertedArguments.get(2)).compareTo((ISO8601Time)convertedArguments.get(0));
+ } 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));
+ }
+
+ // is arg 0 within the inclusive range of the other two?
+ if (compareResultLow <=0 && compareResultHigh >= 0) {
+ return ER_TRUE;
+ } else {
+ return ER_FALSE;
+ }
+ }
+
+
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.java
new file mode 100755
index 0000000..cf9a375
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.java
@@ -0,0 +1,114 @@
+/*
+ * 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.List;
+
+import com.att.research.xacml.api.DataTypeException;
+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.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;
+
+/**
+ * FunctionDefinitionURIStringConcatenate extends {@link FunctionDefinitionHomogeneousSimple} to
+ * implement the XACML uri-string-concatenate predicate as a function taking one <code>URI</code> and one or more <code>String</code> arguments
+ * and returning a single <code>URI</code> value.
+ *
+ * THIS FUNCTION IS DEPRECATED IN 3.0 BUT NOT REMOVED.
+ * To provide backward compatibility for previously built XACML policies we include it in our R3 version.
+ *
+ * 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:
+ * uri-string-concatenate
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ */
+@Deprecated
+public class FunctionDefinitionURIStringConcatenate extends FunctionDefinitionBase<URI, URI> {
+
+
+ /**
+ * Constructor
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ * @param op
+ */
+ public FunctionDefinitionURIStringConcatenate(Identifier idIn) {
+ super(idIn, DataTypes.DT_ANYURI, DataTypes.DT_ANYURI, 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 or more arguments, got " +
+ ((arguments == null) ? "null" : arguments.size()) ));
+ }
+
+ // get the string to search for
+ ConvertedArgument<URI> uriArgument = new ConvertedArgument<URI>(arguments.get(0), DataTypes.DT_ANYURI, false);
+ if ( ! uriArgument.isOk()) {
+ Status decoratedStatus = new StdStatus(uriArgument.getStatus().getStatusCode(), uriArgument.getStatus().getStatusMessage() + " at arg index 0" );
+ return ExpressionResult.newError(getFunctionStatus(decoratedStatus));
+ }
+ String uriString = uriArgument.getValue().toString();
+
+ // remaining arguments are strings
+ String[] stringValues = new String[arguments.size() - 1];
+
+ for (int i = 1; i < arguments.size(); i++) {
+
+ ConvertedArgument<String> stringArgument = new ConvertedArgument<String>(arguments.get(i), DataTypes.DT_STRING, false);
+ if ( ! stringArgument.isOk()) {
+ Status decoratedStatus = new StdStatus(stringArgument.getStatus().getStatusCode(), stringArgument.getStatus().getStatusMessage() + " at arg index " + i );
+ return ExpressionResult.newError(getFunctionStatus(decoratedStatus));
+ }
+
+ stringValues[i-1] = stringArgument.getValue();
+
+ }
+
+
+ // add each of the strings onto the URI
+ for (int i = 0; i < stringValues.length; i++) {
+ uriString += stringValues[i];
+ }
+
+ URI resultURI = null;
+ try {
+ resultURI = DataTypes.DT_ANYURI.convert(uriString);
+ } catch (DataTypeException e) {
+ String message = e.getMessage();
+ if (e.getCause() != null) {
+ message = e.getCause().getMessage();
+ }
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, getShortFunctionId() +
+ " Final string '" + uriString + "' not URI, " + message));
+ }
+
+ return ExpressionResult.newSingle(new StdAttributeValue<URI>(XACML.ID_DATATYPE_ANYURI, resultURI));
+
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.java
new file mode 100755
index 0000000..7f5069c
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.java
@@ -0,0 +1,98 @@
+/*
+ * 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 javax.security.auth.x500.X500Principal;
+
+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;
+
+/**
+ * FunctionDefinitionX500NameMatch extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to
+ * implement the XACML X500Name match predicate as functions taking two <code>X500Name</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:
+ * x500Name-match
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ */
+public class FunctionDefinitionX500NameMatch extends FunctionDefinitionHomogeneousSimple<Boolean, X500Principal> {
+
+
+ /**
+ * Constructor
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ * @param op
+ */
+ public FunctionDefinitionX500NameMatch(Identifier idIn) {
+ super(idIn, DataTypes.DT_BOOLEAN, DataTypes.DT_X500NAME, 2);
+ }
+
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+ List<X500Principal> convertedArguments = new ArrayList<X500Principal>();
+ 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 perform the match.
+ */
+
+ /*
+ * The spec writer's comments at:
+ * https://lists.oasis-open.org/archives/xacml/200906/msg00019.html
+ * say that the first sequence must exactly match the END of the second sequence.
+ */
+
+ String[] searchFor = convertedArguments.get(0).getName().split(",");
+ String[] searchIn = convertedArguments.get(1).getName().split(",");
+
+ // if first is bigger than 2nd there is no way we can match
+ if (searchFor.length > searchIn.length) {
+ return ER_FALSE;
+ }
+
+ // start from back-end of both lists - everything should match up to the length of the input
+ for (int i = 0; i < searchFor.length; i++) {
+ String searchForTerm = searchFor[searchFor.length - i - 1];
+ String searchInTerm = searchIn[searchIn.length - i - 1];
+ if (searchForTerm == null || searchInTerm == null ||
+ ! searchForTerm.trim().equals(searchInTerm.trim())) {
+ return ER_FALSE;
+ }
+ }
+
+
+ return ER_TRUE;
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.java
new file mode 100755
index 0000000..22ed22c
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.java
@@ -0,0 +1,249 @@
+/*
+ * 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.Iterator;
+import java.util.List;
+
+import javax.xml.xpath.XPathExpression;
+
+import org.w3c.dom.NodeList;
+
+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.RequestAttributes;
+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.xacml.std.datatypes.DataTypes;
+import com.att.research.xacml.std.datatypes.XPathExpressionWrapper;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+
+
+/**
+ * FunctionDefinitionXPath extends {@link com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHomogeneousSimple} to
+ * implement the XACML XPath predicates as functions taking one or two <code>XPathExpression</code> arguments and returning
+ * either an <code>Integer</code> or a <code>Boolean</code>.
+ *
+ * XACML version 1.0 and 2.0 used <code>String</code> data type as input.
+ * We do NOT support those functions because of ambiguity in the meaning of those Strings.
+ * The root of the XPath changed from the Request level in 2.0 to the Content level in 3.0.
+ * Also the 2.0 Requests contain only one Content, located in the resources category, while 3.0 allows Requests to contain Content in multiple categories.
+ *
+ * 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:
+ * xpath-node-count
+ * xpath-node-equals
+ * xpath-node-match
+ *
+ * @author glenngriffin
+ * @version $Revision: 1.1 $
+ *
+ * @param <O> the java class for the data type of the function Output
+
+ *
+ */
+public class FunctionDefinitionXPath<O> extends FunctionDefinitionHomogeneousSimple<O, XPathExpressionWrapper> {
+
+ /**
+ * List of string normalization operations.
+ *
+ * @author glenngriffin
+ *
+ */
+ public enum OPERATION {COUNT, EQUAL, MATCH };
+
+ // operation to be used in this instance of the Arightmetic class
+ private final OPERATION operation;
+
+
+ // result variables used by all functions
+ AttributeValue<String> result;
+
+
+ /**
+ * Constructor
+ *
+ * @param idIn
+ * @param dataTypeArgsIn
+ * @param op
+ */
+ public FunctionDefinitionXPath(Identifier idIn, DataType<O> dataTypeIn, OPERATION op) {
+ super(idIn, dataTypeIn, DataTypes.DT_XPATHEXPRESSION, ( (op == OPERATION.COUNT) ? 1 : 2 ) );
+ // save the operation and data type to be used in this instance
+ operation = op;
+
+ }
+
+ @Override
+ public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+
+ List<NodeList> nodeListList = new ArrayList<NodeList>();
+
+ List<XPathExpressionWrapper> convertedArguments = new ArrayList<XPathExpressionWrapper>();
+ 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));
+ }
+
+ // check the evaluationContext and Request for null
+ if (evaluationContext == null) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Got null EvaluationContext"));
+ }
+ if (evaluationContext.getRequest() == null) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " Got null Request in EvaluationContext"));
+ }
+
+
+ // each argument is an XPath that needs to be evaluated against the Content part of some Category (specified in the argument)
+ for (int i = 0; i < arguments.size(); i++) {
+ FunctionArgument functionArgument = arguments.get(i);
+ if (functionArgument.isBag()) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got bag at index " + i));
+ }
+ AttributeValue<?> attributeValueFunctionArgument = functionArgument.getValue();
+ if (attributeValueFunctionArgument == null) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got null value at index " + i));
+ }
+ Identifier xpathCategory = attributeValueFunctionArgument.getXPathCategory();
+ if (xpathCategory == null) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() +
+ " Got null Category at index " + i));
+ }
+
+ Iterator<RequestAttributes> it = evaluationContext.getRequest().getRequestAttributes(xpathCategory);
+ if (it == null) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() +
+ " Got null Iterator at index " + i));
+ }
+
+ NodeList nodeList = null;
+
+ while (it.hasNext()) {
+ if (nodeList != null) {
+ // the request has more than one Content entry for the same Category - error
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() +
+ " More than one Content section for id '" + xpathCategory + "'" ));
+ }
+ RequestAttributes requestAttributes = it.next();
+
+ // if there is no Content section then we return either 0 or FALSE
+ if (requestAttributes.getContentRoot() == null) {
+ if (operation == OPERATION.COUNT){
+ return ExpressionResult.newSingle(new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER, new BigInteger("0") ));
+ } else {
+ return ER_FALSE;
+ }
+ }
+
+ try {
+ XPathExpression xPathExpression = convertedArguments.get(i).getXpathExpressionWrapped();
+ nodeList = requestAttributes.getContentNodeListByXpathExpression(xPathExpression);
+ } catch (Exception e) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, this.getShortFunctionId() +
+ " XPath produces null result at '" + convertedArguments.get(i).getPath() + "' at index " + i ));
+ }
+
+
+ }
+
+ if (nodeList == null) {
+ return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() +
+ " XPathExpression returned null at index " + i));
+ }
+
+ // add this nodeList to the list of lists
+ nodeListList.add(nodeList);
+ }
+
+
+ /*
+ * Now perform the requested operation.
+ */
+ ExpressionResult expressionResult = null;
+
+ switch (operation) {
+ case COUNT:
+ Integer listLength = new Integer(nodeListList.get(0).getLength());
+ expressionResult = ExpressionResult.newSingle(new StdAttributeValue<BigInteger>(XACML.ID_DATATYPE_INTEGER,
+ new BigInteger(listLength.toString()) ));
+ return expressionResult;
+
+
+ case EQUAL:
+ // true if any node in first list equals any node in second set.
+ // The spec says: "Two nodes are considered equal if they have the same identity."
+ // we use the isSameNode method in Node to determine that.
+ for (int index0 = 0; index0 < nodeListList.get(0).getLength(); index0++) {
+ for (int index1 = 0; index1 < nodeListList.get(1).getLength(); index1++) {
+ if (nodeListList.get(0).item(index0).isSameNode(nodeListList.get(1).item(index1))) {
+ return ER_TRUE;
+ }
+ }
+ }
+ // none from the first list found in the second
+ return ER_FALSE;
+
+
+ case MATCH:
+ // this is looking to see if any of the nodes in the second set are children of (or equal to) the nodes in the first set
+ // Call recursive check for that.
+ expressionResult = nodeListMatch(nodeListList.get(0), nodeListList.get(1));
+ return expressionResult;
+ }
+
+ expressionResult = ExpressionResult.newSingle(result);
+
+ return expressionResult;
+ }
+
+ /**
+ * Recursive method checking to see if anything in list 2 equals anything in list 1 OR list 1's child nodes
+ * @param list1
+ * @param list2
+ * @return
+ */
+ private ExpressionResult nodeListMatch(NodeList list1, NodeList list2) {
+ // look for match with current contents of list 1
+ for (int index1 = 0; index1 < list1.getLength(); index1++) {
+ for (int index2 = 0; index2 < list2.getLength(); index2++) {
+ if (list1.item(index1).isSameNode(list2.item(index2))) {
+ return ER_TRUE;
+ }
+ }
+ }
+ // look for match with children of list 1
+ for (int index1 = 0; index1 < list1.getLength(); index1++) {
+ if (nodeListMatch(list1.item(index1).getChildNodes(), list2) == ER_TRUE) {
+ return ER_TRUE;
+ }
+ // this one had no children that matched, so check the next element in list1
+ }
+
+ // no match anywhere
+ return ER_FALSE;
+ }
+
+}
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/package-info.java
new file mode 100755
index 0000000..2122dd9
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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;
+
+/**
+ * com.att.research.xacmlatt.pdp.policy.expressions contains class definitions that represent specific XACML function
+ * implementations for target and condition evaluation and variable definitions.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/package-info.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/package-info.java
new file mode 100755
index 0000000..fe69353
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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;
+
+/**
+ * com.att.research.xacmlatt.pdp.std contains classes that provide reference implementations of various extensible components
+ * in the PDP implementation.
+ *
+ * @author car
+ * @version $Revision: 1.1 $
+ */
diff --git a/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.java b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.java
new file mode 100755
index 0000000..2b932ba
--- /dev/null
+++ b/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.java
@@ -0,0 +1,29 @@
+/*
+ * 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.util;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.util.XACMLProperties;
+
+public class ATTPDPProperties extends XACMLProperties {
+ public static final String PROP_EVALUATIONCONTEXTFACTORY = "xacml.att.evaluationContextFactory";
+ public static final String PROP_COMBININGALGORITHMFACTORY = "xacml.att.combiningAlgorithmFactory";
+ public static final String PROP_FUNCTIONDEFINITIONFACTORY = "xacml.att.functionDefinitionFactory";
+ public static final String PROP_POLICYFINDERFACTORY = "xacml.att.policyFinderFactory";
+ public static final String PROP_POLICYFINDERFACTORY_COMBINEROOTPOLICIES = "xacml.att.policyFinderFactory.combineRootPolicies";
+
+ public static final Identifier ID_POLICY_COMBINEDPERMITOVERRIDES = new IdentifierImpl("urn:com:att:xacml:3.0:policy-combining-algorithm:combined-permit-overrides");
+
+ protected ATTPDPProperties() {
+ }
+
+}
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine$1.class
new file mode 100644
index 0000000..61fbdd6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine.class
new file mode 100644
index 0000000..56e339d
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngine.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.class
new file mode 100644
index 0000000..647988e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Evaluatable.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Evaluatable.class
new file mode 100644
index 0000000..435ab9c
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Evaluatable.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContext.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContext.class
new file mode 100644
index 0000000..25802a3
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContext.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.class
new file mode 100644
index 0000000..ab03f3e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.class
new file mode 100644
index 0000000..8e508d2
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationException.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationException.class
new file mode 100644
index 0000000..2f424aa
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationException.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationResult.class
new file mode 100644
index 0000000..c73f36d
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/EvaluationResult.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult$MatchCode.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult$MatchCode.class
new file mode 100644
index 0000000..8306ba6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult$MatchCode.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult.class
new file mode 100644
index 0000000..9ec087c
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/MatchResult.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Matchable.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Matchable.class
new file mode 100644
index 0000000..d24eb17
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/eval/Matchable.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AdviceExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AdviceExpression.class
new file mode 100644
index 0000000..ccb1e74
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AdviceExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf$1.class
new file mode 100644
index 0000000..cdf3dc3
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf.class
new file mode 100644
index 0000000..58d2ced
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AllOf.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf$1.class
new file mode 100644
index 0000000..101274e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf.class
new file mode 100644
index 0000000..4942daf
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AnyOf.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.class
new file mode 100644
index 0000000..ef8fe7e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.class
new file mode 100644
index 0000000..3fb1237
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Bag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Bag.class
new file mode 100644
index 0000000..2bc997b
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Bag.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombinerParameter.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombinerParameter.class
new file mode 100644
index 0000000..ee80fd2
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombinerParameter.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.class
new file mode 100644
index 0000000..5157663
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.class
new file mode 100644
index 0000000..ad60823
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningElement.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningElement.class
new file mode 100644
index 0000000..225cf1d
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/CombiningElement.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Condition.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Condition.class
new file mode 100644
index 0000000..2a74ea6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Condition.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Expression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Expression.class
new file mode 100644
index 0000000..0e0aea0
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Expression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultBag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultBag.class
new file mode 100644
index 0000000..051dbef
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultBag.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultEmptyBag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultEmptyBag.class
new file mode 100644
index 0000000..30c0841
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultEmptyBag.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultError.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultError.class
new file mode 100644
index 0000000..9c507c0
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultError.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultSingle.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultSingle.class
new file mode 100644
index 0000000..dddaa10
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultSingle.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult.class
new file mode 100644
index 0000000..1c431ba
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResult.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.class
new file mode 100644
index 0000000..c337941
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgument.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgument.class
new file mode 100644
index 0000000..d5cb5ed
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgument.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.class
new file mode 100644
index 0000000..12ef034
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.class
new file mode 100644
index 0000000..1abf718
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.class
new file mode 100644
index 0000000..8ba8dd4
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.class
new file mode 100644
index 0000000..6367b3f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.class
new file mode 100644
index 0000000..5c2d6f3
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match$1.class
new file mode 100644
index 0000000..3bd5b5e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match.class
new file mode 100644
index 0000000..1a7355c
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Match.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ObligationExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ObligationExpression.class
new file mode 100644
index 0000000..285943b
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/ObligationExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy$1.class
new file mode 100644
index 0000000..d45b7cb
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy.class
new file mode 100644
index 0000000..1ff09f5
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Policy.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyComponent.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyComponent.class
new file mode 100644
index 0000000..2a245a5
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyComponent.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDef.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDef.class
new file mode 100644
index 0000000..121d0a8
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDef.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.class
new file mode 100644
index 0000000..9bc54d9
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinder.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinder.class
new file mode 100644
index 0000000..5fdb442
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinder.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.class
new file mode 100644
index 0000000..90a1f82
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.class
new file mode 100644
index 0000000..2e17129
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.class
new file mode 100644
index 0000000..98f42a1
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.class
new file mode 100644
index 0000000..3883a6e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.class
new file mode 100644
index 0000000..f631054
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet$1.class
new file mode 100644
index 0000000..7cda7d4
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet.class
new file mode 100644
index 0000000..af76185
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySet.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetChild.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetChild.class
new file mode 100644
index 0000000..643f5eb
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetChild.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.class
new file mode 100644
index 0000000..d834fa5
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule$1.class
new file mode 100644
index 0000000..171ecbe
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule.class
new file mode 100644
index 0000000..1dc60b6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Rule.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/RuleEffect.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/RuleEffect.class
new file mode 100644
index 0000000..911cbcb
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/RuleEffect.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Target.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Target.class
new file mode 100644
index 0000000..9ab657b
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/Target.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.class
new file mode 100644
index 0000000..5b2ca51
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.class
new file mode 100644
index 0000000..96c3cab
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableDefinition.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableDefinition.class
new file mode 100644
index 0000000..b955b0e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableDefinition.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableMap.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableMap.class
new file mode 100644
index 0000000..2516589
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/VariableMap.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.class
new file mode 100644
index 0000000..503201c
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.class
new file mode 100644
index 0000000..8be4cfc
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.class
new file mode 100644
index 0000000..3ac5422
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.class
new file mode 100644
index 0000000..14583a3
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.class
new file mode 100644
index 0000000..a0b2a05
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.class
new file mode 100644
index 0000000..7062e1f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.class
new file mode 100644
index 0000000..c2709e6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.class
new file mode 100644
index 0000000..e823a43
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.class
new file mode 100644
index 0000000..c3ce1c7
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.class
new file mode 100644
index 0000000..b006026
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.class
new file mode 100644
index 0000000..c4ef9c6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.class
new file mode 100644
index 0000000..d02bb03
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.class
new file mode 100644
index 0000000..585ad00
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.class
new file mode 100644
index 0000000..9abb139
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.class
new file mode 100644
index 0000000..8213a5b
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.class
new file mode 100644
index 0000000..5f2a5b2
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.class
new file mode 100644
index 0000000..251b708
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.class
new file mode 100644
index 0000000..5052858
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.class
new file mode 100644
index 0000000..c6d8849
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.class
new file mode 100644
index 0000000..170541f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.class
new file mode 100644
index 0000000..5975519
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.class
new file mode 100644
index 0000000..4307789
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.class
new file mode 100644
index 0000000..f2faac6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.class
new file mode 100644
index 0000000..c05e205
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.class
new file mode 100644
index 0000000..c60901c
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.class
new file mode 100644
index 0000000..94411a2
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Apply.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Apply.class
new file mode 100644
index 0000000..99f5f44
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Apply.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.class
new file mode 100644
index 0000000..9fcf24a
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.class
new file mode 100644
index 0000000..36bddc1
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.class
new file mode 100644
index 0000000..e4ea696
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.class
new file mode 100644
index 0000000..c0864ba
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Function.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Function.class
new file mode 100644
index 0000000..dd76634
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/Function.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.class
new file mode 100644
index 0000000..d62b7c1
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.class
new file mode 100644
index 0000000..cc23407
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.class
new file mode 100644
index 0000000..2ef4d9a
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.class
new file mode 100644
index 0000000..a6a4b4b
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.class
new file mode 100644
index 0000000..0a065dd
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.class
new file mode 100644
index 0000000..b704f03
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctions.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctions.class
new file mode 100644
index 0000000..2dcba35
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdFunctions.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$1.class
new file mode 100644
index 0000000..1671f08
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$StdPolicyFinderException.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$StdPolicyFinderException.class
new file mode 100644
index 0000000..ffed3c4
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder$StdPolicyFinderException.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.class
new file mode 100644
index 0000000..d409eba
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.class
new file mode 100644
index 0000000..ea56f8e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.class
new file mode 100644
index 0000000..6f57c16
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdProperties.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdProperties.class
new file mode 100644
index 0000000..8bef17e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/StdProperties.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides$1.class
new file mode 100644
index 0000000..019485f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.class
new file mode 100644
index 0000000..20bd937
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.class
new file mode 100644
index 0000000..42057bf
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides$1.class
new file mode 100644
index 0000000..f5a6ae2
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.class
new file mode 100644
index 0000000..71f33e6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit$1.class
new file mode 100644
index 0000000..b5a3d4c
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.class
new file mode 100644
index 0000000..d75367a
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.class
new file mode 100644
index 0000000..72554f8
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy$1.class
new file mode 100644
index 0000000..95e620a
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.class
new file mode 100644
index 0000000..44ad7fd
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule$1.class
new file mode 100644
index 0000000..d29d9a7
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.class
new file mode 100644
index 0000000..d965889
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy$1.class
new file mode 100644
index 0000000..f7bf40e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.class
new file mode 100644
index 0000000..7c13802
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule$1.class
new file mode 100644
index 0000000..62eeef6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.class
new file mode 100644
index 0000000..5135125
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable$1.class
new file mode 100644
index 0000000..9081b65
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.class
new file mode 100644
index 0000000..a1656af
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides$1.class
new file mode 100644
index 0000000..61d0da8
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.class
new file mode 100644
index 0000000..d1c518a
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny$1.class
new file mode 100644
index 0000000..b8f83e6
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.class
new file mode 100644
index 0000000..ae8115c
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.class
new file mode 100644
index 0000000..d28ce78
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.class
new file mode 100644
index 0000000..0a104a2
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$1.class
new file mode 100644
index 0000000..a0ac560
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$OPERATION.class
new file mode 100644
index 0000000..7fe2a1b
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.class
new file mode 100644
index 0000000..6cc59f0
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.class
new file mode 100644
index 0000000..7e69de0
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.class
new file mode 100644
index 0000000..da9dead
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.class
new file mode 100644
index 0000000..34f3a5e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.class
new file mode 100644
index 0000000..844df5e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.class
new file mode 100644
index 0000000..ff60811
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$1.class
new file mode 100644
index 0000000..652a98f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$OPERATION.class
new file mode 100644
index 0000000..5e9bf60
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.class
new file mode 100644
index 0000000..1045783
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$1.class
new file mode 100644
index 0000000..1056721
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$OPERATION.class
new file mode 100644
index 0000000..85d79ca
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.class
new file mode 100644
index 0000000..ccd974a
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.class
new file mode 100644
index 0000000..4e3726f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$1.class
new file mode 100644
index 0000000..315fb99
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$OPERATION.class
new file mode 100644
index 0000000..ae2716d
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.class
new file mode 100644
index 0000000..a2a0169
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.class
new file mode 100644
index 0000000..1bcaa07
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$1.class
new file mode 100644
index 0000000..ef8f697
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$OPERATION.class
new file mode 100644
index 0000000..7d04b7b
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.class
new file mode 100644
index 0000000..92e5e67
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.class
new file mode 100644
index 0000000..c204a33
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.class
new file mode 100644
index 0000000..612f3c3
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.class
new file mode 100644
index 0000000..7ddfc87
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$1.class
new file mode 100644
index 0000000..2e56349
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$OPERATION.class
new file mode 100644
index 0000000..ddc1cb0
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.class
new file mode 100644
index 0000000..2b522e8
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.class
new file mode 100644
index 0000000..93eae8f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.class
new file mode 100644
index 0000000..9cf81f1
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$1.class
new file mode 100644
index 0000000..b3d96fa
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$OPERATION.class
new file mode 100644
index 0000000..305cd59
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.class
new file mode 100644
index 0000000..714bf36
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$1.class
new file mode 100644
index 0000000..23e2571
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$OPERATION.class
new file mode 100644
index 0000000..592b19e
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.class
new file mode 100644
index 0000000..4a8b7b1
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.class
new file mode 100644
index 0000000..5f6a4e9
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.class
new file mode 100644
index 0000000..b80bd20
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.class
new file mode 100644
index 0000000..e0eb6cb
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$1.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$1.class
new file mode 100644
index 0000000..b539667
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$1.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$OPERATION.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$OPERATION.class
new file mode 100644
index 0000000..b8b971f
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$OPERATION.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.class
new file mode 100644
index 0000000..0f93467
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.class b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.class
new file mode 100644
index 0000000..3ef30e5
--- /dev/null
+++ b/openaz-xacml-pdp/target/classes/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.class
Binary files differ
diff --git a/openaz-xacml-pdp/target/maven-archiver/pom.properties b/openaz-xacml-pdp/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..7e994fb
--- /dev/null
+++ b/openaz-xacml-pdp/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Tue Apr 07 07:42:36 EDT 2015
+version=0.0.1-SNAPSHOT
+groupId=org.openliberty.openaz
+artifactId=openaz-xacml-pdp
diff --git a/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..d6cacb9
--- /dev/null
+++ b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,176 @@
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$OPERATION.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMRule.class
+com/att/research/xacmlatt/pdp/policy/FunctionDefinition.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.class
+com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny$1.class
+com/att/research/xacmlatt/pdp/policy/AdviceExpression.class
+com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.class
+com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.class
+com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.class
+com/att/research/xacmlatt/pdp/policy/CombiningElement.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$1.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$1.class
+com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.class
+com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.class
+com/att/research/xacmlatt/pdp/policy/Match.class
+com/att/research/xacmlatt/pdp/policy/RuleEffect.class
+com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.class
+com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule$1.class
+com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.class
+com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.class
+com/att/research/xacmlatt/pdp/policy/expressions/Apply.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$OPERATION.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.class
+com/att/research/xacmlatt/pdp/ATTPDPEngine.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize$1.class
+com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides$1.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule$1.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$1.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath$1.class
+com/att/research/xacmlatt/pdp/policy/AllOf.class
+com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$OPERATION.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.class
+com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.class
+com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.class
+com/att/research/xacmlatt/pdp/policy/FunctionArgument.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.class
+com/att/research/xacmlatt/pdp/eval/EvaluationResult.class
+com/att/research/xacmlatt/pdp/std/StdProperties.class
+com/att/research/xacmlatt/pdp/policy/Target.class
+com/att/research/xacmlatt/pdp/policy/Bag.class
+com/att/research/xacmlatt/pdp/policy/AnyOf.class
+com/att/research/xacmlatt/pdp/policy/PolicyIdReference.class
+com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultBag.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.class
+com/att/research/xacmlatt/pdp/eval/Evaluatable.class
+com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.class
+com/att/research/xacmlatt/pdp/policy/Expression.class
+com/att/research/xacmlatt/pdp/policy/ExpressionResult.class
+com/att/research/xacmlatt/pdp/eval/EvaluationException.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.class
+com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.class
+com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy$1.class
+com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.class
+com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.class
+com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.class
+com/att/research/xacmlatt/pdp/policy/PolicySetChild.class
+com/att/research/xacmlatt/pdp/std/StdPolicyFinder.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.class
+com/att/research/xacmlatt/pdp/eval/MatchResult.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$1.class
+com/att/research/xacmlatt/pdp/policy/Match$1.class
+com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultError.class
+com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.class
+com/att/research/xacmlatt/pdp/policy/PolicySet$1.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy$1.class
+com/att/research/xacmlatt/pdp/eval/MatchResult$MatchCode.class
+com/att/research/xacmlatt/pdp/policy/PolicySet.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$1.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison$OPERATION.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.class
+com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.class
+com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultSingle.class
+com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.class
+com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.class
+com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.class
+com/att/research/xacmlatt/pdp/policy/PolicyDef.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.class
+com/att/research/xacmlatt/pdp/policy/VariableDefinition.class
+com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.class
+com/att/research/xacmlatt/pdp/policy/Policy$1.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet$1.class
+com/att/research/xacmlatt/pdp/std/StdPolicyFinder$1.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.class
+com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.class
+com/att/research/xacmlatt/pdp/std/StdPolicyFinder$StdPolicyFinderException.class
+com/att/research/xacmlatt/pdp/eval/Matchable.class
+com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMApply.class
+com/att/research/xacmlatt/pdp/eval/EvaluationContext.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.class
+com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides$1.class
+com/att/research/xacmlatt/pdp/policy/PolicyFinder.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.class
+com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.class
+com/att/research/xacmlatt/pdp/std/StdFunctions.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.class
+com/att/research/xacmlatt/pdp/policy/PolicyComponent.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.class
+com/att/research/xacmlatt/pdp/policy/Condition.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic$OPERATION.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.class
+com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.class
+com/att/research/xacmlatt/pdp/policy/PolicyIssuer.class
+com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.class
+com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit$1.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.class
+com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable$1.class
+com/att/research/xacmlatt/pdp/policy/AnyOf$1.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.class
+com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$1.class
+com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic$OPERATION.class
+com/att/research/xacmlatt/pdp/policy/expressions/Function.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.class
+com/att/research/xacmlatt/pdp/policy/CombinerParameter.class
+com/att/research/xacmlatt/pdp/policy/VariableMap.class
+com/att/research/xacmlatt/pdp/policy/Rule$1.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag$OPERATION.class
+com/att/research/xacmlatt/pdp/policy/Rule.class
+com/att/research/xacmlatt/pdp/policy/Policy.class
+com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides$1.class
+com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.class
+com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.class
+com/att/research/xacmlatt/pdp/policy/PolicyDefaults.class
+com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.class
+com/att/research/xacmlatt/pdp/policy/ExpressionResult$ExpressionResultEmptyBag.class
+com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.class
+com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.class
+com/att/research/xacmlatt/pdp/std/StdEvaluationContext.class
+com/att/research/xacmlatt/pdp/ATTPDPEngine$1.class
+com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.class
+com/att/research/xacmlatt/pdp/policy/ObligationExpression.class
+com/att/research/xacmlatt/pdp/policy/AllOf$1.class
+com/att/research/xacmlatt/pdp/util/ATTPDPProperties.class
+com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.class
+com/att/research/xacmlatt/pdp/eval/EvaluationContextException.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions$OPERATION.class
+com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical$OPERATION.class
+com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.class
diff --git a/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..b9e94a4
--- /dev/null
+++ b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,142 @@
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySet.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPath.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAllOf.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnly.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermitted.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesRule.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEquality.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicy.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIssuer.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBag.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContextFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Function.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/RuleEffect.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesPolicy.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Match.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMVariableDefinition.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReferenceBase.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombiningAlgorithmBase.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Bag.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentBag.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameterMap.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Matchable.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombinerParameter.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinition.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparison.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeDesignator.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetIdReference.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSet.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ObligationExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContext.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRuleCombinerParameters.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAnyOf.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResultBoolean.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithms.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeSelector.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalize.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Expression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/TargetedCombinerParameter.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/util/ATTPDPProperties.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdProperties.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDef.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngineFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitOverrides.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMMatch.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMTarget.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBag.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsIn.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMRule.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithmFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdCombiningAlgorithmFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/Apply.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/CombinedPermitOverrides.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Policy.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentAttributeValue.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeDesignator.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctions.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySet.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgument.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMApply.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctions.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyCombinerParameter.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeSelector.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/ExpressionResult.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/MatchResult.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningAlgorithm.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversion.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinder.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyUnlessPermit.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAdviceExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMAttributeAssignmentExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicySetCombinerParameter.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationContextException.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyRepair.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyFinderResult.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionTimeInRange.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBase.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeRetrievalBase.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMCombinerParameter.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDef.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMDocumentRepair.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinder.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationException.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/FirstApplicable.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AnyOf.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimple.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AllOf.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableMap.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyDenyOverridesPolicy.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCase.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetIdReference.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMObligationExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdEvaluationContext.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Condition.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AttributeAssignmentResult.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/PermitUnlessDeny.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/VariableDefinition.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdFunctionDefinitionFactory.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/OnlyOneApplicable.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/LegacyPermitOverridesRule.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/VariableReference.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyIdReference.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyDefaults.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicySetChild.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/expressions/AttributeValueExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIssuer.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/ATTPDPEngine.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionX500NameMatch.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversion.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Target.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmetic.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/PolicyComponent.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/Evaluatable.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRFC822NameMatch.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/ConvertedArgument.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/CombiningElement.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyIdReference.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionArgumentExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/combiners/DenyOverrides.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSize.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenate.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/eval/EvaluationResult.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogical.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/StdPolicyFinderResult.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/AdviceExpression.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatch.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/package-info.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/dom/DOMPolicyDefaults.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/Rule.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmetic.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp/src/main/java/com/att/research/xacmlatt/pdp/policy/FunctionDefinitionFactory.java
diff --git a/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/openaz-xacml-pdp/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
diff --git a/openaz-xacml-pdp/target/openaz-xacml-pdp-0.0.1-SNAPSHOT.jar b/openaz-xacml-pdp/target/openaz-xacml-pdp-0.0.1-SNAPSHOT.jar
new file mode 100644
index 0000000..ff65667
--- /dev/null
+++ b/openaz-xacml-pdp/target/openaz-xacml-pdp-0.0.1-SNAPSHOT.jar
Binary files differ
diff --git a/openaz-xacml-pdp/xacml.properties b/openaz-xacml-pdp/xacml.properties
new file mode 100755
index 0000000..8394be9
--- /dev/null
+++ b/openaz-xacml-pdp/xacml.properties
@@ -0,0 +1,26 @@
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+
+# If there is a standard set of PIPEngines:
+# xacml.pip.engines=engine1,engine2,...,engineN
+# engine1.classname=com.att.research.xacmlpip.OraclePIP
+# engine1.prop1=foo
+# engine1.prop2=bar
+# ...
+# engine2.classname=com.att.research.xacmlpip.ActiveDirectoryPIP
+# ...
+
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+# If there is a standard policy for the engine:
+# xacml.att.stdPolicyFinderFactory.rootPolicyFile=/etc/stdpolicyset.xml
diff --git a/openaz-xacml-rest/pom.xml b/openaz-xacml-rest/pom.xml
new file mode 100755
index 0000000..cf8b334
--- /dev/null
+++ b/openaz-xacml-rest/pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>openaz</artifactId>
+ <groupId>org.openliberty.openaz</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>openaz-xacml-rest</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openliberty.openaz</groupId>
+ <artifactId>openaz-xacml</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRest.java b/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRest.java
new file mode 100755
index 0000000..83a8c7b
--- /dev/null
+++ b/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRest.java
@@ -0,0 +1,201 @@
+/*
+ * 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.xacml.rest;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.util.XACMLProperties;
+
+/**
+ * This static class is used by both the PDP and PAP servlet's. It contains some common
+ * static functions and objects used by both the servlet's.
+ *
+ * @author pameladragosh
+ *
+ */
+public class XACMLRest {
+ private static final Log logger = LogFactory.getLog(XACMLRest.class);
+ private static Properties restProperties = new Properties();
+
+ /**
+ * This must be called during servlet initialization. It sets up the xacml.?.properties
+ * file as a system property. If the System property is already set, then it does not
+ * do anything. This allows the developer to specify their own xacml.properties file to be
+ * used. They can 1) modify the default properties that comes with the project, or 2) change
+ * the WebInitParam annotation, or 3) specify an alternative path in the web.xml, or 4) set
+ * the Java System property to point to their xacml.properties file.
+ *
+ * The recommended way of overriding the default xacml.properties file is using a Java System
+ * property:
+ *
+ * -Dxacml.properties=/opt/app/xacml/etc/xacml.admin.properties
+ *
+ * This way one does not change any actual code or files in the project and can leave the
+ * defaults alone.
+ *
+ * @param config - The servlet config file passed from the javax servlet init() function
+ */
+ public static void xacmlInit(ServletConfig config) {
+ //
+ // Get the XACML Properties File parameter first
+ //
+ String propFile = config.getInitParameter("XACML_PROPERTIES_NAME");
+ if (propFile != null) {
+ //
+ // Look for system override
+ //
+ String xacmlPropertiesName = System.getProperty(XACMLProperties.XACML_PROPERTIES_NAME);
+ if (xacmlPropertiesName == null) {
+ //
+ // Set it to our servlet default
+ //
+ if (logger.isDebugEnabled()) {
+ logger.debug("Using Servlet Config Property for XACML_PROPERTIES_NAME:" + propFile);
+ }
+ System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, propFile);
+ } else {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Using System Property for XACML_PROPERTIES_NAME:" + xacmlPropertiesName);
+ }
+ }
+ }
+ //
+ // Setup the remaining properties
+ //
+ Enumeration<String> params = config.getInitParameterNames();
+ while (params.hasMoreElements()) {
+ String param = params.nextElement();
+ if (! param.equals("XACML_PROPERTIES_NAME")) {
+ String value = config.getInitParameter(param);
+ logger.info(param + "=" + config.getInitParameter(param));
+ restProperties.setProperty(param, value);
+ }
+ }
+ }
+
+ /**
+ * Reset's the XACMLProperties internal properties object so we start
+ * in a fresh environment. Then adds back in our Servlet init properties that were
+ * passed in the javax Servlet init() call.
+ *
+ * This function is primarily used when a new configuration is passed in and the
+ * PDP servlet needs to load a new PDP engine instance.
+ *
+ * @param pipProperties - PIP configuration properties
+ * @param policyProperties - Policy configuration properties
+ */
+ public static void loadXacmlProperties(Properties policyProperties, Properties pipProperties) {
+ try {
+ //
+ // Start fresh
+ //
+ XACMLProperties.reloadProperties();
+ //
+ // Now load our init properties
+ //
+ XACMLProperties.getProperties().putAll(XACMLRest.restProperties);
+ //
+ // Load our policy properties
+ //
+ if (policyProperties != null) {
+ XACMLProperties.getProperties().putAll(policyProperties);
+ }
+ //
+ // Load our pip config properties
+ //
+ if (pipProperties != null) {
+ XACMLProperties.getProperties().putAll(pipProperties);
+ }
+ } catch (IOException e) {
+ logger.error("Failed to put init properties into Xacml properties", e);
+ }
+ //
+ // Dump them
+ //
+ if (logger.isDebugEnabled()) {
+ try {
+ logger.debug(XACMLProperties.getProperties().toString());
+ } catch (IOException e) {
+ logger.error("Cannot dump properties", e);
+ }
+ }
+ }
+
+ /**
+ * Helper routine to dump the HTTP servlet request being serviced. Primarily for debugging.
+ *
+ * @param request - Servlet request (from a POST/GET/PUT/etc.)
+ */
+ public static void dumpRequest(HttpServletRequest request) {
+ if (logger.isDebugEnabled()) {
+ // special-case for receiving heartbeat - don't need to repeatedly output all of the information in multiple lines
+ if (request.getMethod().equals("GET") && "hb".equals(request.getParameter("type")) ) {
+ logger.debug("GET type=hb : heartbeat received");
+ return;
+ }
+ logger.debug(request.getMethod() + ":" + request.getRemoteAddr() + " " + request.getRemoteHost() + " " + request.getRemotePort());
+ logger.debug(request.getLocalAddr() + " " + request.getLocalName() + " " + request.getLocalPort());
+ Enumeration<String> en = request.getHeaderNames();
+ logger.debug("Headers:");
+ while (en.hasMoreElements()) {
+ String element = en.nextElement();
+ Enumeration<String> values = request.getHeaders(element);
+ while (values.hasMoreElements()) {
+ String value = values.nextElement();
+ logger.debug(element + ":" + value);
+ }
+ }
+ logger.debug("Attributes:");
+ en = request.getAttributeNames();
+ while (en.hasMoreElements()) {
+ String element = en.nextElement();
+ logger.debug(element + ":" + request.getAttribute(element));
+ }
+ logger.debug("ContextPath: " + request.getContextPath());
+ if (request.getMethod().equals("PUT") || request.getMethod().equals("POST")) {
+ // POST and PUT are allowed to have parameters in the content, but in our usage the parameters are always in the Query string.
+ // More importantly, there are cases where the POST and PUT content is NOT parameters (e.g. it might contain a Policy file).
+ // Unfortunately the request.getParameterMap method reads the content to see if there are any parameters,
+ // and once the content is read it cannot be read again.
+ // Thus for PUT and POST we must avoid reading the content here so that the main code can read it.
+ logger.debug("Query String:" + request.getQueryString());
+ try {
+ if (request.getInputStream() == null) {
+ logger.debug("Content: No content inputStream");
+ } else {
+ logger.debug("Content available: " + request.getInputStream().available());
+ }
+ } catch (Exception e) {
+ logger.debug("Content: inputStream exception: " + e.getMessage() + "; (May not be relevant)");
+ }
+ } else {
+ logger.debug("Parameters:");
+ Map<String, String[]> params = request.getParameterMap();
+ Set<String> keys = params.keySet();
+ for (String key : keys) {
+ String[] values = params.get(key);
+ logger.debug(key + "(" + values.length + "): " + (values.length > 0 ? values[0] : ""));
+ }
+ }
+ logger.debug("Request URL:" + request.getRequestURL());
+ }
+ }
+}
diff --git a/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRestProperties.java b/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRestProperties.java
new file mode 100755
index 0000000..d70f33e
--- /dev/null
+++ b/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRestProperties.java
@@ -0,0 +1,137 @@
+/*
+ * 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.xacml.rest;
+
+import com.att.research.xacml.util.XACMLProperties;
+
+/**
+ * These are XACML Properties that are relevant to the RESTful API interface for
+ * the PDP, PAP and AC interfaces.
+ *
+ *
+ * @author pameladragosh
+ *
+ */
+public class XACMLRestProperties extends XACMLProperties {
+ /**
+ * A unique identifier for the PDP servlet instance. Usually set to the URL
+ * it is running as in the J2EE container.
+ *
+ * Eg. http://localhost:8080/pdp/
+ */
+ public static final String PROP_PDP_ID = "xacml.rest.pdp.id";
+ /**
+ * A PDP servlet's configuration directory. Holds the pip and policy configuration
+ * data as well as the local policy cache.
+ *
+ * Eg: /opt/app/xacml/config
+ */
+ public static final String PROP_PDP_CONFIG = "xacml.rest.pdp.config";
+ /**
+ * Set this property to true or false if the PDP servlet should register itself upon
+ * startup with the PAP servlet.
+ */
+ public static final String PROP_PDP_REGISTER = "xacml.rest.pdp.register";
+ /**
+ * Number of seconds the PDP will sleep while retrying registration with the PAP.
+ * This value must be greater or equal to 5.
+ */
+ public static final String PROP_PDP_REGISTER_SLEEP = "xacml.rest.pdp.register.sleep";
+ /**
+ * Number of retry attempts at registration with the PAP. A value of -1 indicates infinite retries.
+ */
+ public static final String PROP_PDP_REGISTER_RETRIES = "xacml.rest.pdp.register.retries";
+ /**
+ * Max content length accepted for an incoming POST XML/JSON request. Default is 32767 bytes.
+ */
+ public static final String PROP_PDP_MAX_CONTENT = "xacml.rest.pdp.maxcontent";
+ /**
+ * Custom HTTP header used by PDP to send the value of the PROP_PDP_ID
+ */
+ public static final String PROP_PDP_HTTP_HEADER_ID = "X-XACML-PDP-ID";
+ /**
+ * Custom HHTP header used by PDP to send its heartbeat value.
+ */
+ public static final String PROP_PDP_HTTP_HEADER_HB = "X-XACML-PDP-HB";
+ /**
+ * The URL of the PAP servlet. Used by PDP servlet's to communicate. Because administrators
+ * can set whatever context they want to run the PAP servlet, it isn't easy to determine a return
+ * URL for the PAP servlet. This is especially true upon initialization.
+ */
+ public static final String PROP_PAP_URL = "xacml.rest.pap.url";
+ /**
+ * Upon startup, have the PAP servlet send latest configuration information to all
+ * the PDP nodes it knows about.
+ */
+ public static final String PROP_PAP_INITIATE_PDP_CONFIG = "xacml.rest.pap.initiate.pdp";
+ /**
+ * The interval the PAP servlet uses to send heartbeat requests to the PDP nodes.
+ */
+ public static final String PROP_PAP_HEARTBEAT_INTERVAL = "xacml.rest.pap.heartbeat.interval";
+ /**
+ * Timeout value used by the PAP servlet when trying to check the heartbeat of a PDP node.
+ */
+ public static final String PROP_PAP_HEARTBEAT_TIMEOUT = "xacml.rest.pap.heartbeat.timeout";
+ /*
+ * Local path to where the GIT repository exists.
+ *
+ * Eg. /opt/app/xacml/repository
+ */
+ public static final String PROP_ADMIN_REPOSITORY = "xacml.rest.admin.repository";
+ /*
+ * Local path to where user workspaces exist. The user workspace contains temporary files, the
+ * user's clone of the GIT repository, anything specific to the user, etc.
+ */
+ public static final String PROP_ADMIN_WORKSPACE = "xacml.rest.admin.workspace";
+ /*
+ * This is the domain you can setup for your organization, it should be a URI.
+ *
+ * Eg. com:sample:foo
+ */
+ public static final String PROP_ADMIN_DOMAIN = "xacml.rest.admin.domain";
+ /**
+ * PROP_ADMIN_USER_NAME is simply a name for the logged in user.
+ *
+ * AC authentication is out the scope of the web application itself. It is up to the
+ * developer to setup authentication as they please in the J2EE container used to run
+ * the web application. Whatever authentication mechanism they use, they should then set
+ * the attribute into the HttpSession object. The Admin Console will be able to read that
+ * value (default to "guest") in.
+ *
+ * ((HttpServletRequest) request).getSession().setAttribute("xacml.rest.admin.user.name", "Homer");
+ *
+ */
+ public static final String PROP_ADMIN_USER_NAME = "xacml.rest.admin.user.name";
+ /**
+ *
+ * PROP_ADMIN_USER_ID is an id for the logged in user.
+ *
+ * Eg. hs1234
+ *
+ * @see #PROP_ADMIN_USER_NAME for more information.
+ */
+ public static final String PROP_ADMIN_USER_ID = "xacml.rest.admin.user.id";
+ /**
+ *
+ * PROP_ADMIN_USER_EMAIL is a user's email address.
+ *
+ * @see #PROP_ADMIN_USER_NAME for more information.
+ */
+ public static final String PROP_ADMIN_USER_EMAIL = "xacml.rest.admin.user.email";
+ /**
+ * Directory path containing sub-directories where the Subscriber servlet puts files sent through data feeds.
+ */
+ public static final String PROP_SUBSCRIBER_INCOMING = "xacml.subscriber.incoming";
+ /**
+ * The specific data feed name for the Subscriber servlet to register for.
+ */
+ public static final String PROP_SUBSCRIBER_FEED = "xacml.subscriber.feed";
+}
diff --git a/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRest.class b/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRest.class
new file mode 100644
index 0000000..ef86656
--- /dev/null
+++ b/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRest.class
Binary files differ
diff --git a/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRestProperties.class b/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRestProperties.class
new file mode 100644
index 0000000..b6570eb
--- /dev/null
+++ b/openaz-xacml-rest/target/classes/com/att/research/xacml/rest/XACMLRestProperties.class
Binary files differ
diff --git a/openaz-xacml-rest/target/maven-archiver/pom.properties b/openaz-xacml-rest/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..75af03d
--- /dev/null
+++ b/openaz-xacml-rest/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Tue Apr 07 07:42:35 EDT 2015
+version=0.0.1-SNAPSHOT
+groupId=org.openliberty.openaz
+artifactId=openaz-xacml-rest
diff --git a/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..d842d7d
--- /dev/null
+++ b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,2 @@
+com/att/research/xacml/rest/XACMLRestProperties.class
+com/att/research/xacml/rest/XACMLRest.class
diff --git a/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..f772e13
--- /dev/null
+++ b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,2 @@
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRest.java
+/Users/ajith/IdeaProjects/openaz/openaz-xacml-rest/src/main/java/com/att/research/xacml/rest/XACMLRestProperties.java
diff --git a/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/openaz-xacml-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
diff --git a/openaz-xacml-rest/target/openaz-xacml-rest-0.0.1-SNAPSHOT.jar b/openaz-xacml-rest/target/openaz-xacml-rest-0.0.1-SNAPSHOT.jar
new file mode 100644
index 0000000..49eba1f
--- /dev/null
+++ b/openaz-xacml-rest/target/openaz-xacml-rest-0.0.1-SNAPSHOT.jar
Binary files differ
diff --git a/openaz-xacml-test/pom.xml b/openaz-xacml-test/pom.xml
new file mode 100755
index 0000000..c88e4c0
--- /dev/null
+++ b/openaz-xacml-test/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>openaz</artifactId>
+ <groupId>org.openliberty.openaz</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>openaz-xacml-test</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>openaz-xacml</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>openaz-xacml-rest</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>openaz-xacml-pdp</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>postgresql</groupId>
+ <artifactId>postgresql</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseConformanceTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseConformanceTest.java
new file mode 100755
index 0000000..de3851b
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseConformanceTest.java
@@ -0,0 +1,187 @@
+/*
+ * 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.dom;
+
+import static org.junit.Assert.fail;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.Response;
+import com.att.research.xacml.std.dom.DOMResponse;
+
+/**
+ * Tests for handling the XML version of the XACML Response object.
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * Normally the Response is generated by the PDP and returned through the RESTful interface as JSON.
+ * Testing of the XML interface is minimal and not complete.
+ *
+ *
+ *
+ * @author glenngriffin
+ *
+ */
+public class DOMResponseConformanceTest {
+
+ // where to find the conformance test XML files
+ private final String CONFORMANCE_DIRECTORY_PATH = "testsets/conformance/xacml3.0-ct-v.0.4";
+
+ // The request object output from each test conversion from JSON string
+ Response response;
+
+
+
+ // Load the Conformance test responses into Response objects, generate the output XML for that Response and compare with the original files.
+ @Test
+ public void testDOMResponse() {
+ List<File> filesInDirectory = null;
+
+ File conformanceDirectory = null;
+
+ File currentFile = null;
+
+ try {
+ conformanceDirectory = new File(CONFORMANCE_DIRECTORY_PATH);
+ filesInDirectory = getRequestsInDirectory(conformanceDirectory);
+ } catch (Exception e) {
+ fail("Unable to set up Conformance tests for dir '" + conformanceDirectory.getAbsolutePath()+"' e="+ e);
+ }
+
+ // run through each XML file
+ // - load the file from XML into an internal Response object
+ // - generate the XML representation from that Response object
+ // - reload the file into a String
+ // - compare the 2 XML strings
+ Response xmlResponse = null;
+ try {
+ for (File f : filesInDirectory) {
+ currentFile = f;
+
+//// This is a simple way to select just one file for debugging - comment out when not being used
+//if ( ! f.getName().equals("IID302Response.xml")) { continue; }
+
+// during debugging it is helpful to know what file it is starting to work on
+// System.out.println("starting file="+currentFile.getName());
+
+
+ BufferedReader br = new BufferedReader(new FileReader(f));
+ StringBuffer sb = new StringBuffer();
+ String line;
+ while ((line = br.readLine()) != null) {
+ sb.append(line + "\n");
+ }
+ br.close();
+
+ String xmlFromFile = sb.toString();
+
+ try {
+ // load XML into a Response object
+ xmlResponse = DOMResponse.load(xmlFromFile);
+ } catch (Exception e) {
+ // if XML does not load, just note it and continue with next file
+ System.out.println("XML file did not load: '" + f.getName() + " e=" + e);
+ continue;
+ }
+//System.out.println(xmlFromFile);
+
+ // create String version from the Response object
+ String xmlResponseString = DOMResponse.toString(xmlResponse, false);
+
+ // Comparing the string directly to the String from the file is difficult.
+ // We can minimize the problems with newlines and whitespace, but we have other issues with how various object values are represented.
+ // For instance, and input double of "23.50" is output as "23.5" which is the same value but not identical strings.
+ // Therefore we take the XML output and use it to create a new Response object, then compare the two objects.
+
+//System.out.println(xmlResponseString);
+ Response reGeneratedResponse = DOMResponse.load(xmlResponseString);
+
+ if ( ! xmlResponse.equals(reGeneratedResponse)) {
+ String normalizedFromFile = xmlFromFile.replaceAll("\\r|\\n", "");
+ normalizedFromFile = normalizedFromFile.replaceAll("\\s+", " ");
+ normalizedFromFile = normalizedFromFile.replaceAll(">\\s*<", "><");
+ System.out.println("File="+normalizedFromFile);
+ System.out.println("Gend="+ xmlResponseString);
+
+ System.out.println(DOMResponse.toString(xmlResponse, true));
+
+ fail("Output string did not re-generate eqivilent object.");
+ }
+
+// // Normally whitespace is significant in XML.
+// // However in this case we are generating an XML string for output and comparing it to a hand-made file.
+// // The file may contain extra newlines or fewer spaces then our prettyPrinted output version.
+// // Therefore we do the comparison on the un-prettyPrinted generated string.
+// // To do this we have to remove the extra whitespace from the version read from the file.
+// String normalizedFromFile = xmlFromFile.replaceAll("\\r|\\n", "");
+// normalizedFromFile = normalizedFromFile.replaceAll("\\s+", " ");
+// normalizedFromFile = normalizedFromFile.replaceAll(">\\s*<", "><");
+//
+// if ( ! xmlResponseString.equals(normalizedFromFile)) {
+// System.out.println("file="+normalizedFromFile+"\ngend="+xmlResponseString);
+// fail("file not same as generated string: " + f.getName()+ "\nFile="+xmlFromFile + "\nString="+xmlResponseString);
+// }
+
+
+ }
+
+ } catch (Exception e) {
+ fail ("Failed test with '" + currentFile.getName() + "', e=" + e);
+ }
+
+
+ }
+
+
+
+ //
+ // HELPER to get list of all Request files in the given directory
+ //
+
+ private List<File> getRequestsInDirectory(File directory) {
+ List<File> fileList = new ArrayList<File>();
+
+ File[] fileArray = directory.listFiles();
+ for (File f : fileArray) {
+ if (f.isDirectory()) {
+ List<File> subDirList = getRequestsInDirectory(f);
+ fileList.addAll(subDirList);
+ }
+ if (f.getName().endsWith("Response.xml")) {
+ fileList.add(f);
+ }
+ }
+ return fileList;
+
+ }
+
+
+}
+
+
+/*
+Place to edit long strings output during tests
+
+
+
+
+
+
+
+
+*/
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseTest.java
new file mode 100755
index 0000000..9596650
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/dom/DOMResponseTest.java
@@ -0,0 +1,2287 @@
+/*
+ * 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.dom;
+
+import com.att.research.xacml.api.*;
+import com.att.research.xacml.std.*;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacml.std.datatypes.StringNamespaceContext;
+import com.att.research.xacml.std.datatypes.XPathExpressionWrapper;
+import com.att.research.xacml.std.dom.DOMResponse;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import org.junit.Test;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Test DOM XML Responses
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * This class was copied from the JSON tests. At this time only the first two methods have been revised to work with XML.
+ * The second method includes multiple instances of all possible fields and has been manually verified.
+ * The remaining methods have not been converted because:
+ * - "conversion" consists of replacing the JSON strings with XML
+ * - the replacement would consist of copying the XML from the JUnit output and doing a String replace
+ * - there would be little examination of the (long) XML strings, so their validity would be questionable
+ * so the benefit for the cost of doing that work is not clear.
+ *
+ * @author glenngriffin
+ *
+ */
+public class DOMResponseTest {
+
+ String xmlResponse;
+
+ StdMutableResponse response;
+
+ StdMutableResult result;
+
+ StdMutableStatus status;
+
+
+ // Note: Initially test responses without Obligations, Associated Advice, Attributes, or PolicyIdentifier
+
+
+ @Test
+ public void testEmptyAndDecisions() {
+ // null response
+ try {
+ xmlResponse = DOMResponse.toString(null, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // empty response (no Result object)
+ response = new StdMutableResponse();
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+
+ // just decision, no status
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // just status (empty), no decision
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ result.setStatus(status);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // just status (non-empty), no decision
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_OK);
+ result.setStatus(status);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+
+ // test other decisions without Status
+
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.DENY);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Deny</Decision></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.NOTAPPLICABLE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>NotApplicable</Decision></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.INDETERMINATE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.INDETERMINATE_DENY);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.INDETERMINATE_DENYPERMIT);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.INDETERMINATE_PERMIT);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // test Multiple Decisions - success
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ response.add(result);
+ StdMutableResult result2 = new StdMutableResult();
+ result2.setDecision(Decision.DENY);
+ response.add(result2);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision></Result><Result><Decision>Deny</Decision></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // test Multiple Decisions - one success and one error
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ response.add(result);
+ result2 = new StdMutableResult();
+ result2.setDecision(Decision.INDETERMINATE);
+ response.add(result2);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision></Result><Result><Decision>Indeterminate</Decision></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ }
+
+
+
+
+ // Test with every field filled in with multiple values where appropriate
+ @Test
+ public void testAllFieldsResponse() {
+
+ // fully-loaded multiple response
+
+ StdMutableResponse response = new StdMutableResponse();
+ // create a Status object
+ StdMutableStatus status = new StdMutableStatus(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);
+ status.setStatusMessage("some status message");
+ StdMutableStatusDetail statusDetailIn = new StdMutableStatusDetail();
+ StdMutableMissingAttributeDetail mad = new StdMutableMissingAttributeDetail();
+ mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "doh"));
+ mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_INTEGER.getId(), "5432"));
+ mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh"));
+ mad.setAttributeId(XACML3.ID_ACTION_PURPOSE);
+ mad.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_ACTION);
+ mad.setDataTypeId(XACML3.ID_DATATYPE_STRING);
+ mad.setIssuer("an Issuer");
+ statusDetailIn.addMissingAttributeDetail(mad);
+ status.setStatusDetail(statusDetailIn);
+ // create a single result object
+ StdMutableResult result = new StdMutableResult(status);
+ // set the decision
+ result.setDecision(Decision.INDETERMINATE);
+ // put the Result into the Response
+ response.add(result);
+
+
+ // create a new Result with a different Decision
+ status = new StdMutableStatus(StdStatusCode.STATUS_CODE_OK);
+ result = new StdMutableResult(status);
+ result.setDecision(Decision.DENY);
+
+ StdMutableObligation obligation = new StdMutableObligation();
+ obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "obligation-issuer1",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "obligation-issuer2",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Ned")));
+ result.addObligation(obligation);
+ obligation = new StdMutableObligation();
+ obligation.setId(XACML3.ID_SUBJECT_CATEGORY_INTERMEDIARY_SUBJECT);
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "obligation-issuer3",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Maggie")));
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "obligation-issuer4",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Homer")));
+ result.addObligation(obligation);
+
+
+ StdMutableAdvice advice = new StdMutableAdvice();
+ advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "advice-issuer1",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu")));
+ advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ null,
+ XACML3.ID_SUBJECT,
+ "advice-issuerNoCategory",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Crusty")));
+ result.addAdvice(advice);
+
+
+ response.add(result);
+
+
+ // create a new Result with a different Decision
+ // add Child/minor status codes within the main status
+ StdStatusCode childChildChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildChildStatusCode"));
+ StdStatusCode childChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildStatusCode"), childChildChildStatusCode);
+ StdStatusCode child1StatusCode = new StdStatusCode(new IdentifierImpl("child1StatusCode"), childChildStatusCode);
+ StdStatusCode statusCode = new StdStatusCode(XACML3.ID_STATUS_OK, child1StatusCode);
+
+ status = new StdMutableStatus(statusCode);
+
+
+ result = new StdMutableResult(status);
+ result.setDecision(Decision.PERMIT);
+
+
+
+
+ // add attribute list in result
+ Identifier categoryIdentifier = new IdentifierImpl("firstCategory");
+ Attribute[] attrList = {
+ new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true),
+ new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", false),
+ new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true),
+ new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true),
+ new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true),
+ new StdAttribute(categoryIdentifier, new IdentifierImpl("attrNoIssuer"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), null, true) };
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, Arrays.asList(attrList)));
+ categoryIdentifier = new IdentifierImpl("secondCategory");
+ Attribute[] secondAttrList = {
+ new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent12"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu2"), "AIssue2", true),
+ new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent22"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Abc2"), "BIssue2", false),
+ new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent32"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Der2"), "CIssue2", true) };
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, Arrays.asList(secondAttrList)));
+
+
+ // add PolicyIdentifierList to result
+ StdIdReference policyIdentifier1 = null;
+ StdIdReference policyIdentifier2 = null;
+ StdIdReference policySetIdentifier1 = null;
+ StdIdReference policySetIdentifier2 = null;
+ try {
+ policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), StdVersion.newInstance("1.2.3"));
+ policyIdentifier2 = new StdIdReference(new IdentifierImpl("idRef2_NoVersion"));
+ policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"), StdVersion.newInstance("4.5.6.7.8.9.0"));
+ policySetIdentifier2 = new StdIdReference(new IdentifierImpl("idSetRef2_NoVersion"));
+ } catch (ParseException e1) {
+ fail("creating policyIds, e="+e1);
+ }
+
+ result.addPolicyIdentifier(policyIdentifier1);
+ result.addPolicyIdentifier(policyIdentifier2);
+
+ result.addPolicySetIdentifier(policySetIdentifier1);
+ result.addPolicySetIdentifier(policySetIdentifier2);
+
+ response.add(result);
+
+ // convert Response to XML
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+//System.out.println(xmlResponse);
+//System.out.println(DOMResponse.toString(response, true));
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusMessage>some status message</StatusMessage><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:action:purpose\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\" Issuer=\"an Issuer\"><AttributeValue>doh</AttributeValue><AttributeValue>5432</AttributeValue><AttributeValue>meh</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result><Result><Decision>Deny</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Ned</AttributeAssignment></Obligation><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Maggie</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Homer</AttributeAssignment></Obligation></Obligations><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Crusty</AttributeAssignment></Advice></AssociatedAdvice></Result><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"><StatusCode Value=\"child1StatusCode\"><StatusCode Value=\"childChildStatusCode\"><StatusCode Value=\"childChildChildStatusCode\"/></StatusCode></StatusCode></StatusCode></Status><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrNoIssuer\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes><Attributes Category=\"secondCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent12\" Issuer=\"AIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu2</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent32\" Issuer=\"CIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Der2</AttributeValue></Attribute></Attributes><PolicyIdentifierList><PolicyIdReference Version=\"1.2.3\">idRef1</PolicyIdReference><PolicyIdReference>idRef2_NoVersion</PolicyIdReference><PolicySetIdReference Version=\"4.5.6.7.8.9.0\">idSetRef1</PolicySetIdReference><PolicySetIdReference>idSetRef2_NoVersion</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ }
+
+
+
+
+ // combinations of Status values with Decision values
+ @Test
+ public void testDecisionStatusMatch() {
+ // the tests in this method use different values and do not change structures, so we can re-use the objects
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ result.setStatus(status);
+ response.add(result);
+
+ // StatusCode = OK
+ status.setStatusCode(StdStatusCode.STATUS_CODE_OK);
+ result.setDecision(Decision.PERMIT);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ result.setDecision(Decision.DENY);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Deny</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ result.setDecision(Decision.NOTAPPLICABLE);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>NotApplicable</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ result.setDecision(Decision.INDETERMINATE);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+ result.setDecision(Decision.INDETERMINATE_DENY);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+ result.setDecision(Decision.INDETERMINATE_DENYPERMIT);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+ result.setDecision(Decision.INDETERMINATE_PERMIT);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+
+
+
+
+
+ // StatusCode = SyntaxError
+ status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR);
+ result.setDecision(Decision.PERMIT);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+ result.setDecision(Decision.DENY);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+ result.setDecision(Decision.NOTAPPLICABLE);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+ result.setDecision(Decision.INDETERMINATE);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ result.setDecision(Decision.INDETERMINATE_DENY);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ result.setDecision(Decision.INDETERMINATE_DENYPERMIT);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ result.setDecision(Decision.INDETERMINATE_PERMIT);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // StatusCode = ProcessingError
+ status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR);
+ result.setDecision(Decision.PERMIT);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+ result.setDecision(Decision.DENY);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+ result.setDecision(Decision.NOTAPPLICABLE);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+ result.setDecision(Decision.INDETERMINATE);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ result.setDecision(Decision.INDETERMINATE_DENY);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ result.setDecision(Decision.INDETERMINATE_DENYPERMIT);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ result.setDecision(Decision.INDETERMINATE_PERMIT);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+
+ // StatusCode = MissingAttribute
+ status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);
+ result.setDecision(Decision.PERMIT);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+ result.setDecision(Decision.DENY);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+ result.setDecision(Decision.NOTAPPLICABLE);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+ result.setDecision(Decision.INDETERMINATE);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ result.setDecision(Decision.INDETERMINATE_DENY);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ result.setDecision(Decision.INDETERMINATE_DENYPERMIT);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ result.setDecision(Decision.INDETERMINATE_PERMIT);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ }
+
+
+
+
+ // tests related to Status and its components
+ @Test
+ public void testStatus() {
+ // Status with no StatusCode - error
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ result.setStatus(status);
+ result.setDecision(Decision.PERMIT);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // Status with StatusMessage when OK
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_OK);
+ status.setStatusMessage("I'm ok, you're ok");
+ result.setStatus(status);
+ result.setDecision(Decision.PERMIT);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // Status with StatusDetail when OK
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_OK);
+ StdMutableStatusDetail statusDetail = new StdMutableStatusDetail();
+ status.setStatusDetail(statusDetail);
+ result.setStatus(status);
+ result.setDecision(Decision.PERMIT);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // Status with StatusMessage when SyntaxError
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR);
+ status.setStatusMessage("I'm ok, you're ok");
+ result.setStatus(status);
+ result.setDecision(Decision.INDETERMINATE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // Status with empty StatusDetail when SyntaxError
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR);
+ statusDetail = new StdMutableStatusDetail();
+ status.setStatusDetail(statusDetail);
+ result.setStatus(status);
+ result.setDecision(Decision.INDETERMINATE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+
+ // Status with StatusMessage when ProcessingError
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR);
+ status.setStatusMessage("I'm ok, you're ok");
+ result.setStatus(status);
+ result.setDecision(Decision.INDETERMINATE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // Status with empty StatusDetail when ProcessingError
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR);
+ statusDetail = new StdMutableStatusDetail();
+ status.setStatusDetail(statusDetail);
+ result.setStatus(status);
+ result.setDecision(Decision.INDETERMINATE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+
+ // Status with StatusMessage when MissingAttribute
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);
+ status.setStatusMessage("I'm ok, you're ok");
+ result.setStatus(status);
+ result.setDecision(Decision.INDETERMINATE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // Status with empty StatusDetail when MissingAttribute
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);
+ statusDetail = new StdMutableStatusDetail();
+ status.setStatusDetail(statusDetail);
+ result.setStatus(status);
+ result.setDecision(Decision.INDETERMINATE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail></StatusDetail></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+
+ // Status with StatusDetail with empty detail when MissingAttribute
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);
+ statusDetail = new StdMutableStatusDetail();
+ StdMutableMissingAttributeDetail mad = new StdMutableMissingAttributeDetail();
+ statusDetail.addMissingAttributeDetail(mad);
+ status.setStatusDetail(statusDetail);
+ result.setStatus(status);
+ result.setDecision(Decision.INDETERMINATE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // Status with StatusDetail with valid detail with no value when MissingAttribute
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);
+ statusDetail = new StdMutableStatusDetail();
+ mad = new StdMutableMissingAttributeDetail();
+ mad.setAttributeId(new IdentifierImpl("mad"));
+ mad.setCategory(XACML3.ID_ACTION);
+ mad.setDataTypeId(DataTypes.DT_STRING.getId());
+ statusDetail.addMissingAttributeDetail(mad);
+ status.setStatusDetail(statusDetail);
+ result.setStatus(status);
+ result.setDecision(Decision.INDETERMINATE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // Status with StatusDetail with valid detail with value when MissingAttribute
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);
+ statusDetail = new StdMutableStatusDetail();
+ mad = new StdMutableMissingAttributeDetail();
+ mad.setAttributeId(new IdentifierImpl("mad"));
+ mad.setCategory(XACML3.ID_ACTION);
+ mad.setDataTypeId(DataTypes.DT_STRING.getId());
+ mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh"));
+ statusDetail.addMissingAttributeDetail(mad);
+ status.setStatusDetail(statusDetail);
+ result.setStatus(status);
+ result.setDecision(Decision.INDETERMINATE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>meh</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // Status with StatusDetail with array valid detail with value when MissingAttribute
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);
+ statusDetail = new StdMutableStatusDetail();
+ mad = new StdMutableMissingAttributeDetail();
+ mad.setAttributeId(new IdentifierImpl("mad"));
+ mad.setCategory(XACML3.ID_ACTION);
+ mad.setDataTypeId(DataTypes.DT_STRING.getId());
+ mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh"));
+ mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "nu?"));
+ statusDetail.addMissingAttributeDetail(mad);
+ status.setStatusDetail(statusDetail);
+ result.setStatus(status);
+ result.setDecision(Decision.INDETERMINATE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>meh</AttributeValue><AttributeValue>nu?</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // Status with StatusDetail with valid detail with Integer value when MissingAttribute
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);
+ statusDetail = new StdMutableStatusDetail();
+ mad = new StdMutableMissingAttributeDetail();
+ mad.setAttributeId(new IdentifierImpl("mad"));
+ mad.setCategory(XACML3.ID_ACTION);
+ mad.setDataTypeId(DataTypes.DT_STRING.getId());
+ mad.addAttributeValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111));
+ statusDetail.addMissingAttributeDetail(mad);
+ status.setStatusDetail(statusDetail);
+ result.setStatus(status);
+ result.setDecision(Decision.INDETERMINATE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>1111</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // Status with StatusDetail with array valid detail with Integer value when MissingAttribute
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);
+ statusDetail = new StdMutableStatusDetail();
+ mad = new StdMutableMissingAttributeDetail();
+ mad.setAttributeId(new IdentifierImpl("mad"));
+ mad.setCategory(XACML3.ID_ACTION);
+ mad.setDataTypeId(DataTypes.DT_STRING.getId());
+ mad.addAttributeValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111));
+ mad.addAttributeValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 2222));
+ statusDetail.addMissingAttributeDetail(mad);
+ status.setStatusDetail(statusDetail);
+ result.setStatus(status);
+ result.setDecision(Decision.INDETERMINATE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>1111</AttributeValue><AttributeValue>2222</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+// StringNamespaceContext snc = new StringNamespaceContext();
+// try {
+// snc.add("defaultURI");
+// snc.add("md", "referenceForMD");
+// } catch (Exception e) {
+// fail("unable to create NamespaceContext e="+e);
+// }
+// XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record");
+//
+//TODO - assume that we will never try to pass back an XPathExpression in a MissingAttributeDetail - it doesn't make sense and is unclear how to put into XML
+// // Status with StatusDetail with valid detail with XPathExpression value when MissingAttribute
+// response = new StdMutableResponse();
+// result = new StdMutableResult();
+// status = new StdMutableStatus();
+// status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);
+// statusDetail = new StdMutableStatusDetail();
+// mad = new StdMutableMissingAttributeDetail();
+// mad.setAttributeId(new IdentifierImpl("mad"));
+// mad.setCategory(XACML3.ID_ACTION);
+// mad.setDataTypeId(DataTypes.DT_STRING.getId());
+// mad.addAttributeValue(new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategoryId")));
+// statusDetail.addMissingAttributeDetail(mad);
+// status.setStatusDetail(statusDetail);
+// result.setStatus(status);
+// result.setDecision(Decision.INDETERMINATE);
+// response.add(result);
+// try {
+// xmlResponse = DOMResponse.toString(response, false);
+// assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusDetail\":\"<MissingAttributeDetail><AttributeValue>1111</AttributeValue><Category>urn:oasis:names:tc:xacml:1.0:action</Category><AttributeId>mad</AttributeId><DataType>http://www.w3.org/2001/XMLSchema#string</DataType></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"}]}", xmlResponse);
+// } catch (Exception e) {
+// fail("operation failed, e="+e);
+// }
+//
+// // Status with StatusDetail with array valid detail with XPathExpression value when MissingAttribute
+// response = new StdMutableResponse();
+// result = new StdMutableResult();
+// status = new StdMutableStatus();
+// status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE);
+// statusDetail = new StdMutableStatusDetail();
+// mad = new StdMutableMissingAttributeDetail();
+// mad.setAttributeId(new IdentifierImpl("mad"));
+// mad.setCategory(XACML3.ID_ACTION);
+// mad.setDataTypeId(DataTypes.DT_STRING.getId());
+// mad.addAttributeValue(new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategoryId1")));
+// mad.addAttributeValue(new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategoryId2")));
+// statusDetail.addMissingAttributeDetail(mad);
+// status.setStatusDetail(statusDetail);
+// result.setStatus(status);
+// result.setDecision(Decision.INDETERMINATE);
+// response.add(result);
+// try {
+// xmlResponse = DOMResponse.toString(response, false);
+// assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusDetail\":\"<MissingAttributeDetail><AttributeValue>1111</AttributeValue><AttributeValue>2222</AttributeValue><Category>urn:oasis:names:tc:xacml:1.0:action</Category><AttributeId>mad</AttributeId><DataType>http://www.w3.org/2001/XMLSchema#string</DataType></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"}]}", xmlResponse);
+// } catch (Exception e) {
+// fail("operation failed, e="+e);
+// }
+
+//TODO - try with other data types, esp XPathExpression
+
+ // Status with StatusDetail with array valid detail with value when SyntaxError
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR);
+ statusDetail = new StdMutableStatusDetail();
+ mad = new StdMutableMissingAttributeDetail();
+ mad.setAttributeId(new IdentifierImpl("mad"));
+ mad.setCategory(XACML3.ID_ACTION);
+ mad.setDataTypeId(DataTypes.DT_STRING.getId());
+ mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh"));
+ mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "nu?"));
+ statusDetail.addMissingAttributeDetail(mad);
+ status.setStatusDetail(statusDetail);
+ result.setStatus(status);
+ result.setDecision(Decision.INDETERMINATE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // Status with StatusDetail with array valid detail with value when ProcessingError
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR);
+ statusDetail = new StdMutableStatusDetail();
+ mad = new StdMutableMissingAttributeDetail();
+ mad.setAttributeId(new IdentifierImpl("mad"));
+ mad.setCategory(XACML3.ID_ACTION);
+ mad.setDataTypeId(DataTypes.DT_STRING.getId());
+ mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh"));
+ mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "nu?"));
+ statusDetail.addMissingAttributeDetail(mad);
+ status.setStatusDetail(statusDetail);
+ result.setStatus(status);
+ result.setDecision(Decision.INDETERMINATE);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+
+
+ // Status with nested child StatusCodes (child status containing child status containing...)
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ StdStatusCode child1StatusCode = new StdStatusCode(new IdentifierImpl("child1StatusCode"));
+ StdStatusCode statusCode = new StdStatusCode(XACML3.ID_STATUS_OK, child1StatusCode);
+ status = new StdMutableStatus(statusCode);
+ status.setStatusMessage("I'm ok, you're ok");
+ result.setStatus(status);
+ result.setDecision(Decision.PERMIT);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"><StatusCode Value=\"child1StatusCode\"/></StatusCode><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ status = new StdMutableStatus();
+ StdStatusCode childChildChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildChildStatusCode"));
+ StdStatusCode childChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildStatusCode"), childChildChildStatusCode);
+ child1StatusCode = new StdStatusCode(new IdentifierImpl("child1StatusCode"), childChildStatusCode);
+ statusCode = new StdStatusCode(XACML3.ID_STATUS_OK, child1StatusCode);
+ status = new StdMutableStatus(statusCode);
+ status.setStatusMessage("I'm ok, you're ok");
+ result.setStatus(status);
+ result.setDecision(Decision.PERMIT);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"><StatusCode Value=\"child1StatusCode\"><StatusCode Value=\"childChildStatusCode\"><StatusCode Value=\"childChildChildStatusCode\"/></StatusCode></StatusCode></StatusCode><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ }
+
+
+
+ @Test
+ public void testObligations() {
+
+ // create an XPathExpression for use later
+ StringNamespaceContext snc = new StringNamespaceContext();
+ try {
+ snc.add("defaultURI");
+ snc.add("md", "referenceForMD");
+ } catch (Exception e) {
+ fail("unable to create NamespaceContext e="+e);
+ }
+ XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record");
+ XPathExpressionWrapper xpathExpressionWrapper2 = new XPathExpressionWrapper(snc, "//md:hospital");
+
+ StdMutableObligation obligation;
+
+ // test Obligation single decision no attributes
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ obligation = new StdMutableObligation();
+ obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ result.addObligation(obligation);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"></Obligation></Obligations></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // obligation missing Id
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ obligation = new StdMutableObligation();
+ result.addObligation(obligation);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+
+
+ // AttributeAssignment - with AttributeId, Value, Category, DataType, Issuer
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ obligation = new StdMutableObligation();
+ obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "obligation-issuer1",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));
+ result.addObligation(obligation);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // AttributeAssignment - with AttributeId, Value, no Category, DataType, Issuer
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ obligation = new StdMutableObligation();
+ obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ null,
+ XACML3.ID_SUBJECT,
+ "obligation-issuer1",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));
+ result.addObligation(obligation);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // AttributeAssignment - Missing AttributeId
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ obligation = new StdMutableObligation();
+ obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ null,
+ "obligation-issuer1",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));
+ result.addObligation(obligation);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // AttributeAssignment - Missing Value
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ obligation = new StdMutableObligation();
+ obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "obligation-issuer1",
+ null));
+ result.addObligation(obligation);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // AttributeAssignment - missing required DataType (Different than JSON where DataType is optional with default String)
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ obligation = new StdMutableObligation();
+ obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "obligation-issuer1",
+ new StdAttributeValue<String>(null, "Bart")));
+ result.addObligation(obligation);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // AttributeAssignment - missing issuer
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ obligation = new StdMutableObligation();
+ obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ null,
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));
+ result.addObligation(obligation);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // AttributeAssignment - Integer type
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ obligation = new StdMutableObligation();
+ obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ null,
+ new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111)));
+ result.addObligation(obligation);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // AttributeAssignment - XPathExpression type
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ obligation = new StdMutableObligation();
+ obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ null,
+ new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory"))));
+ result.addObligation(obligation);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+
+
+ //
+ // Technically arrays cannot occur in Obligations and Advice elements. The XML spec boils down to the following definition:
+ // <Obligation (attributes of the obligation) >
+ // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment>
+ // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment>
+ // :
+ // </Obligation
+ // which means that there may be multiple AttributeAssignments but each one has only one value.
+ // This differs from the Attributes section in which each <Attribute> may have multiple <AttributeValue> elements.
+ // For Obligations and Advice we can simulate an array by having multiple AttributeAssignment elements with the same Category, Id and Issuer.
+ //
+
+
+ // AttributeAssignment - Multiple values with same Category and Id (one way of doing array)
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ obligation = new StdMutableObligation();
+ obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "obligation-issuer1",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "obligation-issuer1",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Lisa")));
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "obligation-issuer1",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Maggie")));
+ result.addObligation(obligation);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Lisa</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Maggie</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // AttributeAssignment - Multiple Integer values with same Category and Id (one way of doing array)
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ obligation = new StdMutableObligation();
+ obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "obligation-issuer1",
+ new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111)));
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "obligation-issuer1",
+ new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 2222)));
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "obligation-issuer1",
+ new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 3333)));
+ result.addObligation(obligation);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">2222</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">3333</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // Multiple XPathExpression values with same Category and Id (one way of doing array)
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ obligation = new StdMutableObligation();
+ obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ null,
+ new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory"))));
+ obligation.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ null,
+ new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper2, new IdentifierImpl("SimpleXPathCategory"))));
+ result.addObligation(obligation);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:hospital</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ }
+
+
+
+
+ @Test
+ public void testAdvice() {
+
+ // create an XPathExpression for use later
+ StringNamespaceContext snc = new StringNamespaceContext();
+ try {
+ snc.add("defaultURI");
+ snc.add("md", "referenceForMD");
+ } catch (Exception e) {
+ fail("unable to create NamespaceContext e="+e);
+ }
+ XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record");
+ XPathExpressionWrapper xpathExpressionWrapper2 = new XPathExpressionWrapper(snc, "//md:hospital");
+
+ StdMutableAdvice Advice;
+
+ // test Advice single decision no attributes
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ Advice = new StdMutableAdvice();
+ Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ result.addAdvice(Advice);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"></Advice></AssociatedAdvice></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // Advice missing Id
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ Advice = new StdMutableAdvice();
+ result.addAdvice(Advice);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+
+
+ // AttributeAssignment - with AttributeId, Value, Category, DataType, Issuer
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ Advice = new StdMutableAdvice();
+ Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "Advice-issuer1",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));
+ result.addAdvice(Advice);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // AttributeAssignment - with AttributeId, Value, no Category, DataType, Issuer
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ Advice = new StdMutableAdvice();
+ Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ null,
+ XACML3.ID_SUBJECT,
+ "Advice-issuer1",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));
+ result.addAdvice(Advice);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // AttributeAssignment - Missing AttributeId
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ Advice = new StdMutableAdvice();
+ Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ null,
+ "Advice-issuer1",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));
+ result.addAdvice(Advice);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // AttributeAssignment - Missing Value
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ Advice = new StdMutableAdvice();
+ Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "Advice-issuer1",
+ null));
+ result.addAdvice(Advice);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // AttributeAssignment - missing Required DataType (Different than JSON where DataType is optional with default String)
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ Advice = new StdMutableAdvice();
+ Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "Advice-issuer1",
+ new StdAttributeValue<String>(null, "Bart")));
+ result.addAdvice(Advice);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // AttributeAssignment - missing issuer
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ Advice = new StdMutableAdvice();
+ Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ null,
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));
+ result.addAdvice(Advice);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // AttributeAssignment - Integer type
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ Advice = new StdMutableAdvice();
+ Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ null,
+ new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111)));
+ result.addAdvice(Advice);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // AttributeAssignment - XPathExpression type
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ Advice = new StdMutableAdvice();
+ Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ null,
+ new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory"))));
+ result.addAdvice(Advice);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+
+
+ //
+ // Technically arrays cannot occur in Obligations and Advice elements. The XML spec boils down to the following definition:
+ // <Obligation (attributes of the obligation) >
+ // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment>
+ // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment>
+ // :
+ // </Obligation
+ // which means that there may be multiple AttributeAssignments but each one has only one value.
+ // This differs from the Attributes section in which each <Attribute> may have multiple <AttributeValue> elements.
+ // For Obligations and Advice we can simulate an array by having multiple AttributeAssignment elements with the same Category, Id and Issuer.
+ //
+
+ // AttributeAssignment - Multiple values with same Category and Id (one way of doing array)
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ Advice = new StdMutableAdvice();
+ Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "Advice-issuer1",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")));
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "Advice-issuer1",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Lisa")));
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "Advice-issuer1",
+ new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Maggie")));
+ result.addAdvice(Advice);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Lisa</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Maggie</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // AttributeAssignment - Multiple Integer values with same Category and Id (one way of doing array)
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ Advice = new StdMutableAdvice();
+ Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "Advice-issuer1",
+ new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111)));
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "Advice-issuer1",
+ new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 2222)));
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ "Advice-issuer1",
+ new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 3333)));
+ result.addAdvice(Advice);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">2222</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">3333</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // Multiple XPathExpression values with same Category and Id (one way of doing array)
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ Advice = new StdMutableAdvice();
+ Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION);
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ null,
+ new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory"))));
+ Advice.addAttributeAssignment(new StdMutableAttributeAssignment(
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
+ XACML3.ID_SUBJECT,
+ null,
+ new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper2, new IdentifierImpl("SimpleXPathCategory"))));
+ result.addAdvice(Advice);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:hospital</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+ // Attributes tests
+ @Test
+ public void testAttributes() {
+
+ // create an XPathExpression for use later
+ StringNamespaceContext snc = new StringNamespaceContext();
+ try {
+ snc.add("defaultURI");
+ snc.add("md", "referenceForMD");
+ } catch (Exception e) {
+ fail("unable to create NamespaceContext e="+e);
+ }
+ XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record");
+
+
+ Identifier categoryIdentifier;
+ List<Attribute> attrList = new ArrayList<Attribute>();
+ StdMutableAttribute mutableAttribute;
+
+ // Attr list with no entries
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ attrList.clear();
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"></Attributes></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // one Attribute
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ attrList.clear();
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // multiple attributes
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ attrList.clear();
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true));
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent2\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // IncludeInResult=false/true
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ attrList.clear();
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", false));
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"></Attributes></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // Missing AttributeId (mandatory)
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ attrList.clear();
+ attrList.add(new StdAttribute(categoryIdentifier, null, new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // Missing mandatory Value
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ attrList.clear();
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), null), "AIssue", true));
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // Missing optional Issuer
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ attrList.clear();
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), null, true));
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // missing required DataType (different from JSON where DataType is optional and assumed to be String)
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ attrList.clear();
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(null, "Apu"), "AIssue", true));
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // same id, same type different issuer
+ // (This is not an array of values because Issuer is different)
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ attrList.clear();
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"), "BIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Simpson"), "CIssue", true));
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Simpson</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // same id, same type same issuer
+ // (This is an array of values)
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ attrList.clear();
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"), "AIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Simpson"), "AIssue", true));
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Simpson</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // same Id, different types, same issuer
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ attrList.clear();
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "AIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "AIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "AIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "AIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "AIssue", true));
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // same Id, different types, different issuer
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ attrList.clear();
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), null, true));
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ // different Id, different types, same issuer
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ attrList.clear();
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "AIssue"), "BIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "AIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "AIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "AIssue", true));
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent2\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">AIssue</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // one Attribute of type XPathExpression (the only complex data type)
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ attrList.clear();
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategory")), "AIssue", true));
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" XPathCategory=\"xpathCategory\">//md:record</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // multiple sets of values
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ attrList.clear();
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", false));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true));
+ attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrNoIssuer"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), null, true));
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ categoryIdentifier = new IdentifierImpl("secondCategory");
+ Attribute[] secondAttrList = {
+ new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent12"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu2"), "AIssue2", true),
+ new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent22"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Abc2"), "BIssue2", false),
+ new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent32"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Der2"), "CIssue2", true) };
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, Arrays.asList(secondAttrList)));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrNoIssuer\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes><Attributes Category=\"secondCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent12\" Issuer=\"AIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu2</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent32\" Issuer=\"CIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Der2</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // array of values - same type
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ attrList.clear();
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ mutableAttribute = new StdMutableAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), (Collection<AttributeValue<?>>)null, "AIssue", true);
+
+ mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"));
+ mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"));
+ mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Homer"));
+ mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Ned"));
+
+ attrList.add(mutableAttribute);
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Homer</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Ned</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // array of values - compatible different types
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ attrList.clear();
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ mutableAttribute = new StdMutableAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), (Collection<AttributeValue<?>>)null, "AIssue", true);
+
+ mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567));
+ mutableAttribute.addValue(new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432));
+ mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567));
+ attrList.add(mutableAttribute);
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // array of values - incompatible different types (Different from JSON because these are not part of an array in XML, just separate values)
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ attrList.clear();
+ categoryIdentifier = new IdentifierImpl("firstCategory");
+ mutableAttribute = new StdMutableAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), (Collection<AttributeValue<?>>)null, "AIssue", true);
+
+ mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"));
+ mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"));
+ mutableAttribute.addValue(new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432));
+ mutableAttribute.addValue(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true));
+ mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567));
+ mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567));
+ attrList.add(mutableAttribute);
+ result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList));
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+ }
+
+
+
+
+
+ // PolicyIdentifier tests
+ @Test
+ public void testPolicyIdentifier() {
+
+ StdIdReference policyIdentifier1 = null;
+ StdIdReference policyIdentifier2 = null;
+ StdIdReference policySetIdentifier1 = null;
+ StdIdReference policySetIdentifier2 = null;
+
+ // multiple PolicyIdentifiers of both types
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ try {
+ policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), StdVersion.newInstance("1.2.3"));
+ policyIdentifier2 = new StdIdReference(new IdentifierImpl("idRef2_NoVersion"));
+ policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"), StdVersion.newInstance("4.5.6.7.8.9.0"));
+ policySetIdentifier2 = new StdIdReference(new IdentifierImpl("idSetRef2_NoVersion"));
+ } catch (ParseException e1) {
+ fail("creating policyIds, e="+e1);
+ }
+ result.addPolicyIdentifier(policyIdentifier1);
+ result.addPolicyIdentifier(policyIdentifier2);
+ result.addPolicySetIdentifier(policySetIdentifier1);
+ result.addPolicySetIdentifier(policySetIdentifier2);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicyIdReference Version=\"1.2.3\">idRef1</PolicyIdReference><PolicyIdReference>idRef2_NoVersion</PolicyIdReference><PolicySetIdReference Version=\"4.5.6.7.8.9.0\">idSetRef1</PolicySetIdReference><PolicySetIdReference>idSetRef2_NoVersion</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // PolicyIdentifier exists but has no IdReferences
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ policyIdentifier1 = null;
+ result.addPolicyIdentifier(policyIdentifier1);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // PolicySetIdentifier exists but has not IdReferences
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ policySetIdentifier1 = null;
+ result.addPolicyIdentifier(policySetIdentifier1);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ fail("Operation should throw exception");
+ } catch (DOMStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from object to XML: " + e);
+ }
+
+ // PolicyIdentifier with PolicyIdReference and no PolicySetIdReference
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ try {
+ policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), StdVersion.newInstance("1.2.3"));
+ } catch (ParseException e1) {
+ fail("creating policyIds, e="+e1);
+ }
+ result.addPolicyIdentifier(policyIdentifier1);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicyIdReference Version=\"1.2.3\">idRef1</PolicyIdReference></PolicyIdentifierList></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+
+ // PolicyIdentifier with no PolicyIdReference and with PolicySetIdReference
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+ try {
+ policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"), StdVersion.newInstance("4.5.6.7.8.9.0"));
+ } catch (ParseException e1) {
+ fail("creating policyIds, e="+e1);
+ }
+ result.addPolicySetIdentifier(policySetIdentifier1);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicySetIdReference Version=\"4.5.6.7.8.9.0\">idSetRef1</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+
+
+ // IdReferences without version
+ response = new StdMutableResponse();
+ result = new StdMutableResult();
+ result.setDecision(Decision.PERMIT);
+
+ policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), null);
+ policyIdentifier2 = new StdIdReference(new IdentifierImpl("idRef2_NoVersion"));
+ policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"));
+ policySetIdentifier2 = new StdIdReference(new IdentifierImpl("idSetRef2_NoVersion"));
+
+ result.addPolicyIdentifier(policyIdentifier1);
+ result.addPolicyIdentifier(policyIdentifier2);
+ result.addPolicySetIdentifier(policySetIdentifier1);
+ result.addPolicySetIdentifier(policySetIdentifier2);
+ response.add(result);
+ try {
+ xmlResponse = DOMResponse.toString(response, false);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicyIdReference>idRef1</PolicyIdReference><PolicyIdReference>idRef2_NoVersion</PolicyIdReference><PolicySetIdReference>idSetRef1</PolicySetIdReference><PolicySetIdReference>idSetRef2_NoVersion</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse);
+ } catch (Exception e) {
+ fail("operation failed, e="+e);
+ }
+ }
+
+
+//TODO - the XML spec implies that the Result Attributes may include the Content (It is part of the UML)
+
+
+ // test indentation???
+
+
+}
+
+
+/*
+Place to edit long strings ouput from tests
+
+
+Expected
+<?xml version="1.0" encoding="UTF-8"?><Response xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd"><Result><Decision>Permit</Decision></Result></Response>
+<?xml version="1.0" encoding="UTF-8"?><Response xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd"><Result><Decision>Permit</Decision></Result></Response>
+Actual
+
+
+
+ */
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermittedTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermittedTest.java
new file mode 100755
index 0000000..c7844a8
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionAccessPermittedTest.java
@@ -0,0 +1,497 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdMutableRequest;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacml.std.dom.DOMRequest;
+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.std.StdEvaluationContext;
+import com.att.research.xacmlatt.pdp.std.StdFunctions;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import javax.xml.namespace.NamespaceContext;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * NOT IMPLEMENTED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * This function is not yet implemented so these tests intentionally fail.
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionAccessPermittedTest {
+
+ //
+ // Strings for the Request contents
+ //
+
+ String reqStrMainStart = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ + "<Request xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
+ + " http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\""
+ + " ReturnPolicyIdList=\"false\""
+ + " CombinedDecision=\"false\""
+ + " xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\""
+ + " xmlns:md=\"http://www.medico.com/schemas/record\""
+ + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+ + " <Attributes Category=\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\">"
+ + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\">"
+ + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Julius Hibbert</AttributeValue>"
+ + " </Attribute>"
+ + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">"
+ + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>"
+ + " </Attribute>"
+ + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">"
+ + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>"
+ + " </Attribute>"
+ + "</Attributes>";
+
+ String reqStrResourceStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\">";
+
+ String reqStrMdRecordSimpson =
+ "<md:record>" +
+ "<md:hospital_info>" +
+ "<md:name>ABC Hospital</md:name>" +
+ "<md:department>Surgery</md:department>" +
+ "</md:hospital_info>" +
+ "<md:patient_info>" +
+ "<md:name>Bart Simpson</md:name>" +
+ "<md:age>60</md:age>" +
+ "<md:sex>male</md:sex>" +
+ "<md:health_insurance>123456</md:health_insurance>" +
+ "</md:patient_info>" +
+ "<md:diagnosis_info>" +
+ "<md:diagnosis>" +
+ "<md:item type=\"primary\">Gastric Cancer</md:item>" +
+ "<md:item type=\"secondary\">Hyper tension</md:item>" +
+ "</md:diagnosis>" +
+ "<md:pathological_diagnosis>" +
+ "<md:diagnosis>" +
+ "<md:item type=\"primary\">Well differentiated adeno carcinoma</md:item>" +
+ "</md:diagnosis>" +
+ "<md:date>2000-10-05</md:date>" +
+ "<md:malignancy type=\"yes\"/>" +
+ "</md:pathological_diagnosis>" +
+ "</md:diagnosis_info>" +
+ " </md:record>";
+ String reqStrContentMdRecordSimpson = "<Content>" + reqStrMdRecordSimpson + "</Content>";
+ String reqStrMalformedContent =
+ " <Content>" +
+ "<md:record>" +
+ "<md:hospital_info>" +
+ "<md:name>ABC Hospital</md:name>" +
+ "<md:malignancy type=\"yes\"/>" +
+ "</Content>";
+ String reqStrMdRecordSpringer =
+ "<md:record>" +
+ "<md:hospital_info>" +
+ "<md:name>XYZ Hospital</md:name>" +
+ "<md:department>Surgery</md:department>" +
+ "</md:hospital_info>" +
+ "<md:patient_info>" +
+ "<md:name>Jerry Springer</md:name>" +
+ "<md:age>65</md:age>" +
+ "<md:sex>male</md:sex>" +
+ "<md:health_insurance>765432</md:health_insurance>" +
+ "</md:patient_info>" +
+ "<md:diagnosis_info>" +
+ "<md:diagnosis>" +
+ "<md:item type=\"primary\">Hyatal Hernia</md:item>" +
+ "<md:item type=\"secondary\">Diabetes</md:item>" +
+ "<md:item type=\"tertiary\">Neuronal Collapse</md:item>" +
+ "</md:diagnosis>" +
+ "<md:pathological_diagnosis>" +
+ "<md:diagnosis>" +
+ "<md:item type=\"primary\">We have no idea</md:item>" +
+ "</md:diagnosis>" +
+ "<md:date>2012-07-22</md:date>" +
+ "<md:malignancy type=\"no\"/>" +
+ "</md:pathological_diagnosis>" +
+ "</md:diagnosis_info>" +
+ " </md:record>";
+ String reqStrContentMdRecordSpringer =
+ "<Content>" + reqStrMdRecordSpringer + "</Content>";
+
+ String reqStrResourceEnd = " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\">"
+ + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#anyURI\">http://medico.com/record/patient/BartSimpson</AttributeValue>"
+ + " </Attribute>"
+ + "</Attributes> ";
+ String reqStrActionStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\">";
+
+ String reqStrActionEnd = "<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\">"
+ + "<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">read</AttributeValue>"
+ + "</Attribute>"
+ + "</Attributes> ";
+ String reqStrEnvironmentStartEnd = " <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\" />";
+ String reqStrMainEnd = " </Request>";
+
+
+ // combined strings for convenience
+ String reqStrMainResourceStart = reqStrMainStart + reqStrResourceStart;
+ String reqStrResourceAllEnd = reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrEnvironmentStartEnd + reqStrMainEnd;
+
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+
+
+ // Name Spaces used in the XML as part of these examples - needed for compiling XPaths
+ NamespaceContext nameSpaceContext = new NamespaceContext() {
+ @Override
+ public Iterator<?> getPrefixes(String arg0) { return null;}
+
+ @Override
+ public String getPrefix(String arg0) {return null;}
+
+ @Override
+ public String getNamespaceURI(String arg0) {
+ if("md".equals(arg0)) {
+ return "http://www.medico.com/schemas/record";
+ } else if ("xacml-context".equals(arg0)) {
+ return "urn:oasis:names:tc:xacml:3.0:context:schema:os";
+ } else if ("xsi".equals(arg0)) {
+ return "http://www.w3.org/2001/XMLSchema-instance";
+ }
+ return null;
+ }
+ };
+
+
+
+ //
+ // URIs for attribute categroies
+ //
+
+ FunctionArgumentAttributeValue attrUriNull = null;
+ FunctionArgumentAttributeValue attrUriEmpty = null;
+ FunctionArgumentAttributeValue attrUriResources = null;
+ FunctionArgumentAttributeValue attrUriAction = null;
+ FunctionArgumentAttributeValue attrUriNotInRequest = null;
+ FunctionArgumentAttributeValue attrUriNotCategory = null;
+
+
+
+ //
+ // XML Contents
+ //
+
+ FunctionArgumentAttributeValue attrXnull = null;
+ FunctionArgumentAttributeValue attrXEmpty = null;
+ FunctionArgumentAttributeValue attrXSimpson = null;
+ FunctionArgumentAttributeValue attrXSpringer = null;
+ FunctionArgumentAttributeValue attrXContentSimpson = null;
+ FunctionArgumentAttributeValue attrXContentSpringer = null;
+ FunctionArgumentAttributeValue attrXBadXML = null;
+
+
+
+
+
+
+ //
+ // REQUEST objects available for use in tests
+ //
+ Request requestEmpty = new StdMutableRequest();
+ Request requestMdRecord = null;
+ Request requestDoubleResources = null;
+ Request requestDoubleContent = null;
+ Request requestResourceActionContent = null;
+ Request requestContentInAction = null;
+
+
+
+
+ /**
+ * Set up all variables in one place because it is complicated (lots of steps needed for each attribute)
+ */
+ public FunctionDefinitionAccessPermittedTest() {
+ try {
+
+
+ // create Function Attributes for URIs
+ attrUriNull = null;
+ attrUriEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(""));
+ attrUriResources = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:3.0:attribute-category:resource"));
+ attrUriAction = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:3.0:attribute-category:action"));
+ attrUriNotInRequest = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("NoSuchURI"));
+ attrUriNotCategory = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:1.0:resource:resource-id"));
+
+ // create Function Attributes for XML Strings
+ attrXnull = new FunctionArgumentAttributeValue(null);
+ attrXEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));
+ attrXSimpson = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMdRecordSimpson));
+ attrXSpringer = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMdRecordSpringer));
+ attrXContentSimpson = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrContentMdRecordSimpson));
+ attrXContentSpringer = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrContentMdRecordSpringer));
+ attrXBadXML = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMalformedContent));
+
+
+
+ // Request objects
+ // to create a Request object the easiest way is to put the xml into a file and use the DOMRequest to load it.
+
+ // single Content in the Resources section (normal valid request)
+ String reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceAllEnd;
+ File tFile = File.createTempFile("functionJunit", "request");
+ BufferedWriter bw = new BufferedWriter(new FileWriter(tFile));
+ bw.append(reqString);
+ bw.flush();
+ bw.close();
+ requestMdRecord = DOMRequest.load(tFile);
+ tFile.delete();
+
+ // Resources included twice
+ reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceEnd + reqStrResourceStart + reqStrContentMdRecordSimpson +reqStrResourceAllEnd;
+ tFile = File.createTempFile("functionJunit", "request");
+ bw = new BufferedWriter(new FileWriter(tFile));
+ bw.append(reqString);
+ bw.flush();
+ bw.close();
+ requestDoubleResources = DOMRequest.load(tFile);
+ tFile.delete();
+
+ // Content included twice - error
+ reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrContentMdRecordSimpson +reqStrResourceAllEnd;
+ tFile = File.createTempFile("functionJunit", "request");
+ bw = new BufferedWriter(new FileWriter(tFile));
+ bw.append(reqString);
+ bw.flush();
+ bw.close();
+ try {
+ requestDoubleContent = DOMRequest.load(tFile);
+ tFile.delete();
+ } catch (com.att.research.xacml.std.dom.DOMStructureException e) {
+ // this is what it should do, so just continue
+ } catch (Exception e) {
+ fail("Unexpected exception for bad XML, e="+e);
+ }
+
+ // content included in both Resource and Action - ok
+ reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecordSimpson + reqStrActionEnd + reqStrMainEnd;
+ tFile = File.createTempFile("functionJunit", "request");
+ bw = new BufferedWriter(new FileWriter(tFile));
+ bw.append(reqString);
+ bw.flush();
+ bw.close();
+ requestResourceActionContent = DOMRequest.load(tFile);
+ tFile.delete();
+
+ // Content included only in Action - missing content produces non-error result according to spec
+ reqString = reqStrMainResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecordSimpson + reqStrActionEnd + reqStrMainEnd;
+ tFile = File.createTempFile("functionJunit", "request");
+ bw = new BufferedWriter(new FileWriter(tFile));
+ bw.append(reqString);
+ bw.flush();
+ bw.close();
+ requestContentInAction = DOMRequest.load(tFile);
+ tFile.delete();
+
+
+
+ // Test that Bad XML is caught
+ @SuppressWarnings("unused")
+ Request requestContentMisplaced = null;
+ @SuppressWarnings("unused")
+ Request requestMalformedContent = null;
+
+
+ // Bad XML - Content not under a Category
+ reqString = reqStrMainStart + reqStrContentMdRecordSimpson + reqStrResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrMainEnd;
+ tFile = File.createTempFile("functionJunit", "request");
+ bw = new BufferedWriter(new FileWriter(tFile));
+ bw.append(reqString);
+ bw.flush();
+ bw.close();
+ try {
+ requestContentMisplaced = DOMRequest.load(tFile);
+ tFile.delete();
+ } catch (com.att.research.xacml.std.dom.DOMStructureException e) {
+ // this is what it should do, so just continue
+ } catch (Exception e) {
+ fail("Unexpected exception for bad XML, e="+e);
+ }
+
+ // Bad XML - Content is not valid XML
+ reqString = reqStrMainResourceStart + reqStrMalformedContent + reqStrResourceAllEnd;
+ tFile = File.createTempFile("functionJunit", "request");
+ bw = new BufferedWriter(new FileWriter(tFile));
+ bw.append(reqString);
+ bw.flush();
+ bw.close();
+ try {
+ requestMalformedContent = DOMRequest.load(tFile);
+ tFile.delete();
+ } catch (com.att.research.xacml.std.dom.DOMStructureException e) {
+ // this is what it should do, so just continue
+ } catch (Exception e) {
+ fail("Unexpected exception for bad XML, e="+e);
+ }
+
+ } catch (Exception e) {
+ fail("Constructor initializing variables, e="+ e + " cause="+e.getCause());
+ }
+
+ }
+
+
+
+
+
+
+
+ @Ignore
+ @Test
+ public void testAccess_permitted() {
+
+ ExpressionResult res = null;
+ Boolean resValue = null;
+
+ FunctionDefinitionAccessPermitted fd = (FunctionDefinitionAccessPermitted) StdFunctions.FD_ACCESS_PERMITTED;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_ACCESS_PERMITTED, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+
+ // successful invoke returns true
+ arguments.clear();
+ arguments.add(attrUriResources);
+ arguments.add(attrXEmpty);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+
+
+ // successful invoke returns false
+
+
+ // URI not in Request (ok - evaluate anyway)
+
+ // test for infinite loop
+
+ // second arg ok both with and without <Content> tag
+ arguments.clear();
+ arguments.add(attrUriResources);
+ arguments.add(attrXContentSpringer);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ arguments.clear();
+ arguments.add(attrUriResources);
+ arguments.add(attrXSpringer);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // second arg not valid XML
+ arguments.clear();
+ arguments.add(attrUriResources);
+ arguments.add(attrXBadXML);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:access-permitted Parsing of XML string failed. Cause='The element type \"md:hospital_info\" must be terminated by the matching end-tag \"</md:hospital_info>\".'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null Evaluation Context
+ arguments.clear();
+ arguments.add(attrUriNotCategory);
+ arguments.add(attrXContentSimpson);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:access-permitted First argument must be a urn for an attribute-category, not 'urn:oasis:names:tc:xacml:1.0:resource:resource-id", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null Request
+ arguments.clear();
+ arguments.add(attrUriAction);
+ arguments.add(attrXContentSimpson);
+ res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:access-permitted Got null Request in EvaluationContext", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // first arg not uri
+ arguments.clear();
+ arguments.add(attrUriNotCategory);
+ arguments.add(attrXContentSimpson);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:access-permitted First argument must be a urn for an attribute-category, not 'urn:oasis:names:tc:xacml:1.0:resource:resource-id", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // first arg not attribute-category urn
+ arguments.clear();
+ arguments.add(attrXContentSimpson);
+ arguments.add(attrXContentSimpson);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:access-permitted Expected data type 'anyURI' saw 'string'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second arg not string
+ arguments.clear();
+ arguments.add(attrUriAction);
+ arguments.add(attrUriAction);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:access-permitted Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // too few args
+ arguments.clear();
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:access-permitted Expected 2 arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrXContentSimpson);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:access-permitted Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // too many args
+ arguments.clear();
+ arguments.add(attrUriEmpty);
+ arguments.add(attrXContentSimpson);
+ arguments.add(attrXContentSimpson);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:access-permitted Expected 2 arguments, got 3", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ }
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmeticTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmeticTest.java
new file mode 100755
index 0000000..3887198
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionArithmeticTest.java
@@ -0,0 +1,707 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.DataTypes;
+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.std.StdFunctions;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionArithmeticTest {
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+ @Test
+ public void testInteger_add() {
+
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+ FunctionArgumentAttributeValue attrBadType = null;
+ try {
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));
+ attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_ADD;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_INTEGER_ADD, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+
+ // test normal add
+ arguments.add(attr1);
+ arguments.add(attr2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ BigInteger resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("2"), resValue);
+
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attrBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:integer-add Expected data type 'integer' saw 'double' at arg index 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+ @Test
+ public void testDouble_add() {
+
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+
+ try {
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.5));
+ } catch (Exception e) {
+ fail("creating attributes e="+e);
+ }
+
+ FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_ADD;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DOUBLE_ADD, fd.getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+
+ // test normal add
+ arguments.add(attr1);
+ arguments.add(attr2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Double resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(4.0), resValue);
+
+ }
+
+
+ @Test
+ public void testInteger_subtract() {
+
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+ try {
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(6));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_SUBTRACT;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_INTEGER_SUBTRACT, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+
+ // test normal
+ arguments.add(attr1);
+ arguments.add(attr2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ BigInteger resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("5"), resValue);
+
+ }
+
+
+ @Test
+ public void testDouble_subtract() {
+
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+
+ try {
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(8.5));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.3));
+ } catch (Exception e) {
+ fail("creating attributes e="+e);
+ }
+
+ FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_SUBTRACT;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DOUBLE_SUBTRACT, fd.getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+
+ // test normal
+ arguments.add(attr1);
+ arguments.add(attr2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Double resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(6.2), resValue);
+
+ }
+
+
+ @Test
+ public void testInteger_multiply() {
+
+ FunctionArgumentAttributeValue attr0 = null;
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+ try {
+ attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_MULTIPLY;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_INTEGER_MULTIPLY, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+
+ // test normal
+ arguments.add(attr1);
+ arguments.add(attr2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ BigInteger resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("10"), resValue);
+
+
+ // test 0
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr0);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("0"), resValue);
+ }
+
+
+ @Test
+ public void testDouble_multiply() {
+
+ FunctionArgumentAttributeValue attr0 = null;
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+
+ try {
+ attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0));
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.5));
+ } catch (Exception e) {
+ fail("creating attributes e="+e);
+ }
+
+ FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_MULTIPLY;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DOUBLE_MULTIPLY, fd.getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+
+ // test normal add
+ arguments.add(attr1);
+ arguments.add(attr2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Double resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(3.75), resValue);
+
+ // test multiply by 0
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr0);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(0), resValue);
+ }
+
+
+ @Test
+ public void testInteger_divide() {
+
+ FunctionArgumentAttributeValue attr0 = null;
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+ try {
+ attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_DIVIDE;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_INTEGER_DIVIDE, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+
+ // test normal
+ arguments.add(attr1);
+ arguments.add(attr2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ BigInteger resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("2"), resValue);
+
+
+ // test 0
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr0);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:integer-divide Divide by 0 error: 5, 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+ @Test
+ public void testDouble_divide() {
+
+ FunctionArgumentAttributeValue attr0 = null;
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+
+ try {
+ attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0));
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.5));
+
+ } catch (Exception e) {
+ fail("creating attributes e="+e);
+ }
+ FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_DIVIDE;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DOUBLE_DIVIDE, fd.getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+
+ // test normal
+ arguments.add(attr1);
+ arguments.add(attr2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Double resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(0.6), resValue);
+
+ // test multiply by 0
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr0);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:double-divide Divide by 0 error: 1.5, 0.0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+
+
+ @Test
+ public void testInteger_mod() {
+
+ FunctionArgumentAttributeValue attr0 = null;
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+ try {
+ attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(28));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_MOD;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_INTEGER_MOD, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+
+ // test normal
+ arguments.add(attr1);
+ arguments.add(attr2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ BigInteger resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("3"), resValue);
+
+
+ // test 0
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr0);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:integer-mod Divide by 0 error: 28, 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+ @Test
+ public void testInteger_abs() {
+
+ FunctionArgumentAttributeValue attr0 = null;
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attrM1 = null;
+ try {
+ attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5));
+ attrM1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-7));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_ABS;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_INTEGER_ABS, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+
+ // test normal
+ arguments.add(attr1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ BigInteger resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("5"), resValue);
+
+ arguments.clear();
+ arguments.add(attrM1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("7"), resValue);
+
+ arguments.clear();
+ arguments.add(attr0);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("0"), resValue);
+ }
+
+
+ @Test
+ public void testDouble_abs() {
+
+ FunctionArgumentAttributeValue attr0 = null;
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+
+ try {
+ attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0));
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.5));
+
+ } catch (Exception e) {
+ fail("creating attributes e="+e);
+ }
+
+ FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_ABS;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DOUBLE_ABS, fd.getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+
+ // test normal
+ arguments.add(attr1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Double resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(1.5), resValue);
+
+ arguments.clear();
+ arguments.add(attr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(2.5), resValue);
+
+ arguments.clear();
+ arguments.add(attr0);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(0), resValue);
+
+ }
+
+
+ @Test
+ public void testDouble_round() {
+
+ FunctionArgumentAttributeValue attr0 = null;
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+ FunctionArgumentAttributeValue attr3 = null;
+ FunctionArgumentAttributeValue attr4 = null;
+ FunctionArgumentAttributeValue attr5 = null;
+ FunctionArgumentAttributeValue attr6 = null;
+ try {
+ attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0));
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.49));
+ attr3 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.51));
+ attr4 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.5));
+ attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.49));
+ attr6 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.51));
+ } catch (Exception e) {
+ fail("creating attributes e="+e);
+ }
+
+
+
+ FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_ROUND;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_ROUND, fd.getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+
+ // test normal
+ arguments.add(attr0);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Double resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(0), resValue);
+
+ arguments.clear();
+ arguments.add(attr1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(2), resValue);
+
+ arguments.clear();
+ arguments.add(attr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(1), resValue);
+
+ arguments.clear();
+ arguments.add(attr3);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(2), resValue);
+
+ arguments.clear();
+ arguments.add(attr4);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(-2), resValue);
+
+ arguments.clear();
+ arguments.add(attr5);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(-2), resValue);
+
+ arguments.clear();
+ arguments.add(attr6);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(-3), resValue);
+ }
+
+
+ @Test
+ public void testDouble_floor() {
+ FunctionArgumentAttributeValue attr0 = null;
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+ FunctionArgumentAttributeValue attr3 = null;
+ FunctionArgumentAttributeValue attr4 = null;
+ FunctionArgumentAttributeValue attr5 = null;
+ FunctionArgumentAttributeValue attr6 = null;
+ try {
+ attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0));
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.49));
+ attr3 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.51));
+ attr4 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.5));
+ attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.49));
+ attr6 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.51));
+ } catch (Exception e) {
+ fail("creating attributes e="+e);
+ }
+
+ FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_FLOOR;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_FLOOR, fd.getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+
+ // test normal
+ arguments.add(attr0);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Double resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(0), resValue);
+
+ arguments.clear();
+ arguments.add(attr1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(1), resValue);
+
+ arguments.clear();
+ arguments.add(attr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(1), resValue);
+
+ arguments.clear();
+ arguments.add(attr3);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(1), resValue);
+
+ arguments.clear();
+ arguments.add(attr4);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(-3), resValue);
+
+ arguments.clear();
+ arguments.add(attr5);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(-3), resValue);
+
+ arguments.clear();
+ arguments.add(attr6);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(-3), resValue);
+ }
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsInTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsInTest.java
new file mode 100755
index 0000000..d097122
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagIsInTest.java
@@ -0,0 +1,201 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdAttributeValue;
+import com.att.research.xacml.std.datatypes.DataTypes;
+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.FunctionArgumentBag;
+import com.att.research.xacmlatt.pdp.std.StdFunctions;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionBagIsInTest {
+
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+
+ @Test
+ public void testString() {
+ String v1 = new String("abc");
+ String v2 = new String("def");
+ String notInBag = new String("lmnop");
+ String sameValueV1 = new String("abc");
+ Integer vOtherType = new Integer(11);
+
+
+ FunctionArgumentAttributeValue attrV1 = null;
+ FunctionArgumentAttributeValue attrV2 = null;
+ FunctionArgumentAttributeValue attrNotInBag = null;
+ FunctionArgumentAttributeValue attrSameValueV1 = null;
+ FunctionArgumentAttributeValue attrOtherType = null;
+ try {
+ attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));
+ attrV2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v2));
+ attrNotInBag = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(notInBag));
+ attrSameValueV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(sameValueV1));
+ attrOtherType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(vOtherType));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ Bag bag0 = new Bag();
+ Bag bag1 = new Bag();
+ bag1.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1));
+ Bag bag2 = new Bag();
+ bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1));
+ bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v2));;
+
+
+
+ FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0);
+ FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1);
+ FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2);
+
+
+
+ FunctionDefinitionBagIsIn<?> fd = (FunctionDefinitionBagIsIn<?>) StdFunctions.FD_STRING_IS_IN;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_IS_IN, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // element is in bag
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBag2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // element not in bag
+ arguments.clear();
+ arguments.add(attrNotInBag);
+ arguments.add(attrBag2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // different element with the same value is in bag
+ arguments.clear();
+ arguments.add(attrSameValueV1);
+ arguments.add(attrBag2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // empty bag
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBag0);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // missing arg
+ arguments.clear();
+ arguments.add(attrSameValueV1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-is-in Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // 1st arg is bag
+ arguments.clear();
+ arguments.add(attrBag1);
+ arguments.add(attrBag2);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-is-in Expected a simple value, saw a bag", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // 2nd arg not bag
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrV2);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-is-in Expected a bag, saw a simple value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // first arg null
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrBag2);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-is-in Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // 2nd arg null
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-is-in Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // first arg type does not match bag elements
+ arguments.clear();
+ arguments.add(attrOtherType);
+ arguments.add(attrBag2);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-is-in Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bag has mixed element types
+// behavior not specified for this case in spec. It ASSUMES that all elements in bag are same type.
+
+ }
+
+
+
+
+ //
+ //
+ // REST OF DATA TYPES OMITTED
+ // because they "should" all work the same
+ //
+ //
+
+
+
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnlyTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnlyTest.java
new file mode 100755
index 0000000..13c5161
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagOneAndOnlyTest.java
@@ -0,0 +1,204 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.math.BigInteger;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdAttributeValue;
+import com.att.research.xacml.std.datatypes.DataTypes;
+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.FunctionArgumentBag;
+import com.att.research.xacmlatt.pdp.std.StdFunctions;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionBagOneAndOnlyTest {
+
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+
+ @Test
+ public void testString() {
+ String v1 = new String("abc");
+ String v2 = new String("def");
+ BigInteger vOtherType = BigInteger.valueOf(11);
+
+ Bag bag0 = new Bag();
+ Bag bag1 = new Bag();
+ bag1.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1));
+ Bag bag2 = new Bag();
+ bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1));
+ bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v2));
+ Bag bagOtherType = new Bag();
+ bagOtherType.add(new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), vOtherType));
+
+ FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0);
+ FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1);
+ FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2);
+ FunctionArgumentBag attrBagOtherType = new FunctionArgumentBag(bagOtherType);
+
+
+ FunctionDefinitionBagOneAndOnly<?> fd = (FunctionDefinitionBagOneAndOnly<?>) StdFunctions.FD_STRING_ONE_AND_ONLY;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_ONE_AND_ONLY, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+
+
+ // bag with only one
+ arguments.clear();
+ arguments.add(attrBag1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ String resValue = (String)res.getValue().getValue();
+ assertEquals(v1, resValue);
+
+ // null bag
+ arguments.clear();
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-one-and-only Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bag with exactly one but of other type in it
+ arguments.clear();
+ arguments.add(attrBagOtherType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-one-and-only Element in bag of wrong type. Expected string got integer", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bag with none
+ arguments.clear();
+ arguments.add(attrBag0);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-one-and-only Expected 1 but Bag has 0 elements", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bag with multiple
+ arguments.clear();
+ arguments.add(attrBag2);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-one-and-only Expected 1 but Bag has 2 elements", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+ @Test
+ public void testBoolean() {
+ Boolean v1 = new Boolean(true);
+ Boolean v2 = new Boolean(false);
+ BigInteger vOtherType = BigInteger.valueOf(11);
+
+ Bag bag0 = new Bag();
+ Bag bag1 = new Bag();
+ bag1.add(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), v1));
+ Bag bag2 = new Bag();
+ bag2.add(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), v1));
+ bag2.add(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), v2));
+ Bag bagOtherType = new Bag();
+ bagOtherType.add(new StdAttributeValue<BigInteger>(DataTypes.DT_STRING.getId(), vOtherType));
+
+
+ FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0);
+ FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1);
+ FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2);
+ FunctionArgumentBag attrBagOtherType = new FunctionArgumentBag(bagOtherType);
+
+
+ FunctionDefinitionBagOneAndOnly<?> fd = (FunctionDefinitionBagOneAndOnly<?>) StdFunctions.FD_BOOLEAN_ONE_AND_ONLY;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_BOOLEAN_ONE_AND_ONLY, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+
+
+ // bag with only one
+ arguments.clear();
+ arguments.add(attrBag1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(true), resValue);
+
+ // null bag
+ arguments.clear();
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:boolean-one-and-only Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bag with exactly one but of other type in it
+ arguments.clear();
+ arguments.add(attrBagOtherType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:boolean-one-and-only Element in bag of wrong type. Expected boolean got string", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bag with none
+ arguments.clear();
+ arguments.add(attrBag0);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:boolean-one-and-only Expected 1 but Bag has 0 elements", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bag with multiple
+ arguments.clear();
+ arguments.add(attrBag2);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:boolean-one-and-only Expected 1 but Bag has 2 elements", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+ //
+ //
+ // REST OF DATA TYPES OMITTED
+ // because they "should" all work the same
+ //
+ //
+
+
+
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSizeTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSizeTest.java
new file mode 100755
index 0000000..afc5e09
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagSizeTest.java
@@ -0,0 +1,138 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.StdAttributeValue;
+import com.att.research.xacml.std.datatypes.DataTypes;
+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.FunctionArgumentBag;
+import com.att.research.xacmlatt.pdp.std.StdFunctions;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionBagSizeTest {
+
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+
+ @Test
+ public void testString() {
+ String v1 = new String("abc");
+ String v2 = new String("def");
+ Integer vOtherType = new Integer(11);
+
+
+
+ Bag bag0 = new Bag();
+ Bag bag1 = new Bag();
+ bag1.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1));
+ Bag bag2 = new Bag();
+ bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1));
+ bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v2));
+ Bag bagOtherType = new Bag();
+ bagOtherType.add(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), vOtherType));
+
+
+ FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0);
+ FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1);
+ FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2);
+ FunctionArgumentBag attrBagOtherType = new FunctionArgumentBag(bagOtherType);
+
+
+ FunctionDefinitionBagSize<?> fd = (FunctionDefinitionBagSize<?>) StdFunctions.FD_STRING_BAG_SIZE;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_BAG_SIZE, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+
+
+ // bag with only one
+ arguments.clear();
+ arguments.add(attrBag1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(BigInteger.class, res.getValue().getValue().getClass());
+ BigInteger resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(BigInteger.valueOf(1), resValue);
+
+ // null bag
+ arguments.clear();
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-bag-size Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bag with exactly one but of other type in it
+ arguments.clear();
+ arguments.add(attrBagOtherType);
+ res = fd.evaluate(null, arguments);
+ // NOTE: Size does not care about content type!
+ assertTrue(res.isOk());
+ assertEquals(BigInteger.class, res.getValue().getValue().getClass());
+ resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(BigInteger.valueOf(1), resValue);
+
+ // bag with none
+ arguments.clear();
+ arguments.add(attrBag0);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(BigInteger.class, res.getValue().getValue().getClass());
+ resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(BigInteger.valueOf(0), resValue);
+
+ // bag with multiple
+ arguments.clear();
+ arguments.add(attrBag2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(BigInteger.class, res.getValue().getValue().getClass());
+ resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(BigInteger.valueOf(2), resValue);
+ }
+
+
+
+
+
+
+
+ //
+ //
+ // REST OF DATA TYPES OMITTED
+ // because they "should" all work the same
+ //
+ //
+
+
+
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagTest.java
new file mode 100755
index 0000000..4901916
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBagTest.java
@@ -0,0 +1,527 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.DataTypes;
+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.std.StdFunctions;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionBagTest {
+
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+
+ FunctionArgumentAttributeValue attrInteger = null;
+ FunctionArgumentAttributeValue attrString = null;
+
+ public FunctionDefinitionBagTest() {
+ try {
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1111111111));
+ attrString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("a string value"));
+ } catch (Exception e) {
+ fail("creating attributes e="+e);
+ }
+ }
+
+ @Test
+ public void testString() {
+
+ String s1 = "abc";
+ String s2 = "def";
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+ try {
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(s1));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(s2));
+ } catch (Exception e) {
+ fail("creating attributes e="+e);
+ }
+
+ FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_STRING_BAG;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_BAG, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertTrue(fd.returnsBag());
+
+ // bag with only one
+ arguments.clear();
+ arguments.add(attr1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Bag bag = res.getBag();
+ assertNotNull(bag);
+ Iterator<AttributeValue<?>> it = bag.getAttributeValues();
+ assertEquals(1, bag.size());
+ AttributeValue<?> attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+
+ // zero args => empty bag
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ assertEquals(0, bag.size());
+
+
+ // null argument
+ arguments.clear();
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-bag Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // argument of other type
+ arguments.clear();
+ arguments.add(attrInteger);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-bag Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // 2 args (check response is correct)
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(2, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s2, attrValueObject.getValue());
+
+ // duplicate args (verify return)
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr2);
+ arguments.add(attr1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(3, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s2, attrValueObject.getValue());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+
+ // lots of args
+ arguments.clear();
+ for (int i = 0; i < 1000; i++) {
+ arguments.add(attr1);
+ }
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(1000, bag.size());
+
+ }
+
+
+ @Test
+ public void testBoolean() {
+
+ Boolean s1 = true;
+ Boolean s2 = false;
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+ try {
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(s1));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(s2));
+ } catch (Exception e) {
+ fail("creating attributes e="+e);
+ }
+
+ FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_BOOLEAN_BAG;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_BOOLEAN_BAG, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertTrue(fd.returnsBag());
+
+ // bag with only one
+ arguments.clear();
+ arguments.add(attr1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Bag bag = res.getBag();
+ assertNotNull(bag);
+ Iterator<AttributeValue<?>> it = bag.getAttributeValues();
+ assertEquals(1, bag.size());
+ AttributeValue<?> attrValueObject = it.next();
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+
+ // zero args => empty bag
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ assertEquals(0, bag.size());
+
+
+ // null argument
+ arguments.clear();
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:boolean-bag Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // argument of other type
+ arguments.clear();
+ arguments.add(attrInteger);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:boolean-bag Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // 2 args (check response is correct)
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(2, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s2, attrValueObject.getValue());
+
+ // duplicate args (verify return)
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr2);
+ arguments.add(attr1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(3, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s2, attrValueObject.getValue());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+
+ // lots of args
+ arguments.clear();
+ for (int i = 0; i < 1000; i++) {
+ arguments.add(attr1);
+ }
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(1000, bag.size());
+
+ }
+
+
+
+ @Test
+ public void testInteger() {
+
+ BigInteger s1 = new BigInteger("123");
+ BigInteger s2 = new BigInteger("456");
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+ try {
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(s1));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(s2));
+ } catch (Exception e) {
+ fail("creating attributes e="+e);
+ }
+
+ FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_INTEGER_BAG;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_INTEGER_BAG, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertTrue(fd.returnsBag());
+
+ // bag with only one
+ arguments.clear();
+ arguments.add(attr1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Bag bag = res.getBag();
+ assertNotNull(bag);
+ Iterator<AttributeValue<?>> it = bag.getAttributeValues();
+ assertEquals(1, bag.size());
+ AttributeValue<?> attrValueObject = it.next();
+ assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+
+ // zero args => empty bag
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ assertEquals(0, bag.size());
+
+
+ // null argument
+ arguments.clear();
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:integer-bag Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // argument of other type
+ arguments.clear();
+ arguments.add(attrString);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:integer-bag Expected data type 'integer' saw 'string'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // 2 args (check response is correct)
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(2, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s2, attrValueObject.getValue());
+
+ // duplicate args (verify return)
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr2);
+ arguments.add(attr1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(3, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s2, attrValueObject.getValue());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+
+ // lots of args
+ arguments.clear();
+ for (int i = 0; i < 1000; i++) {
+ arguments.add(attr1);
+ }
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(1000, bag.size());
+
+ }
+
+
+
+
+ @Test
+ public void testDouble() {
+
+ Double s1 = 123.45;
+ Double s2 = 678.901;
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+ try {
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(s1));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(s2));
+ } catch (Exception e) {
+ fail("creating attributes e="+e);
+ }
+
+ FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_DOUBLE_BAG;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DOUBLE_BAG, fd.getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertTrue(fd.returnsBag());
+
+ // bag with only one
+ arguments.clear();
+ arguments.add(attr1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Bag bag = res.getBag();
+ assertNotNull(bag);
+ Iterator<AttributeValue<?>> it = bag.getAttributeValues();
+ assertEquals(1, bag.size());
+ AttributeValue<?> attrValueObject = it.next();
+ assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+
+ // zero args => empty bag
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ assertEquals(0, bag.size());
+
+
+ // null argument
+ arguments.clear();
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:double-bag Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // argument of other type
+ arguments.clear();
+ arguments.add(attrInteger);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:double-bag Expected data type 'double' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // 2 args (check response is correct)
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(2, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s2, attrValueObject.getValue());
+
+ // duplicate args (verify return)
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr2);
+ arguments.add(attr1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(3, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s2, attrValueObject.getValue());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId());
+ assertEquals(s1, attrValueObject.getValue());
+
+ // lots of args
+ arguments.clear();
+ for (int i = 0; i < 1000; i++) {
+ arguments.add(attr1);
+ }
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(1000, bag.size());
+
+ }
+
+
+
+
+
+ //
+ //
+ // REST OF DATA TYPES OMITTED
+ // because they "should" all work the same
+ //
+ //
+
+
+
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBaseTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBaseTest.java
new file mode 100755
index 0000000..0a967f5
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionBaseTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
+import com.att.research.xacmlatt.pdp.std.StdFunctions;
+
+/**
+ * Test functions in the abstract FunctionDefinitionSimpleTest class.
+ * Functions are tested by creating instances of other classes that should have appropriate properties to verify all variations of the responses expected.
+ *
+ * Note: we do not test getDataTypeId() because all it does is get the String out of the Identity object and we assume that the Data Type Identity objects
+ * are tested enough in everything else that any errors in them will be found and fixed quickly.
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionBaseTest {
+ /**
+ * getId() is pretty trivial, so verifying one should be enough to check that the mechanism is working ok
+ */
+ @Test
+ public void testGetId() {
+ FunctionDefinition fd = StdFunctions.FD_STRING_EQUAL;
+ Identifier id = fd.getId();
+ assertTrue(XACML3.ID_FUNCTION_STRING_EQUAL.stringValue().equals(id.stringValue()) );
+ }
+
+ /**
+ * check an instance of every result type that we can deal with
+ */
+ @Test
+ public void testGetDataType() {
+
+//?? Need functions that return each of these data types except for Boolean which is returned by any of the EQUAL functions
+ FunctionDefinition fdstring = StdFunctions.FD_STRING_NORMALIZE_SPACE;
+ assertEquals(XACML3.ID_DATATYPE_STRING, fdstring.getDataTypeId());
+
+ FunctionDefinition fdboolean = StdFunctions.FD_STRING_EQUAL;
+ assertEquals(XACML3.ID_DATATYPE_BOOLEAN, fdboolean.getDataTypeId());
+
+ FunctionDefinition fdinteger = StdFunctions.FD_INTEGER_ADD;
+ assertEquals(XACML3.ID_DATATYPE_INTEGER, fdinteger.getDataTypeId());
+
+ FunctionDefinition fddouble = StdFunctions.FD_DOUBLE_ADD;
+ assertEquals(XACML3.ID_DATATYPE_DOUBLE, fddouble.getDataTypeId());
+
+ FunctionDefinition fddate = StdFunctions.FD_DATE_BAG;
+ assertEquals(XACML3.ID_DATATYPE_DATE, fddate.getDataTypeId());
+
+ FunctionDefinition fdtime = StdFunctions.FD_TIME_BAG;
+ assertEquals(XACML3.ID_DATATYPE_TIME, fdtime.getDataTypeId());
+
+ FunctionDefinition fddateTime = StdFunctions.FD_DATETIME_BAG;
+ assertEquals(XACML3.ID_DATATYPE_DATETIME, fddateTime.getDataTypeId());
+
+ FunctionDefinition fddayTimeDuration = StdFunctions.FD_DAYTIMEDURATION_FROM_STRING;
+ assertEquals(XACML3.ID_DATATYPE_DAYTIMEDURATION, fddayTimeDuration.getDataTypeId());
+
+ FunctionDefinition fdyearMonthDuration = StdFunctions.FD_YEARMONTHDURATION_FROM_STRING;
+ assertEquals(XACML3.ID_DATATYPE_YEARMONTHDURATION, fdyearMonthDuration.getDataTypeId());
+
+ FunctionDefinition fdanyURI = StdFunctions.FD_ANYURI_FROM_STRING;
+ assertEquals(XACML3.ID_DATATYPE_ANYURI, fdanyURI.getDataTypeId());
+
+ FunctionDefinition fdhexBinary = StdFunctions.FD_HEXBINARY_UNION;
+ assertEquals(XACML3.ID_DATATYPE_HEXBINARY, fdhexBinary.getDataTypeId());
+
+ FunctionDefinition fdbase64Binary = StdFunctions.FD_BASE64BINARY_UNION;
+ assertEquals(XACML3.ID_DATATYPE_BASE64BINARY, fdbase64Binary.getDataTypeId());
+
+ FunctionDefinition fdrfc822Name = StdFunctions.FD_RFC822NAME_FROM_STRING;
+ assertEquals(XACML3.ID_DATATYPE_RFC822NAME, fdrfc822Name.getDataTypeId());
+
+ FunctionDefinition fdx500Name = StdFunctions.FD_X500NAME_FROM_STRING;
+ assertEquals(XACML3.ID_DATATYPE_X500NAME, fdx500Name.getDataTypeId());
+
+//TODO - There are currently no functions that return XPathExpression objects
+// FunctionDefinition fdxpathExpression = StdFunctions.FD_XPATHEXPRESSION_FROM_STRING;
+// assertEquals(XACML3.ID_DATATYPE_XPATHEXPRESSION, fdxpathExpression.getDataTypeId());
+
+ FunctionDefinition fdipAddress = StdFunctions.FD_IPADDRESS_FROM_STRING;
+ assertEquals(XACML3.ID_DATATYPE_IPADDRESS, fdipAddress.getDataTypeId());
+
+ FunctionDefinition fddnsName = StdFunctions.FD_DNSNAME_FROM_STRING;
+ assertEquals(XACML3.ID_DATATYPE_DNSNAME, fddnsName.getDataTypeId());
+ }
+
+ /**
+ * check the type of return, single vs multiple values
+ */
+ @Test
+ public void testReturnsBag() {
+ FunctionDefinition fdNotBag = StdFunctions.FD_BOOLEAN_EQUAL;
+ assertFalse(fdNotBag.returnsBag());
+
+ FunctionDefinitionBag<?> fdBag = (FunctionDefinitionBag<?>) StdFunctions.FD_STRING_BAG;
+ assertTrue(fdBag.returnsBag());
+ }
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparisonTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparisonTest.java
new file mode 100755
index 0000000..a93bf14
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionComparisonTest.java
@@ -0,0 +1,1356 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacml.std.datatypes.ISO8601Date;
+import com.att.research.xacml.std.datatypes.ISO8601DateTime;
+import com.att.research.xacml.std.datatypes.ISO8601Time;
+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.std.StdFunctions;
+
+/**
+ * Test FunctionDefinitionComparison
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionComparisonTest {
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+ FunctionArgumentAttributeValue stringAttr1 = null;
+ FunctionArgumentAttributeValue stringAttr1a = null;
+ FunctionArgumentAttributeValue stringAttr2 = null;
+ FunctionArgumentAttributeValue stringAttrNeg1 = null;
+
+
+ FunctionArgumentAttributeValue intAttr1 = null;
+ FunctionArgumentAttributeValue intAttr1a = null;
+ FunctionArgumentAttributeValue intAttr2 = null;
+ FunctionArgumentAttributeValue intAttr0 = null;
+ FunctionArgumentAttributeValue intAttrNeg1 = null;
+
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr1a = null;
+ FunctionArgumentAttributeValue attr2 = null;
+ FunctionArgumentAttributeValue attrNeg1 = null;
+
+ FunctionArgumentAttributeValue attrDateToday = null;
+ FunctionArgumentAttributeValue attrDateSameDay = null;
+ FunctionArgumentAttributeValue attrDateTommorrow = null;
+ FunctionArgumentAttributeValue attrDateYesterday = null;
+ FunctionArgumentAttributeValue attrDateWithTimeZone = null;
+ FunctionArgumentAttributeValue attrDateNoTimeZone = null;
+
+
+ FunctionArgumentAttributeValue attrTimeToday = null;
+ FunctionArgumentAttributeValue attrTimeSameDay = null;
+ FunctionArgumentAttributeValue attrTimeTommorrow = null;
+ FunctionArgumentAttributeValue attrTimeYesterday = null;
+ FunctionArgumentAttributeValue attrTimeWithTimeZone = null;
+ FunctionArgumentAttributeValue attrTimeNoTimeZone = null;
+
+ FunctionArgumentAttributeValue attrDateTimeToday = null;
+ FunctionArgumentAttributeValue attrDateTimeSameDay = null;
+ FunctionArgumentAttributeValue attrDateTimeTommorrow = null;
+ FunctionArgumentAttributeValue attrDateTimeYesterday = null;
+ FunctionArgumentAttributeValue attrDateTimeWithTimeZone = null;
+ FunctionArgumentAttributeValue attrDateTimeNoTimeZone = null;
+
+ /**
+ * Set up some common variables on startup
+ */
+ public FunctionDefinitionComparisonTest() {
+ try {
+ stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc"));
+ stringAttr1a = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc"));
+ stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def"));
+ stringAttrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("AAA"));
+
+
+ intAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));
+ intAttr1a = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));
+ intAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2));
+ intAttr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));
+ intAttrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1));
+
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0));
+ attr1a = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.4));
+ attrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-1.0));
+
+ // create dates
+ Calendar calendar = Calendar.getInstance();
+ Date today = calendar.getTime();
+ Date longAgo = new Date(1234);
+ // create a date that is different than "today" but within the same day (i.e. has a different hour)
+ if (calendar.get(Calendar.HOUR_OF_DAY) > 3) {
+ calendar.set(Calendar.HOUR_OF_DAY, 3);
+ } else {
+ calendar.set(Calendar.HOUR_OF_DAY, 5);
+ }
+ Date todayPlus = calendar.getTime();
+ calendar.add(Calendar.DATE, 1);
+ Date tommorrow = calendar.getTime();
+ attrDateToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(today));
+ attrDateSameDay = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(todayPlus));
+ attrDateTommorrow = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(tommorrow));
+ attrDateYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(longAgo));
+ ISO8601Date isoDate = new ISO8601Date(1920, 5, 8);
+ attrDateNoTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(isoDate));
+ isoDate = new ISO8601Date("GMT+00:02", 1920, 5, 8);
+ attrDateWithTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(isoDate));
+
+ // create Times
+ ISO8601Time isoTime = new ISO8601Time(14, 43, 12, 145);
+ attrTimeToday = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime));
+ attrTimeSameDay = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime));
+ isoTime = new ISO8601Time(18, 53, 34, 423);
+ attrTimeTommorrow = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime));
+ isoTime = new ISO8601Time(7, 34, 6,543);
+ attrTimeYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime));
+ isoTime = new ISO8601Time(12, 12, 12, 12);
+ attrTimeNoTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime));
+ isoTime = new ISO8601Time("GMT:+00:03", 12, 12, 12, 12);
+ attrTimeWithTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime));
+
+ // create DateTimes
+ isoDate = new ISO8601Date(1920, 5, 8);
+ isoTime = new ISO8601Time( 18, 53, 34, 423);
+ ISO8601DateTime isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 18, 53, 34, 423);
+ attrDateTimeToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime));
+ attrDateTimeSameDay = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime));
+ isoTime = new ISO8601Time(20, 53, 34, 423);
+ isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 20, 53, 34, 423);
+ attrDateTimeTommorrow = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime));
+ isoTime = new ISO8601Time(7, 34, 6,543);
+ isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 7, 34, 6, 543);
+ attrDateTimeYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime));
+ isoTime = new ISO8601Time(12, 12, 12, 12);
+ isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 12, 12, 12, 12);
+ attrDateTimeNoTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime));
+ isoTime = new ISO8601Time("GMT:+00:03", 12, 12, 12, 12);
+ isoDate = new ISO8601Date("GMT:+00:03", 1920, 5, 8);
+ isoDateTime = new ISO8601DateTime("GMT:+00:03", 1920, 5, 8, 12, 12, 12, 12);
+ attrDateTimeWithTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime));
+
+
+
+
+ } catch (Exception e) {
+ fail("Error creating values e="+ e);
+ }
+ }
+
+ /**
+ * String
+ */
+ @Test
+ public void testString_GT() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_GREATER_THAN;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_GREATER_THAN, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(stringAttr1);
+ arguments.add(stringAttr1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // check first < second
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(stringAttr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(stringAttrNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(intAttr1);
+ arguments.add(stringAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ }
+
+ @Test
+ public void testString_GTE() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_GREATER_THAN_OR_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_GREATER_THAN_OR_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(stringAttr1);
+ arguments.add(stringAttr1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check first < second
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(stringAttr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(stringAttrNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+ }
+
+ @Test
+ public void testString_LT() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_LESS_THAN;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_LESS_THAN, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(stringAttr1);
+ arguments.add(stringAttr1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // check first < second
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(stringAttr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(stringAttrNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+ }
+
+ @Test
+ public void testString_LTE() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_LESS_THAN_OR_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_LESS_THAN_OR_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(stringAttr1);
+ arguments.add(stringAttr1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check first < second
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(stringAttr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(stringAttrNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+ }
+
+
+
+ /**
+ * Integer
+ */
+ @Test
+ public void testInteger_GT() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_GREATER_THAN;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(intAttr1);
+ arguments.add(intAttr1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // check first < second
+ arguments.clear();
+ arguments.add(intAttr1);
+ arguments.add(intAttr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(intAttr1);
+ arguments.add(intAttrNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ }
+
+ @Test
+ public void testInteger_GTE() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_GREATER_THAN_OR_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(intAttr1);
+ arguments.add(intAttr1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check first < second
+ arguments.clear();
+ arguments.add(intAttr1);
+ arguments.add(intAttr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(intAttr1);
+ arguments.add(intAttrNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+ }
+
+ @Test
+ public void testInteger_LT() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_LESS_THAN;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_INTEGER_LESS_THAN, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(intAttr1);
+ arguments.add(intAttr1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // check first < second
+ arguments.clear();
+ arguments.add(intAttr1);
+ arguments.add(intAttr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(intAttr1);
+ arguments.add(intAttrNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+ }
+
+ @Test
+ public void testInteger_LTE() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_LESS_THAN_OR_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_INTEGER_LESS_THAN_OR_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(intAttr1);
+ arguments.add(intAttr1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check first < second
+ arguments.clear();
+ arguments.add(intAttr1);
+ arguments.add(intAttr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(intAttr1);
+ arguments.add(intAttrNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+ }
+
+
+
+
+ /**
+ * Double
+ */
+ @Test
+ public void testDouble_GT() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_GREATER_THAN;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN, fd.getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attr1);
+ arguments.add(attr1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attrNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+ @Test
+ public void testDouble_GTE() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_GREATER_THAN_OR_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN_OR_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attr1);
+ arguments.add(attr1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attrNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+ }
+
+ @Test
+ public void testDouble_LT() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_LESS_THAN;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DOUBLE_LESS_THAN, fd.getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attr1);
+ arguments.add(attr1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attrNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+ }
+
+ @Test
+ public void testDouble_LTE() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_LESS_THAN_OR_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DOUBLE_LESS_THAN_OR_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attr1);
+ arguments.add(attr1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attrNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+ }
+
+
+
+ /**
+ * Date
+ */
+
+ @Test
+ public void testDate_GT() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_GREATER_THAN;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATE_GREATER_THAN, fd.getId());
+ assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attrDateToday);
+ arguments.add(attrDateSameDay);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attrDateToday);
+ arguments.add(attrDateTommorrow);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attrDateToday);
+ arguments.add(attrDateYesterday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // test bad args data types? One with TimeZone and one without
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ // test with TimeZone vs without
+ arguments.clear();
+ arguments.add(attrDateWithTimeZone);
+ arguments.add(attrDateNoTimeZone);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-greater-than Cannot compare this ISO8601DateTime with non-time-zoned ISO8601DateTime", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ }
+
+ @Test
+ public void testDate_GTE() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_GREATER_THAN_OR_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATE_GREATER_THAN_OR_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attrDateToday);
+ arguments.add(attrDateSameDay);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attrDateToday);
+ arguments.add(attrDateTommorrow);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attrDateToday);
+ arguments.add(attrDateYesterday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+ }
+
+ @Test
+ public void testDate_LT() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_LESS_THAN;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATE_LESS_THAN, fd.getId());
+ assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attrDateToday);
+ arguments.add(attrDateSameDay);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attrDateToday);
+ arguments.add(attrDateTommorrow);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attrDateToday);
+ arguments.add(attrDateYesterday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+ }
+
+ @Test
+ public void testDate_LTE() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_LESS_THAN_OR_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATE_LESS_THAN_OR_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attrDateToday);
+ arguments.add(attrDateSameDay);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attrDateToday);
+ arguments.add(attrDateTommorrow);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attrDateToday);
+ arguments.add(attrDateYesterday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+ }
+
+
+
+
+
+
+
+ /**
+ * Time
+ */
+
+ @Test
+ public void testTime_GT() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_GREATER_THAN;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_TIME_GREATER_THAN, fd.getId());
+ assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attrTimeToday);
+ arguments.add(attrTimeSameDay);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attrTimeToday);
+ arguments.add(attrTimeTommorrow);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attrTimeToday);
+ arguments.add(attrTimeYesterday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // test bad args data types? One with TimeZone and one without
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ // test with TimeZone vs without
+ arguments.clear();
+ arguments.add(attrTimeWithTimeZone);
+ arguments.add(attrTimeNoTimeZone);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:time-greater-than Cannot compare this ISO8601DateTime with non-time-zoned ISO8601DateTime", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ }
+
+ @Test
+ public void testTime_GTE() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_GREATER_THAN_OR_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_TIME_GREATER_THAN_OR_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attrTimeToday);
+ arguments.add(attrTimeSameDay);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attrTimeToday);
+ arguments.add(attrTimeTommorrow);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attrTimeToday);
+ arguments.add(attrTimeYesterday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+ }
+
+ @Test
+ public void testTime_LT() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_LESS_THAN;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_TIME_LESS_THAN, fd.getId());
+ assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attrTimeToday);
+ arguments.add(attrTimeSameDay);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attrTimeToday);
+ arguments.add(attrTimeTommorrow);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attrTimeToday);
+ arguments.add(attrTimeYesterday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+ }
+
+ @Test
+ public void testTime_LTE() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_LESS_THAN_OR_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_TIME_LESS_THAN_OR_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attrTimeToday);
+ arguments.add(attrTimeSameDay);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attrTimeToday);
+ arguments.add(attrTimeTommorrow);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attrTimeToday);
+ arguments.add(attrTimeYesterday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+ }
+
+
+
+
+
+ /**
+ * Time-in-range
+ */
+ @Test
+ public void testTime_in_range() {
+
+ FunctionDefinitionTimeInRange<?> fd = (FunctionDefinitionTimeInRange<?>) StdFunctions.FD_TIME_IN_RANGE;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_TIME_IN_RANGE, fd.getId());
+ assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(3), fd.getNumArgs());
+
+ // arg 0 in range of others
+ arguments.add(attrTimeToday);
+ arguments.add(attrTimeYesterday);
+ arguments.add(attrTimeTommorrow);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // below range
+ arguments.clear();
+ arguments.add(attrTimeYesterday);
+ arguments.add(attrTimeToday);
+ arguments.add(attrTimeTommorrow);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // above range
+ arguments.clear();
+ arguments.add(attrTimeTommorrow);
+ arguments.add(attrTimeYesterday);
+ arguments.add(attrTimeToday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // range bad
+ arguments.clear();
+ arguments.add(attrTimeToday);
+ arguments.add(attrTimeTommorrow);
+ arguments.add(attrTimeYesterday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // bad types
+ arguments.clear();
+ arguments.add(attrDateTimeWithTimeZone);
+ arguments.add(attrDateTimeNoTimeZone);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:time-in-range Expected 3 arguments, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrDateTimeWithTimeZone);
+ arguments.add(attrDateTimeNoTimeZone);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:time-in-range Expected data type 'time' saw 'dateTime' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+
+
+ /**
+ * DateTime
+ */
+
+ @Test
+ public void testDateTime_GT() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_GREATER_THAN;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATETIME_GREATER_THAN, fd.getId());
+ assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attrDateTimeToday);
+ arguments.add(attrDateTimeSameDay);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attrDateTimeToday);
+ arguments.add(attrDateTimeTommorrow);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attrDateTimeToday);
+ arguments.add(attrDateTimeYesterday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // test bad args data types? One with TimeZone and one without
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ // test with TimeZone vs without
+ arguments.clear();
+ arguments.add(attrDateTimeWithTimeZone);
+ arguments.add(attrDateTimeNoTimeZone);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-greater-than Cannot compare this ISO8601DateTime with non-time-zoned ISO8601DateTime", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ }
+
+ @Test
+ public void testDateTime_GTE() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_GREATER_THAN_OR_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATETIME_GREATER_THAN_OR_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attrDateTimeToday);
+ arguments.add(attrDateTimeSameDay);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attrDateTimeToday);
+ arguments.add(attrDateTimeTommorrow);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attrDateTimeToday);
+ arguments.add(attrDateTimeYesterday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+ }
+
+ @Test
+ public void testDateTime_LT() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_LESS_THAN;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATETIME_LESS_THAN, fd.getId());
+ assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attrDateTimeToday);
+ arguments.add(attrDateTimeSameDay);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attrDateTimeToday);
+ arguments.add(attrDateTimeTommorrow);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attrDateTimeToday);
+ arguments.add(attrDateTimeYesterday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+ }
+
+ @Test
+ public void testDateTime_LTE() {
+
+ FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_LESS_THAN_OR_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATETIME_LESS_THAN_OR_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // first == second
+ arguments.add(attrDateTimeToday);
+ arguments.add(attrDateTimeSameDay);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first < second
+ arguments.clear();
+ arguments.add(attrDateTimeToday);
+ arguments.add(attrDateTimeTommorrow);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first > second
+ arguments.clear();
+ arguments.add(attrDateTimeToday);
+ arguments.add(attrDateTimeYesterday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmeticTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmeticTest.java
new file mode 100755
index 0000000..d502375
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionDateTimeArithmeticTest.java
@@ -0,0 +1,1582 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacml.std.datatypes.ISO8601Date;
+import com.att.research.xacml.std.datatypes.ISO8601DateTime;
+import com.att.research.xacml.std.datatypes.ISO8601Time;
+import com.att.research.xacml.std.datatypes.ISO8601TimeZone;
+import com.att.research.xacml.std.datatypes.XPathDayTimeDuration;
+import com.att.research.xacml.std.datatypes.XPathYearMonthDuration;
+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.std.StdFunctions;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionDateTimeArithmeticTest {
+
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+ ExpressionResult res;
+
+
+ @Test
+ public void testDateTime_add_dayTimeDuration() {
+ // Date objects to be adjusted
+ ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null,
+ new ISO8601Date(2000, 1, 12),
+ new ISO8601Time(12, 13, 14, 0));
+ ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null,
+ new ISO8601Date(2000, 1, 12),
+ new ISO8601Time(12, 13, 14, 777));
+ ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null,
+ new ISO8601Date(2000, 12, 31),
+ new ISO8601Time(23, 59, 30, 1));
+ ISO8601DateTime dateTimeBC = new ISO8601DateTime(null,
+ new ISO8601Date(-2000, 1, 12),
+ new ISO8601Time(12, 13, 14, 0));
+ ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);
+ ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);
+ ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0,
+ new ISO8601Date(timeZone0, 2000, 1, 12),
+ new ISO8601Time(timeZone0, 12, 13, 14, 0));
+ ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5,
+ new ISO8601Date(timeZone5, 2000, 1, 12),
+ new ISO8601Time(timeZone5, 12, 13, 14, 0));
+ ISO8601DateTime dateTimeIIC102Result = null;
+
+ // Durations
+ XPathDayTimeDuration duration0 = new XPathDayTimeDuration(1, 0, 0, 0, 0);
+ XPathDayTimeDuration durationStdExample1 = new XPathDayTimeDuration(1, 5, 7, 10, 3.3);
+ XPathDayTimeDuration durationNStdExample1 = new XPathDayTimeDuration(-1, 5, 7, 10, 3.3);
+ XPathDayTimeDuration durationMsecs = new XPathDayTimeDuration(1, 5, 7, 10, 3.223);
+ XPathDayTimeDuration durationCrossover = new XPathDayTimeDuration(1, 0, 0, 0, 29.999);
+
+ // ARGS declarations
+ // Dates
+ FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;
+ FunctionArgumentAttributeValue attrDateTimeMsecs = null;
+ FunctionArgumentAttributeValue attrDateTimeCrossover = null;
+ FunctionArgumentAttributeValue attrDateTimeBC = null;
+ FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;
+ FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;
+ FunctionArgumentAttributeValue attrDateTimeIIC102 = null;
+
+ // Durations
+ FunctionArgumentAttributeValue attrDuration0 = null;
+ FunctionArgumentAttributeValue attrDurationStdExample1 = null;
+ FunctionArgumentAttributeValue attrDurationNStdExample1 = null;
+ FunctionArgumentAttributeValue attrDurationMsecs = null;
+ FunctionArgumentAttributeValue attrDurationCrossover = null;
+ FunctionArgumentAttributeValue attrDurationIIC102 = null;
+
+ // misc bad
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrBlank = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ // set values
+ try {
+ // Date attrs
+ attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1));
+ attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs));
+ attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover));
+ attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC));
+ attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0));
+ attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5));
+ attrDateTimeIIC102 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(DataTypes.DT_DATETIME.convert("2002-03-22T08:23:47-05:00")));
+
+ dateTimeIIC102Result = DataTypes.DT_DATETIME.convert("2002-03-27T10:23:47-05:00");
+
+ // Duration attrs
+ attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(duration0));
+ attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationStdExample1));
+ attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationNStdExample1));
+ attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationMsecs));
+ attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationCrossover));
+ attrDurationIIC102 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue("P5DT2H0M0S"));
+
+ // misc bad
+ attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(""));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(null));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_ADD_DAYTIMEDURATION;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATETIME_ADD_DAYTIMEDURATION, fd.getId());
+ assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+ // Duration = 0 => same as original
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDuration0);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue();
+ assertEquals(dateTimeStdExample1, resValue);
+
+
+ // simple positive operation
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ ISO8601DateTime testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(2000, 1, 17),
+ new ISO8601Time(19, 23, 17, 300) );
+ assertEquals(testResponse, resValue);
+
+ // negative operation
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDurationNStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(2000, 1, 7),
+ new ISO8601Time(5, 3, 10, 700) );
+ assertEquals(testResponse, resValue);
+
+ // millisecs work correctly
+ arguments.clear();
+ arguments.add(attrDateTimeMsecs);
+ arguments.add(attrDurationMsecs);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(2000, 1, 17),
+ new ISO8601Time(19, 23, 18, 0) );
+ assertEquals(testResponse, resValue);
+
+ // cross minute => cross day => cross month => cross year
+ arguments.clear();
+ arguments.add(attrDateTimeCrossover);
+ arguments.add(attrDurationCrossover);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(2001, 1, 1),
+ new ISO8601Time(0, 0, 0, 0) );
+ assertEquals(testResponse, resValue);
+
+ // negative (BC) original date add goes the right direction
+ arguments.clear();
+ arguments.add(attrDateTimeBC);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(-2000, 1, 17),
+ new ISO8601Time(19, 23, 17, 300) );
+ assertEquals(testResponse, resValue);
+
+ // non-null timezone not changed
+ // original has timezone offset = 0
+ arguments.clear();
+ arguments.add(attrDateTimeTimeZone0);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ timeZone0,
+ new ISO8601Date(timeZone0, 2000, 1, 17),
+ new ISO8601Time(timeZone0, 19, 23, 17, 300) );
+ assertEquals(testResponse, resValue);
+
+ // original has timezone offset not 0
+ arguments.clear();
+ arguments.add(attrDateTimeTimeZone5);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ timeZone5,
+ new ISO8601Date(timeZone5, 2000, 1, 17),
+ new ISO8601Time(timeZone5, 19, 23, 17, 300) );
+ assertEquals(testResponse, resValue);
+
+ // conformance test IIC102
+ arguments.clear();
+ arguments.add(attrDateTimeIIC102);
+ arguments.add(attrDurationIIC102);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ assertEquals(dateTimeIIC102Result, resValue);
+
+ // empty non-null first arg
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // empty non-null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // two blanks
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null firat arg
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrInteger);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-add-dayTimeDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+ @Test
+ public void testDateTime_subtract_dayTimeDuration() {
+ // Date objects to be adjusted
+ ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null,
+ new ISO8601Date(2000, 1, 12),
+ new ISO8601Time(12, 13, 14, 0));
+ ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null,
+ new ISO8601Date(2000, 1, 12),
+ new ISO8601Time(12, 13, 14, 777));
+ ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null,
+ new ISO8601Date(2001, 1, 1),
+ new ISO8601Time(0, 0, 0, 0) );
+ ISO8601DateTime dateTimeBC = new ISO8601DateTime(null,
+ new ISO8601Date(-2000, 1, 12),
+ new ISO8601Time(12, 13, 14, 0));
+ ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);
+ ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);
+ ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0,
+ new ISO8601Date(timeZone0, 2000, 1, 12),
+ new ISO8601Time(timeZone0, 12, 13, 14, 0));
+ ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5,
+ new ISO8601Date(timeZone5, 2000, 1, 12),
+ new ISO8601Time(timeZone5, 12, 13, 14, 0));
+
+ // Durations
+ XPathDayTimeDuration duration0 = new XPathDayTimeDuration(1, 0, 0, 0, 0);
+ XPathDayTimeDuration durationStdExample1 = new XPathDayTimeDuration(1, 5, 7, 10, 3.3);
+ XPathDayTimeDuration durationNStdExample1 = new XPathDayTimeDuration(-1, 5, 7, 10, 3.3);
+ XPathDayTimeDuration durationMsecs = new XPathDayTimeDuration(1, 5, 7, 10, 14.778);
+ XPathDayTimeDuration durationCrossover = new XPathDayTimeDuration(1, 0, 0, 0, 29.999);
+
+ // ARGS declarations
+ // Dates
+ FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;
+ FunctionArgumentAttributeValue attrDateTimeMsecs = null;
+ FunctionArgumentAttributeValue attrDateTimeCrossover = null;
+ FunctionArgumentAttributeValue attrDateTimeBC = null;
+ FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;
+ FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;
+
+ // Durations
+ FunctionArgumentAttributeValue attrDuration0 = null;
+ FunctionArgumentAttributeValue attrDurationStdExample1 = null;
+ FunctionArgumentAttributeValue attrDurationNStdExample1 = null;
+ FunctionArgumentAttributeValue attrDurationMsecs = null;
+ FunctionArgumentAttributeValue attrDurationCrossover = null;
+
+ // misc bad
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrBlank = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ // set values
+ try {
+ // Date attrs
+ attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1));
+ attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs));
+ attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover));
+ attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC));
+ attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0));
+ attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5));
+
+ // Duration attrs
+ attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(duration0));
+ attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationStdExample1));
+ attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationNStdExample1));
+ attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationMsecs));
+ attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationCrossover));
+
+ // misc bad
+ attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(""));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(null));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_SUBTRACT_DAYTIMEDURATION;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_DAYTIMEDURATION, fd.getId());
+ assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+ // Duration = 0 => same as original
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDuration0);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue();
+ assertEquals(dateTimeStdExample1, resValue);
+
+
+ // simple positive operation
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ ISO8601DateTime testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(2000, 1, 7),
+ new ISO8601Time(5, 3, 10, 700) );
+ assertEquals(testResponse, resValue);
+
+
+ // negative operation
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDurationNStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(2000, 1, 17),
+ new ISO8601Time(19, 23, 17, 300) );
+ assertEquals(testResponse, resValue);
+
+ // millisecs work correctly
+ arguments.clear();
+ arguments.add(attrDateTimeMsecs);
+ arguments.add(attrDurationMsecs);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(2000, 1, 7),
+ new ISO8601Time(5, 2, 59, 999) );
+ assertEquals(testResponse, resValue);
+
+ // cross minute => cross day => cross month => cross year
+ arguments.clear();
+ arguments.add(attrDateTimeCrossover);
+ arguments.add(attrDurationCrossover);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(2000, 12, 31),
+ new ISO8601Time(23, 59, 30, 1));
+ assertEquals(testResponse, resValue);
+
+ // negative (BC) original date add goes the right direction
+ arguments.clear();
+ arguments.add(attrDateTimeBC);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(-2000, 1, 7),
+ new ISO8601Time(5, 3, 10, 700) );
+ assertEquals(testResponse, resValue);
+
+ // non-null timezone not changed
+ // original has timezone offset = 0
+ arguments.clear();
+ arguments.add(attrDateTimeTimeZone0);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ timeZone0,
+ new ISO8601Date(timeZone0, 2000, 1, 7),
+ new ISO8601Time(timeZone0, 5, 3, 10, 700) );
+ assertEquals(testResponse, resValue);
+
+ // original has timezone offset not 0
+ arguments.clear();
+ arguments.add(attrDateTimeTimeZone5);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ timeZone5,
+ new ISO8601Date(timeZone5, 2000, 1, 7),
+ new ISO8601Time(timeZone5, 5, 3, 10, 700) );
+ assertEquals(testResponse, resValue);
+
+ // empty non-null first arg
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // empty non-null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // two blanks
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null firat arg
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrInteger);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-subtract-dayTimeDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+
+
+
+
+
+
+ @Test
+ public void testDateTime_add_yearMonthDuration() {
+ // Date objects to be adjusted
+ ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null,
+ new ISO8601Date(2000, 1, 12),
+ new ISO8601Time(12, 13, 14, 0));
+ ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null,
+ new ISO8601Date(2000, 1, 12),
+ new ISO8601Time(12, 13, 14, 777));
+ ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null,
+ new ISO8601Date(2000, 12, 31),
+ new ISO8601Time(23, 59, 30, 1));
+ ISO8601DateTime dateTimeBC = new ISO8601DateTime(null,
+ new ISO8601Date(-2000, 1, 12),
+ new ISO8601Time(12, 13, 14, 0));
+ ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);
+ ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);
+ ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0,
+ new ISO8601Date(timeZone0, 2000, 1, 12),
+ new ISO8601Time(timeZone0, 12, 13, 14, 0));
+ ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5,
+ new ISO8601Date(timeZone5, 2000, 1, 12),
+ new ISO8601Time(timeZone5, 12, 13, 14, 0));
+
+ // Durations
+ XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0);
+ XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7);
+ XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7);
+ XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7);
+ XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1);
+
+ // ARGS declarations
+ // Dates
+ FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;
+ FunctionArgumentAttributeValue attrDateTimeMsecs = null;
+ FunctionArgumentAttributeValue attrDateTimeCrossover = null;
+ FunctionArgumentAttributeValue attrDateTimeBC = null;
+ FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;
+ FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;
+
+ // Durations
+ FunctionArgumentAttributeValue attrDuration0 = null;
+ FunctionArgumentAttributeValue attrDurationStdExample1 = null;
+ FunctionArgumentAttributeValue attrDurationNStdExample1 = null;
+ FunctionArgumentAttributeValue attrDurationMsecs = null;
+ FunctionArgumentAttributeValue attrDurationCrossover = null;
+
+ // misc bad
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrBlank = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ // set values
+ try {
+ // Date attrs
+ attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1));
+ attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs));
+ attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover));
+ attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC));
+ attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0));
+ attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5));
+
+ // Duration attrs
+ attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0));
+ attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1));
+ attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1));
+ attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs));
+ attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover));
+
+ // misc bad
+ attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(""));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_ADD_YEARMONTHDURATION;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATETIME_ADD_YEARMONTHDURATION, fd.getId());
+ assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+ // Duration = 0 => same as original
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDuration0);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue();
+ assertEquals(dateTimeStdExample1, resValue);
+
+
+ // simple positive operation
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ ISO8601DateTime testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(2005, 8, 12),
+ new ISO8601Time(12, 13, 14, 0) );
+ assertEquals(testResponse, resValue);
+
+ // negative operation
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDurationNStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(1994, 6, 12),
+ new ISO8601Time(12, 13, 14, 0) );
+ assertEquals(testResponse, resValue);
+
+ // millisecs work correctly (not relevant to YearMonth, but should not break
+ arguments.clear();
+ arguments.add(attrDateTimeMsecs);
+ arguments.add(attrDurationMsecs);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(2005, 8, 12),
+ new ISO8601Time(12, 13, 14, 777) );
+ assertEquals(testResponse, resValue);
+
+ // cross minute => cross day => cross month => cross year
+ arguments.clear();
+ arguments.add(attrDateTimeCrossover);
+ arguments.add(attrDurationCrossover);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(2001, 1, 31),
+ new ISO8601Time(23, 59, 30, 1) );
+ assertEquals(testResponse, resValue);
+
+ // negative (BC) original date add goes the right direction
+ arguments.clear();
+ arguments.add(attrDateTimeBC);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(-1995, 8, 12),
+ new ISO8601Time(12, 13, 14, 0) );
+ assertEquals(testResponse, resValue);
+
+ // non-null timezone not changed
+ // original has timezone offset = 0
+ arguments.clear();
+ arguments.add(attrDateTimeTimeZone0);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ timeZone0,
+ new ISO8601Date(timeZone0, 2005, 8, 12),
+ new ISO8601Time(timeZone0, 12, 13, 14, 0) );
+ assertEquals(testResponse, resValue);
+
+ // original has timezone offset not 0
+ arguments.clear();
+ arguments.add(attrDateTimeTimeZone5);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ timeZone5,
+ new ISO8601Date(timeZone5, 2005, 8, 12),
+ new ISO8601Time(timeZone5, 12, 13, 14, 0) );
+ assertEquals(testResponse, resValue);
+
+ // empty non-null first arg
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // empty non-null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // two blanks
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null firat arg
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrInteger);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-add-yearMonthDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+
+ @Test
+ public void testDateTime_subtract_yearMonthDuration() {
+ // Date objects to be adjusted
+ ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null,
+ new ISO8601Date(2000, 1, 12),
+ new ISO8601Time(12, 13, 14, 0));
+ ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null,
+ new ISO8601Date(2000, 1, 12),
+ new ISO8601Time(12, 13, 14, 777));
+ ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null,
+ new ISO8601Date(2000, 1, 1),
+ new ISO8601Time(23, 59, 30, 1));
+ ISO8601DateTime dateTimeBC = new ISO8601DateTime(null,
+ new ISO8601Date(-2000, 1, 12),
+ new ISO8601Time(12, 13, 14, 0));
+ ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);
+ ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);
+ ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0,
+ new ISO8601Date(timeZone0, 2000, 1, 12),
+ new ISO8601Time(timeZone0, 12, 13, 14, 0));
+ ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5,
+ new ISO8601Date(timeZone5, 2000, 1, 12),
+ new ISO8601Time(timeZone5, 12, 13, 14, 0));
+
+ // Durations
+ XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0);
+ XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7);
+ XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7);
+ XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7);
+ XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1);
+
+ // ARGS declarations
+ // Dates
+ FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;
+ FunctionArgumentAttributeValue attrDateTimeMsecs = null;
+ FunctionArgumentAttributeValue attrDateTimeCrossover = null;
+ FunctionArgumentAttributeValue attrDateTimeBC = null;
+ FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;
+ FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;
+
+ // Durations
+ FunctionArgumentAttributeValue attrDuration0 = null;
+ FunctionArgumentAttributeValue attrDurationStdExample1 = null;
+ FunctionArgumentAttributeValue attrDurationNStdExample1 = null;
+ FunctionArgumentAttributeValue attrDurationMsecs = null;
+ FunctionArgumentAttributeValue attrDurationCrossover = null;
+
+ // misc bad
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrBlank = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ // set values
+ try {
+ // Date attrs
+ attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1));
+ attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs));
+ attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover));
+ attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC));
+ attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0));
+ attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5));
+
+ // Duration attrs
+ attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0));
+ attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1));
+ attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1));
+ attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs));
+ attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover));
+
+ // misc bad
+ attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(""));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_SUBTRACT_YEARMONTHDURATION;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_YEARMONTHDURATION, fd.getId());
+ assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+ // Duration = 0 => same as original
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDuration0);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue();
+ assertEquals(dateTimeStdExample1, resValue);
+
+
+ // simple positive operation
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ ISO8601DateTime testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(1994, 6, 12),
+ new ISO8601Time(12, 13, 14, 0) );
+ assertEquals(testResponse, resValue);
+
+ // negative operation
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDurationNStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(2005, 8, 12),
+ new ISO8601Time(12, 13, 14, 0) );
+ assertEquals(testResponse, resValue);
+
+ // millisecs work correctly (not relevant to YearMonth, but should not break
+ arguments.clear();
+ arguments.add(attrDateTimeMsecs);
+ arguments.add(attrDurationMsecs);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(1994, 6, 12),
+ new ISO8601Time(12, 13, 14, 777) );
+ assertEquals(testResponse, resValue);
+
+ // cross minute => cross day => cross month => cross year
+ arguments.clear();
+ arguments.add(attrDateTimeCrossover);
+ arguments.add(attrDurationCrossover);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(1999, 12, 1),
+ new ISO8601Time(23, 59, 30, 1) );
+ assertEquals(testResponse, resValue);
+
+ // negative (BC) original date add goes the right direction
+ arguments.clear();
+ arguments.add(attrDateTimeBC);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ null,
+ new ISO8601Date(-2006, 6, 12),
+ new ISO8601Time(12, 13, 14, 0) );
+ assertEquals(testResponse, resValue);
+
+ // non-null timezone not changed
+ // original has timezone offset = 0
+ arguments.clear();
+ arguments.add(attrDateTimeTimeZone0);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ timeZone0,
+ new ISO8601Date(timeZone0, 1994, 6, 12),
+ new ISO8601Time(timeZone0, 12, 13, 14, 0) );
+ assertEquals(testResponse, resValue);
+
+ // original has timezone offset not 0
+ arguments.clear();
+ arguments.add(attrDateTimeTimeZone5);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601DateTime.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ testResponse = new ISO8601DateTime(
+ timeZone5,
+ new ISO8601Date(timeZone5, 1994, 6, 12),
+ new ISO8601Time(timeZone5, 12, 13, 14, 0) );
+ assertEquals(testResponse, resValue);
+
+ // empty non-null first arg
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // empty non-null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // two blanks
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null firat arg
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrInteger);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-subtract-yearMonthDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+
+
+
+
+
+
+
+
+ @Test
+ public void testDate_add_yearMonthDuration() {
+ // Date objects to be adjusted
+ ISO8601Date dateTimeStdExample1 = new ISO8601Date(2000, 1, 12);
+ ISO8601Date dateTimeMsecs =new ISO8601Date(2000, 1, 12);
+ ISO8601Date dateTimeCrossover = new ISO8601Date(2000, 12, 31);
+ ISO8601Date dateTimeBC = new ISO8601Date(-2000, 1, 12);
+ ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);
+ ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);
+ ISO8601Date dateTimeTimeZone0 = new ISO8601Date(timeZone0, 2000, 1, 12);
+ ISO8601Date dateTimeTimeZone5 = new ISO8601Date(timeZone5, 2000, 1, 12);
+
+ // Durations
+ XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0);
+ XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7);
+ XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7);
+ XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7);
+ XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1);
+
+ // ARGS declarations
+ // Dates
+ FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;
+ FunctionArgumentAttributeValue attrDateTimeMsecs = null;
+ FunctionArgumentAttributeValue attrDateTimeCrossover = null;
+ FunctionArgumentAttributeValue attrDateTimeBC = null;
+ FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;
+ FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;
+
+ // Durations
+ FunctionArgumentAttributeValue attrDuration0 = null;
+ FunctionArgumentAttributeValue attrDurationStdExample1 = null;
+ FunctionArgumentAttributeValue attrDurationNStdExample1 = null;
+ FunctionArgumentAttributeValue attrDurationMsecs = null;
+ FunctionArgumentAttributeValue attrDurationCrossover = null;
+
+ // misc bad
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrBlank = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ // set values
+ try {
+ // Date attrs
+ attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeStdExample1));
+ attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeMsecs));
+ attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeCrossover));
+ attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeBC));
+ attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone0));
+ attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone5));
+
+ // Duration attrs
+ attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0));
+ attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1));
+ attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1));
+ attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs));
+ attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover));
+
+ // misc bad
+ attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(""));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATE_ADD_YEARMONTHDURATION;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATE_ADD_YEARMONTHDURATION, fd.getId());
+ assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+ // Duration = 0 => same as original
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDuration0);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ ISO8601Date resValue = (ISO8601Date)res.getValue().getValue();
+ assertEquals(dateTimeStdExample1, resValue);
+
+
+ // simple positive operation
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ ISO8601Date testResponse = new ISO8601Date(2005, 8, 12);
+ assertEquals(testResponse, resValue);
+
+ // negative operation
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDurationNStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ testResponse = new ISO8601Date(1994, 6, 12);
+ assertEquals(testResponse, resValue);
+
+ // millisecs work correctly (not relevant to YearMonth, but should not break
+ arguments.clear();
+ arguments.add(attrDateTimeMsecs);
+ arguments.add(attrDurationMsecs);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ testResponse = new ISO8601Date(2005, 8, 12);
+ assertEquals(testResponse, resValue);
+
+ // cross minute => cross day => cross month => cross year
+ arguments.clear();
+ arguments.add(attrDateTimeCrossover);
+ arguments.add(attrDurationCrossover);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ testResponse = new ISO8601Date(2001, 1, 31);
+ assertEquals(testResponse, resValue);
+
+ // negative (BC) original date add goes the right direction
+ arguments.clear();
+ arguments.add(attrDateTimeBC);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ testResponse = new ISO8601Date(-1995, 8, 12);
+ assertEquals(testResponse, resValue);
+
+ // non-null timezone not changed
+ // original has timezone offset = 0
+ arguments.clear();
+ arguments.add(attrDateTimeTimeZone0);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ testResponse = new ISO8601Date(timeZone0, 2005, 8, 12);
+ assertEquals(testResponse, resValue);
+
+ // original has timezone offset not 0
+ arguments.clear();
+ arguments.add(attrDateTimeTimeZone5);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ testResponse = new ISO8601Date(timeZone5, 2005, 8, 12);
+ assertEquals(testResponse, resValue);
+
+ // empty non-null first arg
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // empty non-null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // two blanks
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null firat arg
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrInteger);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-add-yearMonthDuration Expected data type 'date' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+
+
+
+ @Test
+ public void testDate_subtract_yearMonthDuration() {
+ // Date objects to be adjusted
+ ISO8601Date dateTimeStdExample1 =new ISO8601Date(2000, 1, 12);
+ ISO8601Date dateTimeMsecs = new ISO8601Date(2000, 1, 12);
+ ISO8601Date dateTimeCrossover = new ISO8601Date(2000, 1, 1);
+ ISO8601Date dateTimeBC = new ISO8601Date(-2000, 1, 12);
+ ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);
+ ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);
+ ISO8601Date dateTimeTimeZone0 = new ISO8601Date(timeZone0, 2000, 1, 12);
+ ISO8601Date dateTimeTimeZone5 = new ISO8601Date(timeZone5, 2000, 1, 12);
+
+ // Durations
+ XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0);
+ XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7);
+ XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7);
+ XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7);
+ XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1);
+
+ // ARGS declarations
+ // Dates
+ FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;
+ FunctionArgumentAttributeValue attrDateTimeMsecs = null;
+ FunctionArgumentAttributeValue attrDateTimeCrossover = null;
+ FunctionArgumentAttributeValue attrDateTimeBC = null;
+ FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;
+ FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;
+
+ // Durations
+ FunctionArgumentAttributeValue attrDuration0 = null;
+ FunctionArgumentAttributeValue attrDurationStdExample1 = null;
+ FunctionArgumentAttributeValue attrDurationNStdExample1 = null;
+ FunctionArgumentAttributeValue attrDurationMsecs = null;
+ FunctionArgumentAttributeValue attrDurationCrossover = null;
+
+ // misc bad
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrBlank = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ // set values
+ try {
+ // Date attrs
+ attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeStdExample1));
+ attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeMsecs));
+ attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeCrossover));
+ attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeBC));
+ attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone0));
+ attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone5));
+
+ // Duration attrs
+ attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0));
+ attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1));
+ attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1));
+ attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs));
+ attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover));
+
+ // misc bad
+ attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(""));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATE_SUBTRACT_YEARMONTHDURATION;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATE_SUBTRACT_YEARMONTHDURATION, fd.getId());
+ assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+ // Duration = 0 => same as original
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDuration0);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ ISO8601Date resValue = (ISO8601Date)res.getValue().getValue();
+ assertEquals(dateTimeStdExample1, resValue);
+
+
+ // simple positive operation
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ ISO8601Date testResponse = new ISO8601Date(1994, 6, 12);
+ assertEquals(testResponse, resValue);
+
+ // negative operation
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrDurationNStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ testResponse = new ISO8601Date(2005, 8, 12);
+ assertEquals(testResponse, resValue);
+
+ // millisecs work correctly (not relevant to YearMonth, but should not break
+ arguments.clear();
+ arguments.add(attrDateTimeMsecs);
+ arguments.add(attrDurationMsecs);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ testResponse = new ISO8601Date(1994, 6, 12);
+ assertEquals(testResponse, resValue);
+
+ // cross minute => cross day => cross month => cross year
+ arguments.clear();
+ arguments.add(attrDateTimeCrossover);
+ arguments.add(attrDurationCrossover);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ testResponse = new ISO8601Date(1999, 12, 1);
+ assertEquals(testResponse, resValue);
+
+ // negative (BC) original date add goes the right direction
+ arguments.clear();
+ arguments.add(attrDateTimeBC);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ testResponse = new ISO8601Date(-2006, 6, 12);
+ assertEquals(testResponse, resValue);
+
+ // non-null timezone not changed
+ // original has timezone offset = 0
+ arguments.clear();
+ arguments.add(attrDateTimeTimeZone0);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ testResponse = new ISO8601Date(timeZone0, 1994, 6, 12);
+ assertEquals(testResponse, resValue);
+
+ // original has timezone offset not 0
+ arguments.clear();
+ arguments.add(attrDateTimeTimeZone5);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(ISO8601Date.class, res.getValue().getValue().getClass());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ testResponse = new ISO8601Date(timeZone5, 1994, 6, 12);
+ assertEquals(testResponse, resValue);
+
+ // empty non-null first arg
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // empty non-null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // two blanks
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null firat arg
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrInteger);
+ arguments.add(attrDurationStdExample1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-subtract-yearMonthDuration Expected data type 'date' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrDateTimeStdExample1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEqualityTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEqualityTest.java
new file mode 100755
index 0000000..d092f60
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionEqualityTest.java
@@ -0,0 +1,1182 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML1;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.Base64Binary;
+import com.att.research.xacml.std.datatypes.DataTypeRFC822Name;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacml.std.datatypes.HexBinary;
+import com.att.research.xacml.std.datatypes.RFC822Name;
+import com.att.research.xacml.std.datatypes.XPathDayTimeDuration;
+import com.att.research.xacml.std.datatypes.XPathYearMonthDuration;
+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.std.StdFunctions;
+
+/**
+ * Test FunctionDefinitionEquality, all of its super-classes, and all XACML functions supported by that class.
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * 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
+ *
+ * Each of these is put into a separate test method just to keep things organized.
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionEqualityTest {
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+ FunctionArgumentAttributeValue stringAttr1 = null;
+ FunctionArgumentAttributeValue stringAttr2 = null;
+ FunctionArgumentAttributeValue stringAttr3 = null;
+ FunctionArgumentAttributeValue stringAttr4 = null;
+
+ FunctionArgumentAttributeValue booleanAttrT1 = null;
+ FunctionArgumentAttributeValue booleanAttrT2 = null;
+ FunctionArgumentAttributeValue booleanAttrF1 = null;
+ FunctionArgumentAttributeValue booleanAttrF2 = null;
+
+ FunctionArgumentAttributeValue intAttr1 = null;
+ FunctionArgumentAttributeValue intAttr1a = null;
+ FunctionArgumentAttributeValue intAttr2 = null;
+ FunctionArgumentAttributeValue intAttr0 = null;
+ FunctionArgumentAttributeValue intAttrNeg1 = null;
+
+ public FunctionDefinitionEqualityTest() {
+ try {
+ stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc"));
+ stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc"));
+ stringAttr3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ABC"));
+ stringAttr4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def"));
+
+ booleanAttrT1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(true));
+ booleanAttrT2 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(true));
+ booleanAttrF1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+ booleanAttrF2 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+
+ intAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));
+ intAttr1a = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));
+ intAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2));
+ intAttr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));
+ intAttrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+ }
+
+
+
+
+ /**
+ * String (matching case)
+ */
+ @Test
+ public void testString_Equal() {
+
+ // String exact match
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_STRING_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check "abc" with "abc" - separate string objects with same value
+ arguments.add(stringAttr1);
+ arguments.add(stringAttr2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check "abc" with "ABC" (not same)
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(stringAttr3);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+
+
+ /**
+ * Boolean
+ */
+ @Test
+ public void testBoolean_Equal() {
+
+ // String exact match
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_BOOLEAN_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_BOOLEAN_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check separate objects with same value
+ arguments.add(booleanAttrT1);
+ arguments.add(booleanAttrT2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check different values
+ arguments.clear();
+ arguments.add(booleanAttrT1);
+ arguments.add(booleanAttrF1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+
+ /**
+ * Integer
+ */
+ @Test
+ public void testInteger_Equal() {
+
+ // String exact match
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_INTEGER_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_INTEGER_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check separate objects with same value
+ arguments.add(intAttr1);
+ arguments.add(intAttr1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check not same
+ arguments.clear();
+ arguments.add(intAttr1);
+ arguments.add(intAttr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ arguments.clear();
+ arguments.add(intAttr1);
+ arguments.add(intAttrNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+
+
+ /**
+ * Double
+ */
+ @Test
+ public void testDouble_Equal() {
+ FunctionArgumentAttributeValue attr1 = null;
+ FunctionArgumentAttributeValue attr1a = null;
+ FunctionArgumentAttributeValue attr2 = null;
+ FunctionArgumentAttributeValue attrNeg1 = null;
+ try {
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0));
+ attr1a = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.4));
+ attrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-1.0));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ // String exact match
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DOUBLE_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DOUBLE_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check separate objects with the same value
+ arguments.add(attr1);
+ arguments.add(attr1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check not same
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ arguments.clear();
+ arguments.add(attr1);
+ arguments.add(attrNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+
+
+
+
+ /**
+ * Date
+ */
+ @Test
+ public void testDate_Equal() {
+ Calendar calendar = Calendar.getInstance();
+ Date today = calendar.getTime();
+ Date longAgo = new Date(1234);
+ // create a date that is different than "today" but within the same day (i.e. has a different hour)
+ if (calendar.get(Calendar.HOUR_OF_DAY) > 3) {
+ calendar.set(Calendar.HOUR_OF_DAY, 3);
+ } else {
+ calendar.set(Calendar.HOUR_OF_DAY, 5);
+ }
+ Date todayPlus = calendar.getTime();
+
+
+ FunctionArgumentAttributeValue attrToday = null;
+ FunctionArgumentAttributeValue attrToday2 = null;
+ FunctionArgumentAttributeValue attrLaterToday = null;
+ FunctionArgumentAttributeValue attrYesterday = null;
+ try {
+ attrToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(today));
+ attrToday2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(today));
+ attrLaterToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(todayPlus));
+ attrYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(longAgo));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ // String exact match
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DATE_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATE_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check separate objects with the same value
+ arguments.add(attrToday);
+ arguments.add(attrToday2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check not same
+ arguments.clear();
+ arguments.add(attrToday);
+ arguments.add(attrYesterday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // Date objects with different times but within the same day should match
+ arguments.clear();
+ arguments.add(attrToday);
+ arguments.add(attrLaterToday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+
+
+
+ /**
+ * Time
+ */
+ @Test
+ public void testTime_Equal() {
+
+ Date now = new Date();
+ Date now2 = new Date(now.getTime());
+ Date notNow = new Date(now.getTime() - 100000);
+
+ FunctionArgumentAttributeValue attrNow = null;
+ FunctionArgumentAttributeValue attrNow2 = null;
+ FunctionArgumentAttributeValue attrNotNow = null;
+ try {
+ attrNow = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(now));
+ attrNow2 = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(now2));
+ attrNotNow = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(notNow));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ // String exact match
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_TIME_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_TIME_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check separate objects with the same value
+ arguments.add(attrNow);
+ arguments.add(attrNow2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check not same
+ arguments.clear();
+ arguments.add(attrNow);
+ arguments.add(attrNotNow);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+
+
+
+ /**
+ * DateTime
+ */
+ @Test
+ public void testDateTime_Equal() {
+ Calendar calendar = Calendar.getInstance();
+ Date today = calendar.getTime();
+ Date longAgo = new Date(1234);
+ // create a dateTime that is different than "today" changing only the Timezone
+ if (calendar.get(Calendar.ZONE_OFFSET) > 3) {
+ calendar.set(Calendar.ZONE_OFFSET, 3);
+ } else {
+ calendar.set(Calendar.ZONE_OFFSET, 5);
+ }
+ Date todayPlus = calendar.getTime();
+
+
+ FunctionArgumentAttributeValue attrToday = null;
+ FunctionArgumentAttributeValue attrToday2 = null;
+ FunctionArgumentAttributeValue attrLaterToday = null;
+ FunctionArgumentAttributeValue attrYesterday = null;
+ try {
+ attrToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(today));
+ attrToday2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(today));
+ attrLaterToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(todayPlus));
+ attrYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(longAgo));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ // String exact match
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DATETIME_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATETIME_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check separate objects with the same value
+ arguments.add(attrToday);
+ arguments.add(attrToday2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check not same
+ arguments.clear();
+ arguments.add(attrToday);
+ arguments.add(attrYesterday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // DateTime with different Zones should not match
+ arguments.clear();
+ arguments.add(attrToday);
+ arguments.add(attrLaterToday);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+
+ /**
+ * dayTimeDuration - Version1
+ */
+ @Test
+ public void testDayTimeDuration_Equal_V1() {
+
+ XPathDayTimeDuration dur1 = new XPathDayTimeDuration(1, 3, 5, 12, 38);
+ XPathDayTimeDuration dur2 = new XPathDayTimeDuration(1, 3, 5, 12, 38);
+ XPathDayTimeDuration differentDur = new XPathDayTimeDuration(-1, 4, 7, 5, 33);
+
+ FunctionArgumentAttributeValue attrDur1 = null;
+ FunctionArgumentAttributeValue attrDur2 = null;
+ FunctionArgumentAttributeValue attrDifferentDur = null;
+ try {
+ attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur1));
+ attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur2));
+ attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(differentDur));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DAYTIMEDURATION_EQUAL_VERSION1;
+
+ // check identity and type of the thing created
+ assertEquals(XACML1.ID_FUNCTION_DAYTIMEDURATION_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check separate objects with the same value
+ arguments.add(attrDur1);
+ arguments.add(attrDur2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check not same
+ arguments.clear();
+ arguments.add(attrDur1);
+ arguments.add(attrDifferentDur);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+
+ /**
+ * dayTimeDuration - Current version
+ */
+ @Test
+ public void testDayTimeDuration_Equal() {
+
+ XPathDayTimeDuration dur1 = new XPathDayTimeDuration(1, 3, 5, 12, 38);
+ XPathDayTimeDuration dur2 = new XPathDayTimeDuration(1, 3, 5, 12, 38);
+ XPathDayTimeDuration differentDur = new XPathDayTimeDuration(-1, 4, 7, 5, 33);
+
+ FunctionArgumentAttributeValue attrDur1 = null;
+ FunctionArgumentAttributeValue attrDur2 = null;
+ FunctionArgumentAttributeValue attrDifferentDur = null;
+ try {
+ attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur1));
+ attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur2));
+ attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(differentDur));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DAYTIMEDURATION_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DAYTIMEDURATION_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check separate objects with the same value
+ arguments.add(attrDur1);
+ arguments.add(attrDur2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check not same
+ arguments.clear();
+ arguments.add(attrDur1);
+ arguments.add(attrDifferentDur);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+
+
+ /**
+ * dayTimeDuration - Version1
+ */
+ @Test
+ public void testYearMonthDuration_Equal_V1() {
+
+ XPathYearMonthDuration dur1 = new XPathYearMonthDuration(1, 3, 5);
+ XPathYearMonthDuration dur2 = new XPathYearMonthDuration(1, 3, 5);
+ XPathYearMonthDuration differentDur = new XPathYearMonthDuration(-1, 4, 7);
+
+ FunctionArgumentAttributeValue attrDur1 = null;
+ FunctionArgumentAttributeValue attrDur2 = null;
+ FunctionArgumentAttributeValue attrDifferentDur = null;
+ try {
+ attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur1));
+ attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur2));
+ attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(differentDur));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_YEARMONTHDURATION_EQUAL_VERSION1;
+
+ // check identity and type of the thing created
+ assertEquals(XACML1.ID_FUNCTION_YEARMONTHDURATION_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check separate objects with the same value
+ arguments.add(attrDur1);
+ arguments.add(attrDur2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check not same
+ arguments.clear();
+ arguments.add(attrDur1);
+ arguments.add(attrDifferentDur);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+
+
+
+ /**
+ * dayTimeDuration - Current version
+ */
+ @Test
+ public void testYearMonthDuration_Equal() {
+
+ XPathYearMonthDuration dur1 = new XPathYearMonthDuration(1, 3, 5);
+ XPathYearMonthDuration dur2 = new XPathYearMonthDuration(1, 3, 5);
+ XPathYearMonthDuration differentDur = new XPathYearMonthDuration(-1, 4, 7);
+
+ FunctionArgumentAttributeValue attrDur1 = null;
+ FunctionArgumentAttributeValue attrDur2 = null;
+ FunctionArgumentAttributeValue attrDifferentDur = null;
+ try {
+ attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur1));
+ attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur2));
+ attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(differentDur));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_YEARMONTHDURATION_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_YEARMONTHDURATION_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check separate objects with the same value
+ arguments.add(attrDur1);
+ arguments.add(attrDur2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check not same
+ arguments.clear();
+ arguments.add(attrDur1);
+ arguments.add(attrDifferentDur);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+
+ /**
+ * URI
+ */
+ @Test
+ public void testAnyURI_Equal() {
+
+ URI uri1 = null;
+ URI uri2 = null;
+ URI uriNotThere = null;
+ try {
+ uri1 = new URI("http://someplace.com/gothere");
+ uri2 = new URI("http://someplace.com/gothere");
+ uriNotThere = new URI("http://someplace.com/notGoingThere");
+ } catch (Exception e) {
+ fail(e.toString());
+ }
+
+ FunctionArgumentAttributeValue attrUri1 = null;
+ FunctionArgumentAttributeValue attrUri2 = null;
+ FunctionArgumentAttributeValue attrUriNotThere = null;
+ try {
+ attrUri1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri1));
+ attrUri2 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri2));
+ attrUriNotThere = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uriNotThere));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_ANYURI_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_ANYURI_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check separate objects with the same value
+ arguments.add(attrUri1);
+ arguments.add(attrUri2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check not same
+ arguments.clear();
+ arguments.add(attrUri1);
+ arguments.add(attrUriNotThere);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+
+ /**
+ * X500Name
+ */
+ @Test
+ public void testX500Name_Equal() {
+
+ X500Principal name1 = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US");
+ X500Principal name2 = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US");
+ X500Principal name3 = new X500Principal("CN=NotDuke, OU=NotThere, O=Oracle, C=US");
+
+
+ FunctionArgumentAttributeValue attrName1 = null;
+ FunctionArgumentAttributeValue attrName1a = null;
+ FunctionArgumentAttributeValue attrNotSameName = null;
+ try {
+ attrName1 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(name1));
+ attrName1a = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(name2));
+ attrNotSameName = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(name3));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_X500NAME_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_X500NAME_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check separate objects with the same value
+ arguments.add(attrName1);
+ arguments.add(attrName1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check not same
+ arguments.clear();
+ arguments.add(attrName1);
+ arguments.add(attrNotSameName);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+
+
+ /**
+ * RFC822Name
+ */
+ @Test
+ public void testRfc822Name_Equal() {
+
+ RFC822Name name1 = null;
+ RFC822Name name1a = null;
+ RFC822Name differentLocalName = null;
+ RFC822Name differentDomainName = null;
+ RFC822Name localCaseName = null;
+ RFC822Name domainCaseName = null;
+ @SuppressWarnings("unused")
+ RFC822Name noAtName = null;
+
+ try {
+ name1 = RFC822Name.newInstance("localPart@DomainPart");
+ name1a = RFC822Name.newInstance("localPart@DomainPart");
+ differentLocalName = RFC822Name.newInstance("differentlocalPart@DomainPart");
+ differentDomainName = RFC822Name.newInstance("localPart@differentDomainPart");
+ localCaseName = RFC822Name.newInstance("LOCALPart@DomainPart");
+ domainCaseName = RFC822Name.newInstance("localPart@DOMAINPart");
+
+
+ } catch (Exception e) {
+ fail(e.toString());
+ }
+
+ // should not be able to create a name without an @. If you try, newInstance returns null
+ Exception exSeen = null;
+ try {
+ noAtName = RFC822Name.newInstance("nameWithoutAnAtSign");
+ } catch (Exception e) {
+ exSeen = e;
+ }
+ assertNotNull(exSeen);
+
+
+ FunctionArgumentAttributeValue attrName1 = null;
+ FunctionArgumentAttributeValue attrName1a = null;
+ FunctionArgumentAttributeValue attrDifferentLocalName = null;
+ FunctionArgumentAttributeValue attrDifferentDomainName = null;
+ FunctionArgumentAttributeValue attrLocalCaseName = null;
+ FunctionArgumentAttributeValue attrDomainCaseName = null;
+ try {
+ attrName1 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(name1));
+ attrName1a = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(name1a));
+ attrDifferentLocalName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(differentLocalName));
+ attrDifferentDomainName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(differentDomainName));
+ attrLocalCaseName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(localCaseName));
+ attrDomainCaseName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(domainCaseName));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_RFC822NAME_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_RFC822NAME_EQUAL, fd.getId());
+ assertEquals(DataTypeRFC822Name.newInstance().getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check separate objects with the same value
+ arguments.add(attrName1);
+ arguments.add(attrName1a);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check not same Local
+ arguments.clear();
+ arguments.add(attrName1);
+ arguments.add(attrDifferentLocalName);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // check not same Domain
+ arguments.clear();
+ arguments.add(attrName1);
+ arguments.add(attrDifferentDomainName);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // test case-sensitivity in local part
+ arguments.clear();
+ arguments.add(attrName1);
+ arguments.add(attrLocalCaseName);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // test non-case-sensitivity in Domain part
+ arguments.clear();
+ arguments.add(attrName1);
+ arguments.add(attrDomainCaseName);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+
+ /**
+ * Hex Binary
+ */
+ @Test
+ public void testHexBinary_Equal() {
+ HexBinary binary = null;
+ HexBinary sameBinary = null;
+ HexBinary differentBinary = null;
+ try {
+ binary = HexBinary.newInstance("e04fd020ea3a6910a2d808002b30309d");
+ sameBinary = HexBinary.newInstance("e04fd020ea3a6910a2d808002b30309d");
+ differentBinary = HexBinary.newInstance("f123a890ee3d");
+ } catch (Exception e) {
+ fail(e.toString());
+ }
+
+ FunctionArgumentAttributeValue attrBinary = null;
+ FunctionArgumentAttributeValue attrSameBinary = null;
+ FunctionArgumentAttributeValue attrDifferentBinary = null;;
+ try {
+ attrBinary = new FunctionArgumentAttributeValue(DataTypes.DT_HEXBINARY.createAttributeValue(binary));
+ attrSameBinary = new FunctionArgumentAttributeValue(DataTypes.DT_HEXBINARY.createAttributeValue(sameBinary));
+ attrDifferentBinary = new FunctionArgumentAttributeValue(DataTypes.DT_HEXBINARY.createAttributeValue(differentBinary));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_HEXBINARY_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_HEXBINARY_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_HEXBINARY.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check separate objects with the same value
+ arguments.add(attrBinary);
+ arguments.add(attrSameBinary);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check not same
+ arguments.clear();
+ arguments.add(attrBinary);
+ arguments.add(attrDifferentBinary);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+
+
+ /**
+ * Base64 Binary
+ */
+ @Test
+ public void testBase64Binary_Equal() {
+ Base64Binary binary = null;
+ Base64Binary sameBinary = null;
+ Base64Binary differentBinary = null;
+ try {
+ binary = Base64Binary.newInstance("TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz");
+ sameBinary = Base64Binary.newInstance("TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz");
+ differentBinary = Base64Binary.newInstance("f123a890ee3d");
+ } catch (Exception e) {
+ fail(e.toString());
+ }
+
+ FunctionArgumentAttributeValue attrBinary = null;
+ FunctionArgumentAttributeValue attrSameBinary = null;
+ FunctionArgumentAttributeValue attrDifferentBinary = null;
+ try {
+ attrBinary = new FunctionArgumentAttributeValue(DataTypes.DT_BASE64BINARY.createAttributeValue(binary));
+ attrSameBinary = new FunctionArgumentAttributeValue(DataTypes.DT_BASE64BINARY.createAttributeValue(sameBinary));
+ attrDifferentBinary = new FunctionArgumentAttributeValue(DataTypes.DT_BASE64BINARY.createAttributeValue(differentBinary));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_BASE64BINARY_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_BASE64BINARY_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_BASE64BINARY.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+ // test normal equals and non-equals
+ // check separate objects with the same value
+ arguments.add(attrBinary);
+ arguments.add(attrSameBinary);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check not same
+ arguments.clear();
+ arguments.add(attrBinary);
+ arguments.add(attrDifferentBinary);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ }
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBagTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBagTest.java
new file mode 100755
index 0000000..e2b9efc
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHigherOrderBagTest.java
@@ -0,0 +1,2173 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.DataTypes;
+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.FunctionArgumentBag;
+import com.att.research.xacmlatt.pdp.std.StdFunctions;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionHigherOrderBagTest {
+
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+
+
+ //
+ // ANY-OF tests
+ //
+
+
+ @Test
+ public void testAny_of() {
+ String a = "a";
+ String b = "b";
+ String c = "c";
+ String d = "d";
+ String e = "e";
+ String f = "f";
+ String g = "g";
+ String h = "h";
+ String j = "j";
+
+
+ Bag bagabcdefg = null;
+ Bag bagbdfhj = null;
+ Bag bagace = null;
+ Bag bagb = null;
+ Bag bagaaacccef = null;
+ Bag bagInt = null;
+ Bag bagStringInt = null;
+ Bag bagEmpty = null;
+ Bag bagStringBooleansTrue = null;
+ Bag bagStringBooleansFalse = null;
+
+
+ // primitive attrs
+ FunctionArgumentAttributeValue attra = null;
+ FunctionArgumentAttributeValue attrb = null;
+ FunctionArgumentAttributeValue attrh = null;
+
+
+ // predicates passed as arguments
+ FunctionArgumentAttributeValue attrPredicateStringEqual = null;
+ FunctionArgumentAttributeValue attrPredicateStringIntersection = null;
+ FunctionArgumentAttributeValue attrPredicateBooleanFromString = null;
+
+ try {
+
+ // Create Bag contents
+ bagabcdefg = new Bag();
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));
+ bagbdfhj = new Bag();
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));
+ bagace = new Bag();
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagb = new Bag();
+ bagb.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagaaacccef = new Bag();
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagInt = new Bag();
+ bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagStringInt = new Bag();
+ bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagEmpty = new Bag();
+ bagStringBooleansTrue = new Bag();
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));
+ bagStringBooleansFalse = new Bag();
+ bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));
+
+
+ // create primitive attrs
+ attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a));
+ attrb = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(b));
+ attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h));
+
+
+ // predicates passed as function arguments
+ attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL));
+ attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION));
+ attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING));
+
+ } catch (Exception ex) {
+ fail("creating attribute e="+ ex);
+ }
+
+ // make into attributes
+ FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);
+ FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);
+ FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);
+ FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);
+ FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);
+ FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue);
+ FunctionArgumentBag attrBagStringBooleansFalse = new FunctionArgumentBag(bagStringBooleansFalse);
+
+ FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ANY_OF;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_ANY_OF, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+ // normal match
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attra);
+ arguments.add(attrBagabcdefg);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // bag in first position - match
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrBagabcdefg);
+ arguments.add(attra);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // normal no-match
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attra);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // multiple primitives
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrh);
+ arguments.add(attrb);
+ arguments.add(attrBagace);
+ arguments.add(attra);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of Predicate error: function:string-equal Expected 2 arguments, got 4", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // no primitives - predicate function expects 2
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of Predicate error: function:string-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // no primitives - predicate expects only 1 arg
+ arguments.clear();
+ arguments.add(attrPredicateBooleanFromString);
+ arguments.add(attrBagStringBooleansTrue);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ arguments.clear();
+ arguments.add(attrPredicateBooleanFromString);
+ arguments.add(attrBagStringBooleansFalse);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // bag is empty
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrh);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // no bag
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrh);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of Did not get any Bag argument; must have at least 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // extra bag
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrh);
+ arguments.add(attrBagStringBooleansTrue);
+ arguments.add(attrh);
+ arguments.add(attrBagStringBooleansTrue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of must have only 1 bag; found one at index 2 and another at 4", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // bad predicate
+ arguments.clear();
+ arguments.add(attrh);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // non-boolean predicate
+ arguments.clear();
+ arguments.add(attrPredicateStringIntersection);
+ arguments.add(attrh);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // predicate after first arg
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrPredicateStringIntersection);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of Predicate error: function:string-equal Expected data type 'string' saw 'anyURI' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bags of different types
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrh);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ // first null
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of Predicate Function (first argument) was null", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second null
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrBagabcdefg);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of Got null argument at index 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+
+ @Test
+ public void testAll_of() {
+ String a = "a";
+ String b = "b";
+ String c = "c";
+ String d = "d";
+ String e = "e";
+ String f = "f";
+ String g = "g";
+ String h = "h";
+ String j = "j";
+
+ String w = "w";
+
+
+ Bag bagabcdefg = null;
+ Bag bagbdfhj = null;
+ Bag bagace = null;
+ Bag bagb = null;
+ Bag bagaaacccef = null;
+ Bag bagInt = null;
+ Bag bagStringInt = null;
+ Bag bagEmpty = null;
+ Bag bagStringBooleansFalse = null;
+ Bag bagStringBooleansTrue = null;
+
+
+ // primitive attrs
+ FunctionArgumentAttributeValue attra = null;
+ FunctionArgumentAttributeValue attrh = null;
+ FunctionArgumentAttributeValue attrw = null;
+
+
+
+ // predicates passed as arguments
+ FunctionArgumentAttributeValue attrPredicateStringEqual = null;
+ FunctionArgumentAttributeValue attrPredicateStringIntersection = null;
+ FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null;
+ FunctionArgumentAttributeValue attrPredicateBooleanFromString = null;
+
+ try {
+
+ // Create Bag contents
+ bagabcdefg = new Bag();
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));
+ bagbdfhj = new Bag();
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));
+ bagace = new Bag();
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagb = new Bag();
+ bagb.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagaaacccef = new Bag();
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagInt = new Bag();
+ bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagStringInt = new Bag();
+ bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagEmpty = new Bag();
+ bagStringBooleansTrue = new Bag();
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));
+ bagStringBooleansFalse = new Bag();
+ bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));
+
+
+
+ // create primitive attrs
+ attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a));
+ attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h));
+ attrw = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(w));
+
+
+ // predicates passed as function arguments
+ attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL));
+ attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION));
+ attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN));
+ attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING));
+
+ } catch (Exception ex) {
+ fail("creating attribute e="+ ex);
+ }
+
+ // make into attributes
+ FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);
+ FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);
+ FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);
+ FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);
+ FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);
+ FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue);
+ FunctionArgumentBag attrBagStringBooleansFalse = new FunctionArgumentBag(bagStringBooleansFalse);
+
+ FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ALL_OF;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_ALL_OF, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+ // normal match
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrw);
+ arguments.add(attrBagace);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // normal no-match
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attra);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // no primitives - predicate function expects 2
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of Predicate error: function:string-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // no primitives - predicate expects only 1 arg
+ arguments.clear();
+ arguments.add(attrPredicateBooleanFromString);
+ arguments.add(attrBagStringBooleansTrue);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ arguments.clear();
+ arguments.add(attrPredicateBooleanFromString);
+ arguments.add(attrBagStringBooleansFalse);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // bag is empty
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrh);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // no bag
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrh);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of Did not get any Bag argument; must have at least 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // extra bag
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrh);
+ arguments.add(attrBagStringBooleansTrue);
+ arguments.add(attrh);
+ arguments.add(attrBagStringBooleansTrue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of must have only 1 bag; found one at index 2 and another at 4", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // bad predicate
+ arguments.clear();
+ arguments.add(attrh);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // non-boolean predicate
+ arguments.clear();
+ arguments.add(attrPredicateStringIntersection);
+ arguments.add(attrh);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // predicate after first arg
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrPredicateStringIntersection);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of Predicate error: function:string-greater-than Expected data type 'string' saw 'anyURI' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bags of different types
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrh);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ // first null
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of Predicate Function (first argument) was null", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second null
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagabcdefg);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of Got null argument at index 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @Test
+ public void testAny_of_any() {
+ String a = "a";
+ String b = "b";
+ String c = "c";
+ String d = "d";
+ String e = "e";
+ String f = "f";
+ String g = "g";
+ String h = "h";
+ String j = "j";
+
+ String w = "w";
+
+
+ Bag bagabcdefg = null;
+ Bag bagbdfhj = null;
+ Bag bagace = null;
+ Bag bagb = null;
+ Bag bagaaacccef = null;
+ Bag bagInt = null;
+ Bag bagStringInt = null;
+ Bag bagEmpty = null;
+ Bag bagStringBooleansFalse = null;
+ Bag bagStringBooleansTrue = null;
+ Bag bagBooleansFalse = null;
+ Bag bagBooleansTrue = null;
+
+
+ // primitive attrs
+ FunctionArgumentAttributeValue attra = null;
+ FunctionArgumentAttributeValue attrh = null;
+ FunctionArgumentAttributeValue attrw = null;
+
+
+ FunctionArgumentAttributeValue attrInt4 = null;
+
+
+ // predicates passed as arguments
+ FunctionArgumentAttributeValue attrPredicateStringEqual = null;
+ FunctionArgumentAttributeValue attrPredicateStringIntersection = null;
+ FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null;
+ FunctionArgumentAttributeValue attrPredicateBooleanFromString = null;
+ FunctionArgumentAttributeValue attrPredicateNof = null;
+
+ try {
+
+ // Create Bag contents
+ bagabcdefg = new Bag();
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));
+ bagbdfhj = new Bag();
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));
+ bagace = new Bag();
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagb = new Bag();
+ bagb.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagaaacccef = new Bag();
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagInt = new Bag();
+ bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagStringInt = new Bag();
+ bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagEmpty = new Bag();
+ bagStringBooleansTrue = new Bag();
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));
+ bagStringBooleansFalse = new Bag();
+ bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagBooleansTrue = new Bag();
+ bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+ bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+ bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true));
+ bagBooleansFalse = new Bag();
+ bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+ bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+
+
+ // create primitive attrs
+ attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a));
+ attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h));
+ attrw = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(w));
+
+ attrInt4 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(4));
+
+
+ // predicates passed as function arguments
+ attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL));
+ attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION));
+ attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN));
+ attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING));
+ attrPredicateNof = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_N_OF));
+
+ } catch (Exception ex) {
+ fail("creating attribute e="+ ex);
+ }
+
+ // make into attributes
+ FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);
+ FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);
+ FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);
+ FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);
+ FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);
+ FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue);
+ FunctionArgumentBag attrBagStringBooleansFalse = new FunctionArgumentBag(bagStringBooleansFalse);
+ FunctionArgumentBag attrBagBooleansTrue = new FunctionArgumentBag(bagBooleansTrue);
+ FunctionArgumentBag attrBagBooleansFalse = new FunctionArgumentBag(bagBooleansFalse);
+
+ FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ANY_OF_ANY;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_ANY_OF_ANY, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+ // normal match
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrw);
+ arguments.add(attrBagace);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // normal no-match
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attra);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // no primitives - predicate function expects 2
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-any Predicate error: function:string-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrBagace);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // no primitives - predicate expects only 1 arg
+ arguments.clear();
+ arguments.add(attrPredicateBooleanFromString);
+ arguments.add(attrBagStringBooleansTrue);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ arguments.clear();
+ arguments.add(attrPredicateBooleanFromString);
+ arguments.add(attrBagStringBooleansFalse);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // n-of with lots of bags - success
+ arguments.clear();
+ arguments.add(attrPredicateNof);
+ arguments.add(attrInt4);
+ arguments.add(attrBagBooleansTrue);
+ arguments.add(attrBagBooleansTrue);
+ arguments.add(attrBagBooleansTrue);
+ arguments.add(attrBagBooleansTrue);
+ arguments.add(attrBagBooleansTrue);
+ arguments.add(attrBagBooleansTrue);
+ arguments.add(attrBagBooleansTrue);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // n-of with lots of bags - fail
+ arguments.clear();
+ arguments.add(attrPredicateNof);
+ arguments.add(attrInt4);
+ arguments.add(attrBagBooleansFalse);
+ arguments.add(attrBagBooleansFalse);
+ arguments.add(attrBagBooleansTrue);
+ arguments.add(attrBagBooleansTrue);
+ arguments.add(attrBagBooleansFalse);
+ arguments.add(attrBagBooleansFalse);
+ arguments.add(attrBagBooleansFalse);
+ arguments.add(attrBagBooleansFalse);
+ arguments.add(attrBagBooleansFalse);
+ arguments.add(attrBagBooleansFalse);
+ arguments.add(attrBagBooleansFalse);
+ arguments.add(attrBagBooleansFalse);
+ arguments.add(attrBagBooleansFalse);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+
+ // bag is empty
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrh);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-any Bag is empty at index 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // no bag
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrh);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-any Predicate error: function:string-greater-than Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrh);
+ arguments.add(attrh);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // bad predicate
+ arguments.clear();
+ arguments.add(attrh);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-any First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // non-boolean predicate
+ arguments.clear();
+ arguments.add(attrPredicateStringIntersection);
+ arguments.add(attrh);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-any Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // predicate after first arg
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrPredicateStringIntersection);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-any Predicate error: function:string-greater-than Expected data type 'string' saw 'anyURI' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bags of different types
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrh);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first null
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-any Predicate Function (first argument) was null", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second null
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagabcdefg);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-any Got null argument at index 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @Test
+ public void testAll_of_any() {
+ String a = "a";
+ String b = "b";
+ String c = "c";
+ String d = "d";
+ String e = "e";
+ String f = "f";
+ String g = "g";
+ String h = "h";
+ String j = "j";
+
+ String w = "w";
+ String x = "x";
+
+
+ Bag bagabcdefg = null;
+ Bag bagbdfhj = null;
+ Bag bagace = null;
+ Bag bagb = null;
+ Bag bagaaacccef = null;
+ Bag bagawx = null;
+ Bag bagInt = null;
+ Bag bagStringInt = null;
+ Bag bagEmpty = null;
+ Bag bagStringBooleansFalse = null;
+ Bag bagStringBooleansTrue = null;
+ Bag bagBooleansFalse = null;
+ Bag bagBooleansTrue = null;
+
+
+ // primitive attrs
+ FunctionArgumentAttributeValue attra = null;
+ FunctionArgumentAttributeValue attrh = null;
+
+
+
+
+ // predicates passed as arguments
+ FunctionArgumentAttributeValue attrPredicateStringEqual = null;
+ FunctionArgumentAttributeValue attrPredicateStringIntersection = null;
+ FunctionArgumentAttributeValue attrPredicateStringLessThan = null;
+ FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null;
+ FunctionArgumentAttributeValue attrPredicateBooleanFromString = null;
+
+ try {
+
+ // Create Bag contents
+ bagabcdefg = new Bag();
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));
+ bagbdfhj = new Bag();
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));
+ bagace = new Bag();
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagb = new Bag();
+ bagb.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagaaacccef = new Bag();
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagawx = new Bag();
+ bagawx.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagawx.add(DataTypes.DT_STRING.createAttributeValue(w));
+ bagawx.add(DataTypes.DT_STRING.createAttributeValue(x));
+ bagInt = new Bag();
+ bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagStringInt = new Bag();
+ bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagEmpty = new Bag();
+ bagStringBooleansTrue = new Bag();
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));
+ bagStringBooleansFalse = new Bag();
+ bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagBooleansTrue = new Bag();
+ bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+ bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+ bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true));
+ bagBooleansFalse = new Bag();
+ bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+ bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+
+
+ // create primitive attrs
+ attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a));
+ attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h));
+
+
+
+ // predicates passed as function arguments
+ attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL));
+ attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION));
+ attrPredicateStringLessThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_LESS_THAN));
+ attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN));
+ attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING));
+
+ } catch (Exception ex) {
+ fail("creating attribute e="+ ex);
+ }
+
+ // make into attributes
+ FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);
+ FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);
+ FunctionArgumentBag attrBagawx = new FunctionArgumentBag(bagawx);
+ FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);
+ FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);
+ FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue);
+
+ FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ALL_OF_ANY;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_ALL_OF_ANY, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+ // normal match
+ arguments.clear();
+ arguments.add(attrPredicateStringLessThan);
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagawx);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // normal no-match
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagace);
+ arguments.add(attrBagawx);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // primitive instead of bag
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attra);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-any 2nd argument must be bag, got 'string'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrBagace);
+ arguments.add(attra);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-any 3rd argument must be bag, got 'string'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // no primitives - predicate expects only 1 arg
+ arguments.clear();
+ arguments.add(attrPredicateBooleanFromString);
+ arguments.add(attrBagStringBooleansTrue);
+ arguments.add(attrBagStringBooleansTrue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-any Predicate error: function:boolean-from-string Expected 1 arguments, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+
+ // bag is empty
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagace);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagEmpty);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // no bag
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrh);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-any Expected 3 arguments, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // bad predicate
+ arguments.clear();
+ arguments.add(attrh);
+ arguments.add(attrBagStringInt);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-any First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // non-boolean predicate
+ arguments.clear();
+ arguments.add(attrPredicateStringIntersection);
+ arguments.add(attrBagStringInt);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-any Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // predicate after first arg
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrPredicateStringIntersection);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-any 2nd argument must be bag, got 'anyURI'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bags of different types
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagace);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-any Predicate error: function:string-greater-than Expected data type 'string' saw 'integer' at arg index 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // no args
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-any Expected at least 2 arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // one arg
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-any Expected at least 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many args
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-any Expected 3 arguments, got 4", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // first null
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-any Expected 3 arguments, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second null
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagabcdefg);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-any 3rd argument must be bag, got 'null'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+ @Test
+ public void testAny_of_all() {
+ String a = "a";
+ String b = "b";
+ String c = "c";
+ String d = "d";
+ String e = "e";
+ String f = "f";
+ String g = "g";
+ String h = "h";
+ String j = "j";
+
+ String w = "w";
+ String x = "x";
+
+
+ Bag bagabcdefg = null;
+ Bag bagbdfhj = null;
+ Bag bagace = null;
+ Bag bagb = null;
+ Bag bagaaacccef = null;
+ Bag bagewx = null;
+ Bag bagInt = null;
+ Bag bagStringInt = null;
+ Bag bagEmpty = null;
+ Bag bagStringBooleansFalse = null;
+ Bag bagStringBooleansTrue = null;
+ Bag bagBooleansFalse = null;
+ Bag bagBooleansTrue = null;
+
+
+ // primitive attrs
+ FunctionArgumentAttributeValue attra = null;
+ FunctionArgumentAttributeValue attrh = null;
+
+
+
+
+ // predicates passed as arguments
+ FunctionArgumentAttributeValue attrPredicateStringEqual = null;
+ FunctionArgumentAttributeValue attrPredicateStringIntersection = null;
+ FunctionArgumentAttributeValue attrPredicateStringGreaterThanOrEqual = null;
+ FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null;
+ FunctionArgumentAttributeValue attrPredicateBooleanFromString = null;
+
+ try {
+
+ // Create Bag contents
+ bagabcdefg = new Bag();
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));
+ bagbdfhj = new Bag();
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));
+ bagace = new Bag();
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagb = new Bag();
+ bagb.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagaaacccef = new Bag();
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagewx = new Bag();
+ bagewx.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagewx.add(DataTypes.DT_STRING.createAttributeValue(w));
+ bagewx.add(DataTypes.DT_STRING.createAttributeValue(x));
+ bagInt = new Bag();
+ bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagStringInt = new Bag();
+ bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagEmpty = new Bag();
+ bagStringBooleansTrue = new Bag();
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));
+ bagStringBooleansFalse = new Bag();
+ bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagBooleansTrue = new Bag();
+ bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+ bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+ bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true));
+ bagBooleansFalse = new Bag();
+ bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+ bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+
+
+ // create primitive attrs
+ attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a));
+ attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h));
+
+
+
+ // predicates passed as function arguments
+ attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL));
+ attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION));
+ attrPredicateStringGreaterThanOrEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN_OR_EQUAL));
+ attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN));
+ attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING));
+
+ } catch (Exception ex) {
+ fail("creating attribute e="+ ex);
+ }
+
+ // make into attributes
+ FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);
+ FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);
+ FunctionArgumentBag attrBagewx = new FunctionArgumentBag(bagewx);
+ FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);
+ FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);
+ FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue);
+
+ FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ANY_OF_ALL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_ANY_OF_ALL, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+ // normal match
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThanOrEqual);
+ arguments.add(attrBagewx);
+ arguments.add(attrBagace);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // normal no-match
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagace);
+ arguments.add(attrBagewx);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // primitive instead of bag
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attra);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-all 2nd argument must be bag, got 'string'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrBagace);
+ arguments.add(attra);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-all 3rd argument must be bag, got 'string'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // no primitives - predicate expects only 1 arg
+ arguments.clear();
+ arguments.add(attrPredicateBooleanFromString);
+ arguments.add(attrBagStringBooleansTrue);
+ arguments.add(attrBagStringBooleansTrue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-all Predicate error: function:boolean-from-string Expected 1 arguments, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bag is empty
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagace);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagEmpty);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // no bag
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrh);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // bad predicate
+ arguments.clear();
+ arguments.add(attrh);
+ arguments.add(attrBagStringInt);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-all First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // non-boolean predicate
+ arguments.clear();
+ arguments.add(attrPredicateStringIntersection);
+ arguments.add(attrBagStringInt);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-all Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // predicate after first arg
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrPredicateStringIntersection);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-all 2nd argument must be bag, got 'anyURI'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bags of different types
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagace);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-all Predicate error: function:string-greater-than Expected data type 'string' saw 'integer' at arg index 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // no args
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-all Expected at least 2 arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // one arg
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-all Expected at least 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many args
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-all Expected 3 arguments, got 4", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // first null
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second null
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagabcdefg);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:any-of-all 3rd argument must be bag, got 'null'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+
+
+ @Test
+ public void testAll_of_all() {
+ String a = "a";
+ String b = "b";
+ String c = "c";
+ String d = "d";
+ String e = "e";
+ String f = "f";
+ String g = "g";
+ String h = "h";
+ String j = "j";
+
+ String w = "w";
+ String x = "x";
+
+
+ Bag bagabcdefg = null;
+ Bag bagbdfhj = null;
+ Bag bagace = null;
+ Bag bagb = null;
+ Bag bagaaacccef = null;
+ Bag bagawx = null;
+ Bag bagwx = null;
+ Bag bagInt = null;
+ Bag bagStringInt = null;
+ Bag bagEmpty = null;
+ Bag bagStringBooleansFalse = null;
+ Bag bagStringBooleansTrue = null;
+ Bag bagBooleansFalse = null;
+ Bag bagBooleansTrue = null;
+
+
+ // primitive attrs
+ FunctionArgumentAttributeValue attra = null;
+ FunctionArgumentAttributeValue attrh = null;
+
+
+
+
+ // predicates passed as arguments
+ FunctionArgumentAttributeValue attrPredicateStringEqual = null;
+ FunctionArgumentAttributeValue attrPredicateStringIntersection = null;
+ FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null;
+ FunctionArgumentAttributeValue attrPredicateBooleanFromString = null;
+
+ try {
+
+ // Create Bag contents
+ bagabcdefg = new Bag();
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));
+ bagbdfhj = new Bag();
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));
+ bagace = new Bag();
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagb = new Bag();
+ bagb.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagaaacccef = new Bag();
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagawx = new Bag();
+ bagawx.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagawx.add(DataTypes.DT_STRING.createAttributeValue(w));
+ bagawx.add(DataTypes.DT_STRING.createAttributeValue(x));
+ bagwx = new Bag();
+ bagwx.add(DataTypes.DT_STRING.createAttributeValue(w));
+ bagwx.add(DataTypes.DT_STRING.createAttributeValue(x));
+ bagInt = new Bag();
+ bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagStringInt = new Bag();
+ bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagEmpty = new Bag();
+ bagStringBooleansTrue = new Bag();
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));
+ bagStringBooleansFalse = new Bag();
+ bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagBooleansTrue = new Bag();
+ bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+ bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+ bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true));
+ bagBooleansFalse = new Bag();
+ bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+ bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+
+
+ // create primitive attrs
+ attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a));
+ attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h));
+
+
+
+ // predicates passed as function arguments
+ attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL));
+ attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION));
+ attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN));
+ attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING));
+
+ } catch (Exception ex) {
+ fail("creating attribute e="+ ex);
+ }
+
+ // make into attributes
+ FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);
+ FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);
+ FunctionArgumentBag attrBagawx = new FunctionArgumentBag(bagawx);
+ FunctionArgumentBag attrBagwx = new FunctionArgumentBag(bagwx);
+ FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);
+ FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);
+ FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue);
+
+ FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ALL_OF_ALL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_ALL_OF_ALL, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+ // normal match
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagwx);
+ arguments.add(attrBagace);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // normal no-match
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagawx);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagace);
+ arguments.add(attrBagwx);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // primitive instead of bag
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attra);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-all 2nd argument must be bag, got 'string'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrPredicateStringEqual);
+ arguments.add(attrBagace);
+ arguments.add(attra);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-all 3rd argument must be bag, got 'string'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // no primitives - predicate expects only 1 arg
+ arguments.clear();
+ arguments.add(attrPredicateBooleanFromString);
+ arguments.add(attrBagStringBooleansTrue);
+ arguments.add(attrBagStringBooleansTrue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-all Predicate error: function:boolean-from-string Expected 1 arguments, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bag is empty
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagace);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagEmpty);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // no bag
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrh);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // bad predicate
+ arguments.clear();
+ arguments.add(attrh);
+ arguments.add(attrBagStringInt);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-all First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // non-boolean predicate
+ arguments.clear();
+ arguments.add(attrPredicateStringIntersection);
+ arguments.add(attrBagStringInt);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-all Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // predicate after first arg
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrPredicateStringIntersection);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-all 2nd argument must be bag, got 'anyURI'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bags of different types
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagwx);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-all Predicate error: function:string-greater-than Expected data type 'string' saw 'integer' at arg index 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // no args
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-all Expected at least 2 arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // one arg
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-all Expected at least 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many args
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-all Expected 3 arguments, got 4", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // first null
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second null
+ arguments.clear();
+ arguments.add(attrPredicateStringGreaterThan);
+ arguments.add(attrBagabcdefg);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:all-of-all 3rd argument must be bag, got 'null'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+
+
+
+
+
+
+ @Test
+ public void testMap() {
+ String a = "a";
+ String b = "b";
+ String c = "c";
+ String d = "d";
+ String e = "e";
+ String f = "f";
+ String g = "g";
+ String h = "h";
+ String j = "j";
+
+
+ Bag bagabcdefg = null;
+ Bag bagbdfhj = null;
+ Bag bagace = null;
+ Bag bagb = null;
+ Bag bagaaacccef = null;
+ Bag bagInt = null;
+ Bag bagStringInt = null;
+ Bag bagEmpty = null;
+ Bag bagStringBooleansFalse = null;
+ Bag bagStringBooleansTrue = null;
+ Bag bagInt123 = null;
+ Bag bagInt789 = null;
+
+
+ // primitive attrs
+ FunctionArgumentAttributeValue attrh = null;
+ FunctionArgumentAttributeValue attrInt7 = null;
+
+
+
+ // predicates passed as arguments
+ FunctionArgumentAttributeValue attrPredicateStringNormalizeToLowerCase = null;
+ FunctionArgumentAttributeValue attrPredicateIntegerEqual = null;
+ FunctionArgumentAttributeValue attrPredicateIntegerAdd = null;
+
+ try {
+
+ // Create Bag contents
+ bagabcdefg = new Bag();
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));
+ bagbdfhj = new Bag();
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));
+ bagace = new Bag();
+ bagace.add(DataTypes.DT_STRING.createAttributeValue("A"));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue("C"));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue("E"));
+ bagb = new Bag();
+ bagb.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagaaacccef = new Bag();
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagInt = new Bag();
+ bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagStringInt = new Bag();
+ bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));
+
+ bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagEmpty = new Bag();
+ bagStringBooleansTrue = new Bag();
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));
+ bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true"));
+ bagStringBooleansFalse = new Bag();
+ bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false"));
+ bagInt123 = new Bag();
+ bagInt123.add(DataTypes.DT_INTEGER.createAttributeValue(1));
+ bagInt123.add(DataTypes.DT_INTEGER.createAttributeValue(2));
+ bagInt123.add(DataTypes.DT_INTEGER.createAttributeValue(3));
+ bagInt789 = new Bag();
+ bagInt789.add(DataTypes.DT_INTEGER.createAttributeValue(7));
+ bagInt789.add(DataTypes.DT_INTEGER.createAttributeValue(8));
+ bagInt789.add(DataTypes.DT_INTEGER.createAttributeValue(9));
+
+
+
+ // create primitive attrs
+ attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h));
+ attrInt7 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(7));
+
+
+ // predicates passed as function arguments
+ attrPredicateStringNormalizeToLowerCase = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_NORMALIZE_TO_LOWER_CASE));
+ attrPredicateIntegerEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_INTEGER_EQUAL));
+ attrPredicateIntegerAdd = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_INTEGER_ADD));
+
+ } catch (Exception ex) {
+ fail("creating attribute e="+ ex);
+ }
+
+ // make into attributes
+ FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);
+ FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);
+ FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);
+ FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);
+ FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue);
+ FunctionArgumentBag attrBagInt789 = new FunctionArgumentBag(bagInt789);
+
+ FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_MAP;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_MAP, fd.getId());
+ assertNull( fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertTrue(fd.returnsBag());
+
+ // normal match
+ arguments.clear();
+ arguments.add(attrPredicateStringNormalizeToLowerCase);
+ arguments.add(attrBagace);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertTrue(res.isBag());
+ Bag bag = res.getBag();
+ assertEquals(3, bag.size());
+ List<AttributeValue<?>> bagAttributes = bag.getAttributeValueList();
+ try {
+ assertTrue(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("a")));
+ assertFalse(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("A")));
+ assertTrue(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("c")));
+ assertFalse(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("C")));
+ assertTrue(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("e")));
+ assertFalse(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("E")));
+ } catch (Exception ex) {
+ fail("checking result e="+ex);
+ }
+
+ // 2-input predicate
+ arguments.clear();
+ arguments.add(attrPredicateIntegerAdd);
+ arguments.add(attrInt7);
+ arguments.add(attrBagInt789);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertTrue(res.isBag());
+ bag = res.getBag();
+ assertEquals(3, bag.size());
+ bagAttributes = bag.getAttributeValueList();
+ try {
+ assertTrue(bagAttributes.contains(DataTypes.DT_INTEGER.createAttributeValue("14")));
+ assertTrue(bagAttributes.contains(DataTypes.DT_INTEGER.createAttributeValue("15")));
+ assertTrue(bagAttributes.contains(DataTypes.DT_INTEGER.createAttributeValue("16")));
+ } catch (Exception ex) {
+ fail("checking result e="+ex);
+ }
+
+
+ // predicate returns booleans
+ arguments.clear();
+ arguments.add(attrPredicateIntegerEqual);
+ arguments.add(attrInt7);
+ arguments.add(attrBagInt789);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertTrue(res.isBag());
+ bag = res.getBag();
+ assertEquals(3, bag.size());
+ bagAttributes = bag.getAttributeValueList();
+ try {
+ assertEquals(bagAttributes.get(0), (DataTypes.DT_BOOLEAN.createAttributeValue(true)));
+ assertEquals(bagAttributes.get(1), (DataTypes.DT_BOOLEAN.createAttributeValue(false)));
+ assertEquals(bagAttributes.get(2), (DataTypes.DT_BOOLEAN.createAttributeValue(false)));
+ } catch (Exception ex) {
+ fail("checking result e="+ex);
+ }
+
+ // predicate returns bag
+
+
+
+ // no primitives - predicate function expects 2
+ arguments.clear();
+ arguments.add(attrPredicateIntegerAdd);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:map Predicate error: function:integer-add Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bag is empty
+ arguments.clear();
+ arguments.add(attrPredicateStringNormalizeToLowerCase);
+ arguments.add(attrh);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertTrue(res.isBag());
+ bag = res.getBag();
+ assertEquals(0, bag.size());;
+
+ // no bag
+ arguments.clear();
+ arguments.add(attrPredicateStringNormalizeToLowerCase);
+ arguments.add(attrh);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:map Did not get any Bag argument; must have at least 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // extra bag
+ arguments.clear();
+ arguments.add(attrPredicateStringNormalizeToLowerCase);
+ arguments.add(attrh);
+ arguments.add(attrBagStringBooleansTrue);
+ arguments.add(attrh);
+ arguments.add(attrBagStringBooleansTrue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:map must have only 1 bag; found one at index 2 and another at 4", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // bad predicate
+ arguments.clear();
+ arguments.add(attrh);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:map First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // predicate gets unexpected number of args
+ arguments.clear();
+ arguments.add(attrPredicateStringNormalizeToLowerCase);
+ arguments.add(attrh);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:map Predicate error: function:string-normalize-to-lower-case Expected 1 arguments, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // predicate gets bad primitive type
+ arguments.clear();
+ arguments.add(attrPredicateStringNormalizeToLowerCase);
+ arguments.add(attrPredicateStringNormalizeToLowerCase);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:map Predicate error: function:string-normalize-to-lower-case Expected 1 arguments, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bags of different types
+ arguments.clear();
+ arguments.add(attrPredicateStringNormalizeToLowerCase);
+ arguments.add(attrh);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+ // first null
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:map Predicate Function (first argument) was null", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second null
+ arguments.clear();
+ arguments.add(attrPredicateStringNormalizeToLowerCase);
+ arguments.add(attrBagabcdefg);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:map Got null argument at index 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimpleTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimpleTest.java
new file mode 100755
index 0000000..e281212
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionHomogeneousSimpleTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.Status;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacmlatt.pdp.policy.Bag;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag;
+
+/**
+ * FunctionDefinitionHomogeneousSimple is an abstract class, so we have to test it by creating a sub-class.
+ * The constructor is tested by default when an instance of the sub-class is created for other tests.
+ *
+ * Each of these functions needs to be tested for each type of function to be sure the values are correct,
+ * so this is just a simple test to see that the mechanism works.
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionHomogeneousSimpleTest {
+
+
+
+ @Test
+ public void testGetDataTypeArgs() {
+
+ // test a simple instance using the Equality class
+ FunctionDefinitionEquality<String> fd = new FunctionDefinitionEquality<String>(XACML3.ID_FUNCTION_STRING_EQUAL, DataTypes.DT_STRING);
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ }
+
+ @Test
+ public void testGetNumArgs() {
+ // test a simple instance using the Equality class
+ FunctionDefinitionEquality<String> fd = new FunctionDefinitionEquality<String>(XACML3.ID_FUNCTION_STRING_EQUAL, DataTypes.DT_STRING);
+ assertEquals(new Integer(2), fd.getNumArgs());
+ }
+
+ @Test
+ public void testValidateArguments() {
+ // create some arguments to use later
+ FunctionArgumentAttributeValue stringAttr1 = null;
+ FunctionArgumentAttributeValue stringAttr2 = null;
+ FunctionArgumentAttributeValue stringAttr3 = null;
+ FunctionArgumentAttributeValue intAttr = null;
+ try {
+ stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc"));
+ stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def"));
+ stringAttr3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ghi"));
+ intAttr = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionEquality<String> fd = new FunctionDefinitionEquality<String>(XACML3.ID_FUNCTION_STRING_EQUAL, DataTypes.DT_STRING);
+ List<String> convertedValues = new ArrayList<String>();
+ List<FunctionArgument> listFunctionArguments = new ArrayList<FunctionArgument>();
+
+ // test correct # of args, both of them strings
+ listFunctionArguments.add(stringAttr1);
+ listFunctionArguments.add(stringAttr2);
+ Status status = fd.validateArguments(listFunctionArguments, convertedValues);
+ assertTrue(status.isOk());
+ assertEquals(convertedValues.size(),2);
+
+ // test too few args
+ listFunctionArguments.remove(1);
+ status = fd.validateArguments(listFunctionArguments, convertedValues);
+ assertFalse(status.isOk());
+ assertEquals("Expected 2 arguments, got 1", status.getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue());
+
+ // test too many args
+ listFunctionArguments.add(stringAttr2);
+ listFunctionArguments.add(stringAttr3);
+ status = fd.validateArguments(listFunctionArguments, convertedValues);
+ assertFalse(status.isOk());
+ assertEquals("Expected 2 arguments, got 3", status.getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue());
+
+ // test with null arg
+ listFunctionArguments.clear();
+ listFunctionArguments.add(null);
+ listFunctionArguments.add(stringAttr1);
+ status = fd.validateArguments(listFunctionArguments, convertedValues);
+ assertFalse(status.isOk());
+ assertEquals("Got null argument at arg index 0", status.getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue());
+
+ // test function that takes 0 args
+//TODO test with func that specifies 0 args? ASSUME for now that there are no such functions since a function needs to operate on something
+// fail("need to test function with 0 args and various inputs - see validateArguments code");
+
+
+ // test with one is a bag
+ listFunctionArguments.clear();
+ listFunctionArguments.add(stringAttr1);
+ Bag bag = new Bag();
+ FunctionArgument bagArg = new FunctionArgumentBag(bag);
+ listFunctionArguments.add(bagArg);
+ status = fd.validateArguments(listFunctionArguments, convertedValues);
+ assertFalse(status.isOk());
+ assertEquals("Expected a simple value, saw a bag at arg index 1", status.getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue());
+
+ // test with string and int
+ listFunctionArguments.clear();
+ listFunctionArguments.add(stringAttr1);
+ listFunctionArguments.add(intAttr);
+ status = fd.validateArguments(listFunctionArguments, convertedValues);
+ assertFalse(status.isOk());
+ assertEquals("Expected data type 'string' saw 'integer' at arg index 1", status.getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogicalTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogicalTest.java
new file mode 100755
index 0000000..9db4610
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionLogicalTest.java
@@ -0,0 +1,402 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.DataTypes;
+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.std.StdFunctions;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionLogicalTest {
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+ // use the same args for each test
+ FunctionArgumentAttributeValue attrT = null;
+ FunctionArgumentAttributeValue attrF = null;
+ public FunctionDefinitionLogicalTest () {
+ try {
+ attrT = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(true));
+ attrF = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(false));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+ }
+
+
+ @Test
+ public void testOR() {
+ FunctionArgumentAttributeValue attr5 = null;
+ try {
+ attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_OR;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_OR, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // test normal
+ arguments.add(attrT);
+ arguments.add(attrF);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(true), resValue);
+
+ arguments.clear();
+ arguments.add(attrF);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(false), resValue);
+
+ // test no args
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(false), resValue);
+
+ // first true, second error
+ arguments.clear();
+ arguments.add(attrT);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(true), resValue);
+
+ // first false, second error
+ arguments.clear();
+ arguments.add(attrF);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:or Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // multiple false
+ arguments.clear();
+ arguments.add(attrF);
+ arguments.add(attrF);
+ arguments.add(attrF);
+ arguments.add(attrF);
+ arguments.add(attrF);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(false), resValue);
+
+ // non-boolean
+ arguments.clear();
+ arguments.add(attrF);
+ arguments.add(attr5);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:or Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // first arg error
+ arguments.clear();
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:or Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+ @Test
+ public void testAND() {
+ FunctionArgumentAttributeValue attr5 = null;
+ try {
+ attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+
+ FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_AND;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_AND, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // test normal
+ arguments.add(attrT);
+ arguments.add(attrF);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(false), resValue);
+
+ arguments.clear();
+ arguments.add(attrF);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(false), resValue);
+
+ // test no args
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(true), resValue);
+
+ // first true, second error
+ arguments.clear();
+ arguments.add(attrT);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:and Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // first false, second error
+ arguments.clear();
+ arguments.add(attrF);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(false), resValue);
+
+ // multiple true
+ arguments.clear();
+ arguments.add(attrT);
+ arguments.add(attrT);
+ arguments.add(attrT);
+ arguments.add(attrT);
+ arguments.add(attrT);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(true), resValue);
+
+ // non-boolean
+ arguments.clear();
+ arguments.add(attrT);
+ arguments.add(attr5);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals("function:and Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // first arg error
+ arguments.clear();
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals("function:and Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+ @Test
+ public void testN_of() {
+ FunctionArgumentAttributeValue attr0 = null;
+ FunctionArgumentAttributeValue attr2 = null;
+ try {
+ attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));
+ attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+
+ FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_N_OF;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_N_OF, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // test normal
+ arguments.add(attr2);
+ arguments.add(attrT);
+ arguments.add(attrF);
+ arguments.add(attrT);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(true), resValue);
+
+ // normal fail
+ arguments.clear();
+ arguments.add(attr2);
+ arguments.add(attrT);
+ arguments.add(attrF);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(false), resValue);
+
+
+ // null count
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrT);
+ arguments.add(attrF);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(true), resValue);
+
+ // 0 count
+ arguments.clear();
+ arguments.add(attr0);
+ arguments.add(attrT);
+ arguments.add(attrF);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(true), resValue);
+
+ // bad object type for count
+ arguments.clear();
+ arguments.add(attrT);
+ arguments.add(attrT);
+ arguments.add(attrF);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:n-of For input string: \"true\"", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // count larger than list
+ arguments.clear();
+ arguments.add(attr2);
+ arguments.add(attrT);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:n-of Expected 2 arguments but only 1 arguments in list after the count", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // aborts after find ok
+ arguments.clear();
+ arguments.add(attr2);
+ arguments.add(attrT);
+ arguments.add(attrT);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(true), resValue);
+
+ // error before find ok
+ arguments.clear();
+ arguments.add(attr2);
+ arguments.add(null);
+ arguments.add(attrT);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:n-of Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // non-boolean in list
+ arguments.clear();
+ arguments.add(attr2);
+ arguments.add(attrT);
+ arguments.add(attr0);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:n-of Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+ @Test
+ public void testNot() {
+
+ FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_NOT;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_NOT, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrT);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(false), resValue);
+
+ arguments.clear();
+ arguments.add(attrF);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(true), resValue);
+
+
+ // test null/0 args
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:not Expected 1 argument, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // test 2 args
+ arguments.clear();
+ arguments.add(attrT);
+ arguments.add(attrF);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:not Expected 1 argument, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversionTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversionTest.java
new file mode 100755
index 0000000..add8069
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionNumberTypeConversionTest.java
@@ -0,0 +1,99 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.DataTypes;
+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.std.StdFunctions;
+
+/**
+ * Tests for various classes containing only one function.
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionNumberTypeConversionTest {
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+ @Test
+ public void testDouble_to_integer() {
+ FunctionArgumentAttributeValue attr1 = null;
+ try {
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(5.432));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionNumberTypeConversion<?, ?> fd = (FunctionDefinitionNumberTypeConversion<?, ?>) StdFunctions.FD_DOUBLE_TO_INTEGER;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DOUBLE_TO_INTEGER, fd.getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+
+ // test normal add
+ arguments.add(attr1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ BigInteger resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(BigInteger.valueOf(5), resValue);
+ }
+
+
+ @Test
+ public void testInteger_to_double() {
+ FunctionArgumentAttributeValue attr1 = null;
+ try {
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionNumberTypeConversion<?, ?> fd = (FunctionDefinitionNumberTypeConversion<?, ?>) StdFunctions.FD_INTEGER_TO_DOUBLE;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_INTEGER_TO_DOUBLE, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+
+ // test normal add
+ arguments.add(attr1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Double resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(5.0), resValue);
+ }
+
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatchTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatchTest.java
new file mode 100755
index 0000000..1381076
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionRegexpMatchTest.java
@@ -0,0 +1,491 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacml.std.datatypes.IPAddress;
+import com.att.research.xacml.std.datatypes.RFC2396DomainName;
+import com.att.research.xacml.std.datatypes.RFC822Name;
+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.std.StdFunctions;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionRegexpMatchTest {
+
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+
+ @Test
+ public void testString() {
+ String v1 = new String("abc");
+ String v2 = new String("def");
+
+
+ FunctionArgumentAttributeValue attrV1 = null;
+ FunctionArgumentAttributeValue attrV2 = null;
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ try {
+ attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));
+ attrV2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v2));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_STRING_REGEXP_MATCH;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_REGEXP_MATCH, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // match
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrV1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // no match
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrV2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // null regex
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrV2);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-regexp-match Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrV2);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-regexp-match Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null object to match
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-regexp-match Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-regexp-match Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // regex not string
+ arguments.clear();
+ arguments.add(attrInteger);
+ arguments.add(attrV2);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-regexp-match Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // object to match not correct type
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrInteger);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-regexp-match Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+ @Test
+ public void testAnyURI() {
+ String regexp = new String("abc");
+ URI uri1 = null;
+ URI uri2 = null;
+ try {
+ uri1 = new URI("abc");
+ uri2 = new URI("def");
+ } catch (Exception e) {
+ fail("Unable to create URIs, e="+e);
+ }
+
+
+ FunctionArgumentAttributeValue attrRegexp = null;
+ FunctionArgumentAttributeValue attrUri1 = null;
+ FunctionArgumentAttributeValue attrUri2 = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ try {
+ attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp));
+ attrUri1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri1));
+ attrUri2 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri2));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_ANYURI_REGEXP_MATCH;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_ANYURI_REGEXP_MATCH, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // match
+ arguments.clear();
+ arguments.add(attrRegexp);
+ arguments.add(attrUri1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // no match
+ arguments.clear();
+ arguments.add(attrRegexp);
+ arguments.add(attrUri2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // object to match not correct type
+ arguments.clear();
+ arguments.add(attrRegexp);
+ arguments.add(attrInteger);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-regexp-match Expected data type 'anyURI' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+ @Test
+ public void testIpAddress() {
+ String regexp = new String(".*123.*");
+ IPAddress addr1 = null;
+ IPAddress addr2 = null;
+ try {
+ addr1 = IPAddress.newInstance("199.123.45.67");
+ addr2 = IPAddress.newInstance("12.34.67.87");
+ } catch (Exception e) {
+ fail("Unable to create IPAddresses, e="+e);
+ }
+
+
+ FunctionArgumentAttributeValue attrRegexp = null;
+ FunctionArgumentAttributeValue attrAddr1 = null;
+ FunctionArgumentAttributeValue attrAddr2 = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ try {
+ attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp));
+ attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(addr1));
+ attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(addr2));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_IPADDRESS_REGEXP_MATCH;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_IPADDRESS_REGEXP_MATCH, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // match
+ arguments.clear();
+ arguments.add(attrRegexp);
+ arguments.add(attrAddr1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // no match
+ arguments.clear();
+ arguments.add(attrRegexp);
+ arguments.add(attrAddr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // object to match not correct type
+ arguments.clear();
+ arguments.add(attrRegexp);
+ arguments.add(attrInteger);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-regexp-match Expected data type 'ipAddress' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+ @Test
+ public void testDnsName() {
+ String regexp = new String("abc");
+ RFC2396DomainName addr1 = null;
+ RFC2396DomainName addr2 = null;
+ try {
+ addr1 = RFC2396DomainName.newInstance("abc");
+ addr2 = RFC2396DomainName.newInstance("def");
+ } catch (Exception e) {
+ fail("Unable to create DNSNames, e="+e);
+ }
+
+
+ FunctionArgumentAttributeValue attrRegexp = null;
+ FunctionArgumentAttributeValue attrAddr1 = null;
+ FunctionArgumentAttributeValue attrAddr2 = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ try {
+ attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp));
+ attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DNSNAME.createAttributeValue(addr1));
+ attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DNSNAME.createAttributeValue(addr2));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_DNSNAME_REGEXP_MATCH;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DNSNAME_REGEXP_MATCH, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // match
+ arguments.clear();
+ arguments.add(attrRegexp);
+ arguments.add(attrAddr1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // no match
+ arguments.clear();
+ arguments.add(attrRegexp);
+ arguments.add(attrAddr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // object to match not correct type
+ arguments.clear();
+ arguments.add(attrRegexp);
+ arguments.add(attrInteger);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dnsName-regexp-match Expected data type 'dnsName' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+ @Test
+ public void testRfc822Name() {
+ String regexp = new String(".*abc.*");
+ RFC822Name addr1 = null;
+ RFC822Name addr2 = null;
+ try {
+ addr1 = RFC822Name.newInstance("abc@somewhere");
+ addr2 = RFC822Name.newInstance("def@somewhere");
+ } catch (Exception e) {
+ fail("Unable to create RFC822Names, e="+e);
+ }
+
+
+ FunctionArgumentAttributeValue attrRegexp = null;
+ FunctionArgumentAttributeValue attrAddr1 = null;
+ FunctionArgumentAttributeValue attrAddr2 = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ try {
+ attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp));
+ attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(addr1));
+ attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(addr2));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_RFC822NAME_REGEXP_MATCH;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_RFC822NAME_REGEXP_MATCH, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // match
+ arguments.clear();
+ arguments.add(attrRegexp);
+ arguments.add(attrAddr1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // no match
+ arguments.clear();
+ arguments.add(attrRegexp);
+ arguments.add(attrAddr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // object to match not correct type
+ arguments.clear();
+ arguments.add(attrRegexp);
+ arguments.add(attrInteger);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:rfc822Name-regexp-match Expected data type 'rfc822Name' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+ @Test
+ public void testX500Name() {
+ String regexp = new String(".*Duke.*");
+ X500Principal addr1 = null;
+ X500Principal addr2 = null;
+ try {
+ addr1 = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US");
+ addr2 = new X500Principal("CN=Policy Engine, OU=Research, O=ATT, C=US");
+ } catch (Exception e) {
+ fail("Unable to create X500Name, e="+e);
+ }
+
+
+ FunctionArgumentAttributeValue attrRegexp = null;
+ FunctionArgumentAttributeValue attrAddr1 = null;
+ FunctionArgumentAttributeValue attrAddr2 = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ try {
+ attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp));
+ attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(addr1));
+ attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(addr2));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_X500NAME_REGEXP_MATCH;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_X500NAME_REGEXP_MATCH, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // match
+ arguments.clear();
+ arguments.add(attrRegexp);
+ arguments.add(attrAddr1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // no match
+ arguments.clear();
+ arguments.add(attrRegexp);
+ arguments.add(attrAddr2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // object to match not correct type
+ arguments.clear();
+ arguments.add(attrRegexp);
+ arguments.add(attrInteger);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:x500Name-regexp-match Expected data type 'x500Name' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSetTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSetTest.java
new file mode 100755
index 0000000..0331386
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSetTest.java
@@ -0,0 +1,1883 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.DataTypes;
+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.FunctionArgumentBag;
+import com.att.research.xacmlatt.pdp.std.StdFunctions;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionSetTest {
+
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+
+
+ //
+ // INTERSECTION tests
+ //
+
+
+ @Test
+ public void testString_intersection() {
+ String a = "a";
+ String b = "b";
+ String c = "c";
+ String d = "d";
+ String e = "e";
+ String f = "f";
+ String g = "g";
+ String h = "h";
+ String j = "j";
+
+
+ Bag bagabcdefg = null;
+ Bag bagbdfhj = null;
+ Bag bagace = null;
+ Bag bagb = null;
+ Bag bagaaacccef = null;
+ Bag bagInt = null;
+ Bag bagStringInt = null;
+ Bag bagEmpty = null;
+
+ FunctionArgumentAttributeValue attrBadType = null;
+
+ try {
+ bagabcdefg = new Bag();
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));
+ bagbdfhj = new Bag();
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));
+ bagace = new Bag();
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagb = new Bag();
+ bagb.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagaaacccef = new Bag();
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagInt = new Bag();
+ bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagStringInt = new Bag();
+ bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagEmpty = new Bag();
+
+ attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1));
+ } catch (Exception ex) {
+ fail("creating attribute e="+ ex);
+ }
+
+ // make into attributes
+ FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);
+ FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);
+ FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);
+ FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb);
+ FunctionArgumentBag attrBagaaacccef = new FunctionArgumentBag(bagaaacccef);
+ FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt);
+ FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);
+ FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);
+
+ FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_INTERSECTION;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_INTERSECTION, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertTrue(fd.returnsBag());
+
+ // normal intersection (everything in both bags, no duplicates)
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Bag bag = res.getBag();
+ assertNotNull(bag);
+ Iterator<AttributeValue<?>> it = bag.getAttributeValues();
+ assertEquals(7, bag.size());
+ AttributeValue<?> attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+
+ // several but not all intersection
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(3, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(b, attrValueObject.getValue() );
+
+ // no intersection
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(0, bag.size());
+
+ // one intersection
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagb);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(1, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(b, attrValueObject.getValue() );
+
+ // bag one has duplicates that do not intersect
+ arguments.clear();
+ arguments.add(attrBagaaacccef);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(1, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(f, attrValueObject.getValue() );
+
+ // bag one has duplicates that do intersect
+ arguments.clear();
+ arguments.add(attrBagaaacccef);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(3, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+ attrValueObject = it.next();
+ assertEquals(c, attrValueObject.getValue() );
+ attrValueObject = it.next();
+ assertEquals(e, attrValueObject.getValue() );
+
+ // bag 2 has duplicates that do not intersect
+ arguments.clear();
+ arguments.add(attrBagbdfhj);
+ arguments.add(attrBagaaacccef);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(1, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(f, attrValueObject.getValue() );
+
+ // bag 2 has duplicates that intersect
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagaaacccef);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(3, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+ attrValueObject = it.next();
+ assertEquals(c, attrValueObject.getValue() );
+ attrValueObject = it.next();
+ assertEquals(e, attrValueObject.getValue() );
+
+ // first bag is empty
+ arguments.clear();
+ arguments.add(attrBagEmpty);
+ arguments.add(attrBagaaacccef);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(0, bag.size());
+
+ // second bag is empty
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(0, bag.size());
+
+ // bags of different types
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(1, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagInt);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(0, bag.size());
+
+ // first not a bag
+ arguments.clear();
+ arguments.add(attrBadType);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second not a bag
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // first null
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-intersection Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second null
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-intersection Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too few args
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-intersection Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-intersection Expected 2 arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many args
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-intersection Expected 2 arguments, got 3", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+ @Test
+ public void testInteger_intersection() {
+ BigInteger a = new BigInteger("1");
+ BigInteger b = new BigInteger("2");
+ BigInteger c = new BigInteger("3");
+ BigInteger d = new BigInteger("4");
+ BigInteger e = new BigInteger("5");
+ BigInteger f = new BigInteger("6");
+ BigInteger g = new BigInteger("7");
+ BigInteger h = new BigInteger("8");
+ BigInteger j = new BigInteger("9");
+
+
+ Bag bagabcdefg = null;
+ Bag bagbdfhj = null;
+ Bag bagace = null;
+ Bag bagb = null;
+ Bag bagaaacccef = null;
+ Bag bagInt = null;
+ Bag bagStringInt = null;
+ Bag bagEmpty = null;
+
+ FunctionArgumentAttributeValue attrBadType = null;
+
+ try {
+ bagabcdefg = new Bag();
+ bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(a));
+ bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(b));
+ bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(c));
+ bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(d));
+ bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(e));
+ bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(f));
+ bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(g));
+ bagbdfhj = new Bag();
+ bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(b));
+ bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(d));
+ bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(f));
+ bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(h));
+ bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(j));
+ bagace = new Bag();
+ bagace.add(DataTypes.DT_INTEGER.createAttributeValue(a));
+ bagace.add(DataTypes.DT_INTEGER.createAttributeValue(c));
+ bagace.add(DataTypes.DT_INTEGER.createAttributeValue(e));
+ bagb = new Bag();
+ bagb.add(DataTypes.DT_INTEGER.createAttributeValue(b));
+ bagaaacccef = new Bag();
+ bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(e));
+ bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(f));
+ bagInt = new Bag();
+ bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagStringInt = new Bag();
+ bagStringInt.add(DataTypes.DT_STRING.createAttributeValue("abc"));
+ bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(1));
+ bagEmpty = new Bag();
+
+ attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1));
+ } catch (Exception ex) {
+ fail("creating attribute e="+ ex);
+ }
+
+ // make into attributes
+ FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);
+ FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);
+ FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);
+ FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb);
+ FunctionArgumentBag attrBagaaacccef = new FunctionArgumentBag(bagaaacccef);
+ FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt);
+ FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);
+ FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);
+
+ FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_INTEGER_INTERSECTION;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_INTEGER_INTERSECTION, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertTrue(fd.returnsBag());
+
+ // normal intersection (everything in both bags, no duplicates)
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Bag bag = res.getBag();
+ assertNotNull(bag);
+ Iterator<AttributeValue<?>> it = bag.getAttributeValues();
+ assertEquals(7, bag.size());
+ AttributeValue<?> attrValueObject = it.next();
+ assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+
+ // several but not all intersection
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(3, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());
+ assertEquals(b, attrValueObject.getValue() );
+
+ // no intersection
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(0, bag.size());
+
+ // one intersection
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagb);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(1, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());
+ assertEquals(b, attrValueObject.getValue() );
+
+ // bag one has duplicates that do not intersect
+ arguments.clear();
+ arguments.add(attrBagaaacccef);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(1, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());
+ assertEquals(f, attrValueObject.getValue() );
+
+ // bag one has duplicates that do intersect
+ arguments.clear();
+ arguments.add(attrBagaaacccef);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(3, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+ attrValueObject = it.next();
+ assertEquals(c, attrValueObject.getValue() );
+ attrValueObject = it.next();
+ assertEquals(e, attrValueObject.getValue() );
+
+ // bag 2 has duplicates that do not intersect
+ arguments.clear();
+ arguments.add(attrBagbdfhj);
+ arguments.add(attrBagaaacccef);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(1, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());
+ assertEquals(f, attrValueObject.getValue() );
+
+ // bag 2 has duplicates that intersect
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagaaacccef);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(3, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+ attrValueObject = it.next();
+ assertEquals(c, attrValueObject.getValue() );
+ attrValueObject = it.next();
+ assertEquals(e, attrValueObject.getValue() );
+
+ // first bag is empty
+ arguments.clear();
+ arguments.add(attrBagEmpty);
+ arguments.add(attrBagaaacccef);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(0, bag.size());
+
+ // second bag is empty
+ arguments.clear();
+ arguments.add(attrBagbdfhj);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(0, bag.size());
+
+ // bags of different types
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(1, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagInt);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(1, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+
+
+ // first not a bag
+ arguments.clear();
+ arguments.add(attrBadType);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:integer-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second not a bag
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:integer-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // first null
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:integer-intersection Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second null
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:integer-intersection Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too few args
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:integer-intersection Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:integer-intersection Expected 2 arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many args
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:integer-intersection Expected 2 arguments, got 3", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+ //
+ // AT_LEAST_ONE_MEMBER_OF tests
+ //
+
+ @Test
+ public void testString_at_least_one_member_of() {
+ String a = "a";
+ String b = "b";
+ String c = "c";
+ String d = "d";
+ String e = "e";
+ String f = "f";
+ String g = "g";
+ String h = "h";
+ String j = "j";
+
+
+ Bag bagabcdefg = null;
+ Bag bagbdfhj = null;
+ Bag bagace = null;
+ Bag bagb = null;
+ Bag bagaaaccce = null;
+ Bag bagInt = null;
+ Bag bagStringInt = null;
+ Bag bagEmpty = null;
+
+ FunctionArgumentAttributeValue attrBadType = null;
+
+ try {
+ bagabcdefg = new Bag();
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));
+ bagbdfhj = new Bag();
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));
+ bagace = new Bag();
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagb = new Bag();
+ bagb.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagaaaccce = new Bag();
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagInt = new Bag();
+ bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagStringInt = new Bag();
+ bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagEmpty = new Bag();
+
+ attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1));
+ } catch (Exception ex) {
+ fail("creating attribute e="+ ex);
+ }
+
+ // make into attributes
+ FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);
+ FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);
+ FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);
+ FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb);
+ FunctionArgumentBag attrBagaaaccce = new FunctionArgumentBag(bagaaaccce);
+ FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt);
+ FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);
+ FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);
+
+ FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_AT_LEAST_ONE_MEMBER_OF;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_AT_LEAST_ONE_MEMBER_OF, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+ // normal intersection (everything in both bags, no duplicates)
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+
+ // several but not all intersection
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // no intersection
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // one intersection
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagb);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // bag one has duplicates that do not intersect
+ arguments.clear();
+ arguments.add(attrBagaaaccce);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // bag one has duplicates that do intersect
+ arguments.clear();
+ arguments.add(attrBagaaaccce);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // bag 2 has duplicates that do not intersect
+ arguments.clear();
+ arguments.add(attrBagbdfhj);
+ arguments.add(attrBagaaaccce);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // bag 2 has duplicates that intersect
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagaaaccce);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // 2 empty bags
+ arguments.clear();
+ arguments.add(attrBagEmpty);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first non-empty, 2nd empty
+ arguments.clear();
+ arguments.add(attrBagaaaccce);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first empty, 2nd not empty
+ arguments.clear();
+ arguments.add(attrBagEmpty);
+ arguments.add(attrBagaaaccce);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // bags of different types
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagInt);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first not a bag
+ arguments.clear();
+ arguments.add(attrBadType);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-at-least-one-member-of Expected a bag, saw a simple value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second not a bag
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-at-least-one-member-of Expected a bag, saw a simple value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // first null
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-at-least-one-member-of Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second null
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-at-least-one-member-of Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too few args
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-at-least-one-member-of Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-at-least-one-member-of Expected 2 arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many args
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-at-least-one-member-of Expected 2 arguments, got 3", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+ //
+ // UNION tests
+ //
+
+
+
+
+
+ @Test
+ public void testString_union() {
+ String a = "a";
+ String b = "b";
+ String c = "c";
+ String d = "d";
+ String e = "e";
+ String f = "f";
+ String g = "g";
+ String h = "h";
+ String j = "j";
+
+
+ Bag bagabcdefg = null;
+ Bag bagbdfhj = null;
+ Bag bagace = null;
+ Bag bagaaacccef = null;
+ Bag bagInt = null;
+ Bag bagStringInt = null;
+ Bag bagEmpty = null;
+
+ FunctionArgumentAttributeValue attrBadType = null;
+
+ try {
+ bagabcdefg = new Bag();
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));
+ bagbdfhj = new Bag();
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));
+ bagace = new Bag();
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagaaacccef = new Bag();
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagInt = new Bag();
+ bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagStringInt = new Bag();
+ bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagEmpty = new Bag();
+
+ attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1));
+ } catch (Exception ex) {
+ fail("creating attribute e="+ ex);
+ }
+
+ // make into attributes
+ FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);
+ FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);
+ FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);
+ FunctionArgumentBag attrBagaaacccef = new FunctionArgumentBag(bagaaacccef);
+ FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt);
+ FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);
+ FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);
+
+ FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_UNION;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_UNION, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertTrue(fd.returnsBag());
+
+ // normal intersection (everything in both bags, no duplicates)
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Bag bag = res.getBag();
+ assertNotNull(bag);
+ Iterator<AttributeValue<?>> it = bag.getAttributeValues();
+ assertEquals(7, bag.size());
+ AttributeValue<?> attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+
+ // several but not all union
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(8, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+
+ // bag one has duplicates that do not match first bag
+ arguments.clear();
+ arguments.add(attrBagaaacccef);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(8, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+
+ // bag one has duplicates that do match first bag
+ arguments.clear();
+ arguments.add(attrBagaaacccef);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(4, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+ attrValueObject = it.next();
+ assertEquals(c, attrValueObject.getValue() );
+ attrValueObject = it.next();
+ assertEquals(e, attrValueObject.getValue() );
+
+ // bag 2 has duplicates that do not match first bag
+ arguments.clear();
+ arguments.add(attrBagbdfhj);
+ arguments.add(attrBagaaacccef);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(8, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(b, attrValueObject.getValue() );
+
+ // bag 2 has duplicates that do match first bag
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagaaacccef);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(4, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+ attrValueObject = it.next();
+ assertEquals(c, attrValueObject.getValue() );
+ attrValueObject = it.next();
+ assertEquals(e, attrValueObject.getValue() );
+
+ // two empty bags
+ arguments.clear();
+ arguments.add(attrBagEmpty);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(0, bag.size());
+
+ // first bag empty, 2nd not empty
+ arguments.clear();
+ arguments.add(attrBagEmpty);
+ arguments.add(attrBagaaacccef);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(4, bag.size());
+
+ // first bag not empty, 2nd empty
+ arguments.clear();
+ arguments.add(attrBagaaacccef);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(4, bag.size());
+
+ // bags of different types
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(4, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagInt);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ bag = res.getBag();
+ assertNotNull(bag);
+ it = bag.getAttributeValues();
+ assertEquals(4, bag.size());
+ attrValueObject = it.next();
+ assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId());
+ assertEquals(a, attrValueObject.getValue() );
+
+ // first not a bag
+ arguments.clear();
+ arguments.add(attrBadType);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-union Expected a bag, saw a simple value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second not a bag
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-union Expected a bag, saw a simple value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // first null
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-union Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second null
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-union Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too few args
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-union Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-union Expected 2 arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many args
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-union Expected 2 arguments, got 3", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+
+
+
+
+
+
+ //
+ // SUBSET tests
+ //
+
+ @Test
+ public void testString_subset() {
+ String a = "a";
+ String b = "b";
+ String c = "c";
+ String d = "d";
+ String e = "e";
+ String f = "f";
+ String g = "g";
+ String h = "h";
+ String j = "j";
+
+
+ Bag bagabcdefg = null;
+ Bag bagbdfhj = null;
+ Bag bagace = null;
+ Bag bagb = null;
+ Bag bagaaaccce = null;
+ Bag bagInt = null;
+ Bag bagStringInt = null;
+ Bag bagEmpty = null;
+
+ FunctionArgumentAttributeValue attrBadType = null;
+
+ try {
+ bagabcdefg = new Bag();
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));
+ bagbdfhj = new Bag();
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));
+ bagace = new Bag();
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagb = new Bag();
+ bagb.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagaaaccce = new Bag();
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagInt = new Bag();
+ bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagStringInt = new Bag();
+ bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagEmpty = new Bag();
+
+ attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1));
+ } catch (Exception ex) {
+ fail("creating attribute e="+ ex);
+ }
+
+ // make into attributes
+ FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);
+ FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);
+ FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);
+ FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb);
+ FunctionArgumentBag attrBagaaaccce = new FunctionArgumentBag(bagaaaccce);
+ FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt);
+ FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);
+ FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);
+
+ FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_SUBSET;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_SUBSET, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+ // normal intersection (everything in both bags, no duplicates)
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+
+ // not subset
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // subset
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+
+ // no intersection
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // Not
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagb);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // Subset
+ arguments.clear();
+ arguments.add(attrBagb);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // bag one has duplicates that do not intersect
+ arguments.clear();
+ arguments.add(attrBagaaaccce);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // bag one has duplicates that do intersect
+ arguments.clear();
+ arguments.add(attrBagaaaccce);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // bag 2 has duplicates that do not intersect
+ arguments.clear();
+ arguments.add(attrBagbdfhj);
+ arguments.add(attrBagaaaccce);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // bag 2 has duplicates that intersect
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagaaaccce);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // 2 empty bags
+ arguments.clear();
+ arguments.add(attrBagEmpty);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first non-empty, 2nd empty
+ arguments.clear();
+ arguments.add(attrBagaaaccce);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first empty, 2nd not empty
+ arguments.clear();
+ arguments.add(attrBagEmpty);
+ arguments.add(attrBagaaaccce);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // bags of different types
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ arguments.clear();
+ arguments.add(attrBagb);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagInt);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first not a bag
+ arguments.clear();
+ arguments.add(attrBadType);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-subset Expected a bag, saw a simple value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second not a bag
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-subset Expected a bag, saw a simple value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // first null
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-subset Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second null
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-subset Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too few args
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-subset Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-subset Expected 2 arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many args
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-subset Expected 2 arguments, got 3", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+ //
+ // SET_EQUALS tests
+ //
+
+ @Test
+ public void testString_set_equals() {
+ String a = "a";
+ String b = "b";
+ String c = "c";
+ String d = "d";
+ String e = "e";
+ String f = "f";
+ String g = "g";
+ String h = "h";
+ String j = "j";
+
+
+ Bag bagabcdefg = null;
+ Bag bagbdfhj = null;
+ Bag bagace = null;
+ Bag bagb = null;
+ Bag bagaaaccce = null;
+ Bag bagInt = null;
+ Bag bagStringInt = null;
+ Bag bagEmpty = null;
+
+ FunctionArgumentAttributeValue attrBadType = null;
+
+ try {
+ bagabcdefg = new Bag();
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g));
+ bagbdfhj = new Bag();
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h));
+ bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j));
+ bagace = new Bag();
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagace.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagb = new Bag();
+ bagb.add(DataTypes.DT_STRING.createAttributeValue(b));
+ bagaaaccce = new Bag();
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c));
+ bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(e));
+ bagInt = new Bag();
+ bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagStringInt = new Bag();
+ bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a));
+ bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123));
+ bagEmpty = new Bag();
+
+ attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1));
+ } catch (Exception ex) {
+ fail("creating attribute e="+ ex);
+ }
+
+ // make into attributes
+ FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg);
+ FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj);
+ FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace);
+ FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb);
+ FunctionArgumentBag attrBagaaaccce = new FunctionArgumentBag(bagaaaccce);
+ FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt);
+ FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt);
+ FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty);
+
+ FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_SET_EQUALS;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_SET_EQUALS, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+ // normal intersection (everything in both bags, no duplicates)
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+
+ // several but not all intersection
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // no intersection
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // one intersection
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagb);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // bag one has duplicates that do not intersect
+ arguments.clear();
+ arguments.add(attrBagaaaccce);
+ arguments.add(attrBagbdfhj);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // bag one has duplicates that do intersect
+ arguments.clear();
+ arguments.add(attrBagaaaccce);
+ arguments.add(attrBagace);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // bag 2 has duplicates that do not intersect
+ arguments.clear();
+ arguments.add(attrBagbdfhj);
+ arguments.add(attrBagaaaccce);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // bag 2 has duplicates that intersect
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagaaaccce);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // 2 empty bags
+ arguments.clear();
+ arguments.add(attrBagEmpty);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first non-empty, 2nd empty
+ arguments.clear();
+ arguments.add(attrBagaaaccce);
+ arguments.add(attrBagEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first empty, 2nd not empty
+ arguments.clear();
+ arguments.add(attrBagEmpty);
+ arguments.add(attrBagaaaccce);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // bags of different types
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagStringInt);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ arguments.clear();
+ arguments.add(attrBagace);
+ arguments.add(attrBagInt);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first not a bag
+ arguments.clear();
+ arguments.add(attrBadType);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-set-equals Expected a bag, saw a simple value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second not a bag
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-set-equals Expected a bag, saw a simple value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // first null
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-set-equals Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // second null
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-set-equals Got null argument", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too few args
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-set-equals Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-set-equals Expected 2 arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many args
+ arguments.clear();
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ arguments.add(attrBagabcdefg);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-set-equals Expected 2 arguments, got 3", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+
+
+
+
+
+
+ //
+ //
+ // REST OF DATA TYPES OMITTED
+ // because they "should" all work the same
+ //
+ //
+
+
+
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSpecialMatchTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSpecialMatchTest.java
new file mode 100755
index 0000000..f5c786f
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionSpecialMatchTest.java
@@ -0,0 +1,467 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.DataTypes;
+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.FunctionArgumentBag;
+import com.att.research.xacmlatt.pdp.std.StdFunctions;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionSpecialMatchTest {
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+ @Test
+ public void testX500NameMatch() {
+ // assume that the contents of the name components are not significant and we can treat them as simple blocks of "<name>=<value>"
+ String A = "cn=Some person";
+ String B = "O=Medico Corp";
+ String C = "C=US";
+ String D = "DNQUALIFIER=d string";
+ String E = "SURNAME=some name";
+ String F = "INITIALS=inits";
+
+
+ X500Principal abc = new X500Principal(A + "," + B + "," + C);
+ X500Principal dabc = new X500Principal(D + "," + A + "," + B + "," + C);
+ X500Principal abcd = new X500Principal(A + "," + B + "," + C + "," + D);
+ X500Principal adbc = new X500Principal(A + "," + D + "," + B + "," + C);
+ X500Principal dcab = new X500Principal(D + "," + C + "," + A + "," + B) ;
+ X500Principal def = new X500Principal(D + "," + E + "," + F) ;
+
+
+ FunctionArgumentAttributeValue attrABC = null;
+ FunctionArgumentAttributeValue attrDABC = null;
+ FunctionArgumentAttributeValue attrABCD = null;
+ FunctionArgumentAttributeValue attrADBC = null;
+ FunctionArgumentAttributeValue attrDCAB = null;
+ FunctionArgumentAttributeValue attrDEF = null;
+
+ FunctionArgumentAttributeValue attrBad = null;
+ FunctionArgumentBag attrBag = new FunctionArgumentBag(new Bag());
+
+
+ try {
+ attrABC = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(abc));
+ attrDABC = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(dabc));
+ attrABCD = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(abcd));
+ attrADBC = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(adbc));
+ attrDCAB = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(dcab));
+ attrDEF = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(def));
+
+ attrBad = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionX500NameMatch fd = (FunctionDefinitionX500NameMatch) StdFunctions.FD_X500NAME_MATCH;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_X500NAME_MATCH, fd.getId());
+ assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+
+ // test normal, first exact match for second
+ arguments.clear();
+ arguments.add(attrABC);
+ arguments.add(attrABC);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // test first is end of second
+ arguments.clear();
+ arguments.add(attrABC);
+ arguments.add(attrDABC);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // first exact match for sub-section but not end of second
+ arguments.clear();
+ arguments.add(attrABC);
+ arguments.add(attrABCD);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // components of first match components in second but not contiguous
+ arguments.clear();
+ arguments.add(attrABC);
+ arguments.add(attrADBC);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // components of first match components in second but not in order
+ arguments.clear();
+ arguments.add(attrABC);
+ arguments.add(attrDCAB);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first does not match second at all
+ arguments.clear();
+ arguments.add(attrABC);
+ arguments.add(attrDEF);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first arg larger than 2nd arg
+ arguments.clear();
+ arguments.add(attrABCD);
+ arguments.add(attrABC);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // bad arg types
+ arguments.clear();
+ arguments.add(attrABC);
+ arguments.add(attrBad);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:x500Name-match Expected data type 'x500Name' saw 'integer' at arg index 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many args
+ arguments.clear();
+ arguments.add(attrABC);
+ arguments.add(attrABC);
+ arguments.add(attrABC);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:x500Name-match Expected 2 arguments, got 3", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too few args
+ arguments.clear();
+ arguments.add(attrABC);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:x500Name-match Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:x500Name-match Expected 2 arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // one arg is bag
+ arguments.clear();
+ arguments.add(attrABC);
+ arguments.add(attrBag);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:x500Name-match Expected a simple value, saw a bag at arg index 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null arg
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrBag);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:x500Name-match Got null argument at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+ @Test
+ public void testRfc822NameMatch() {
+
+
+
+
+ FunctionArgumentAttributeValue attrStringabcxyz = null;
+ FunctionArgumentAttributeValue attrStringABCxyz = null;
+ FunctionArgumentAttributeValue attrStringabcXYZ = null;
+ FunctionArgumentAttributeValue attrStringcx = null;
+ FunctionArgumentAttributeValue attrStringwholedomainpart = null;
+ FunctionArgumentAttributeValue attrStringWholeDomainPart = null;
+ FunctionArgumentAttributeValue attrStringWholeDomain = null;
+ FunctionArgumentAttributeValue attrStringdomainpart = null;
+ FunctionArgumentAttributeValue attrStringDomainPart = null;
+ FunctionArgumentAttributeValue attrStringdotWholeDomain = null;
+ FunctionArgumentAttributeValue attrStringdomain = null;
+
+ FunctionArgumentAttributeValue attrStringNoMatch = null;
+ FunctionArgumentAttributeValue attrStringMultipleAt = null;
+ FunctionArgumentAttributeValue attrStringMissingLocal = null;
+ FunctionArgumentAttributeValue attrStringMissingDomain = null;
+
+
+ FunctionArgumentAttributeValue attrRfcabcxyz = null;
+ FunctionArgumentAttributeValue attrRfcwholedomainpart = null;
+ FunctionArgumentAttributeValue attrRfcWholeDomainPart = null;
+
+ FunctionArgumentBag attrBag = new FunctionArgumentBag(new Bag());
+
+ try {
+ attrStringabcxyz = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc@xyz"));
+ attrStringABCxyz = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ABC@xyz"));
+ attrStringabcXYZ = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc@XYZ"));
+ attrStringcx = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("c@x"));
+ attrStringwholedomainpart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("whole.domain.part"));
+ attrStringWholeDomainPart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("Whole.Domain.Part"));
+ attrStringWholeDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("Whole.Domain"));
+ attrStringdomainpart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".domain.part"));
+ attrStringDomainPart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".Domain.Part"));
+ attrStringdotWholeDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".Whole.Domain"));
+ attrStringdomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".domain."));
+
+ attrStringNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("no match to any legal name"));
+ attrStringMultipleAt = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("name@with@multipleAts"));
+ attrStringMissingLocal = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("@multipleAts"));
+ attrStringMissingDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("localpart@"));
+
+ attrRfcabcxyz = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue("abc@xyz"));
+ attrRfcwholedomainpart = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue("abc@whole.domain.part"));
+ attrRfcWholeDomainPart = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue("abc@Whole.Domain.Part"));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionRFC822NameMatch fd = (FunctionDefinitionRFC822NameMatch) StdFunctions.FD_RFC822NAME_MATCH;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_RFC822NAME_MATCH, fd.getId());
+ assertEquals(DataTypes.DT_RFC822NAME.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // string identical to name - exact match on whole search term
+ arguments.clear();
+ arguments.add(attrStringabcxyz);
+ arguments.add(attrRfcabcxyz);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.getStatus().isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // no match local case different
+ arguments.clear();
+ arguments.add(attrStringABCxyz);
+ arguments.add(attrRfcabcxyz);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.getStatus().isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // match domain case different
+ arguments.clear();
+ arguments.add(attrStringabcXYZ);
+ arguments.add(attrRfcabcxyz);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.getStatus().isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+
+ // partial local + partial domain
+ arguments.clear();
+ arguments.add(attrStringcx);
+ arguments.add(attrRfcabcxyz);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.getStatus().isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // whole domain
+ arguments.clear();
+ arguments.add(attrStringwholedomainpart);
+ arguments.add(attrRfcwholedomainpart);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.getStatus().isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // whole domain different case
+ arguments.clear();
+ arguments.add(attrStringWholeDomainPart);
+ arguments.add(attrRfcwholedomainpart);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.getStatus().isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ arguments.clear();
+ arguments.add(attrStringwholedomainpart);
+ arguments.add(attrRfcWholeDomainPart);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.getStatus().isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // whole domain fail
+ arguments.clear();
+ arguments.add(attrStringWholeDomain);
+ arguments.add(attrRfcWholeDomainPart);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.getStatus().isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // partial domain match
+ arguments.clear();
+ arguments.add(attrStringDomainPart);
+ arguments.add(attrRfcWholeDomainPart);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.getStatus().isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // partial domain different case
+ arguments.clear();
+ arguments.add(attrStringdomainpart);
+ arguments.add(attrRfcWholeDomainPart);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.getStatus().isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // partial domain fail
+ arguments.clear();
+ arguments.add(attrStringdotWholeDomain);
+ arguments.add(attrRfcWholeDomainPart);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.getStatus().isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ arguments.clear();
+ arguments.add(attrStringdomain);
+ arguments.add(attrRfcWholeDomainPart);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.getStatus().isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // search term contains more than 1 @
+ arguments.clear();
+ arguments.add(attrStringMultipleAt);
+ arguments.add(attrRfcabcxyz);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:rfc822Name-match String contained more than 1 '@' in 'name@with@multipleAts'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // search term missing local part
+ arguments.clear();
+ arguments.add(attrStringMissingLocal);
+ arguments.add(attrRfcabcxyz);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:rfc822Name-match String missing local part in '@multipleAts'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // search term missing domain part
+ arguments.clear();
+ arguments.add(attrStringMissingDomain);
+ arguments.add(attrRfcabcxyz);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:rfc822Name-match String missing domain part in 'localpart@'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg types
+ arguments.clear();
+ arguments.add(attrRfcabcxyz);
+ arguments.add(attrStringNoMatch);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:rfc822Name-match Expected data type 'string' saw 'rfc822Name' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many args
+ arguments.clear();
+ arguments.add(attrStringNoMatch);
+ arguments.add(attrStringNoMatch);
+ arguments.add(attrStringNoMatch);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:rfc822Name-match Expected 2 arguments, got 3", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too few args
+ arguments.clear();
+ arguments.add(attrStringNoMatch);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:rfc822Name-match Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:rfc822Name-match Expected 2 arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // one arg is bag
+ arguments.clear();
+ arguments.add(attrStringNoMatch);
+ arguments.add(attrBag);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:rfc822Name-match Expected a simple value, saw a bag at arg index 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null arg
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrStringNoMatch);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:rfc822Name-match Got null argument at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+
+ }
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversionTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversionTest.java
new file mode 100755
index 0000000..8800097
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringConversionTest.java
@@ -0,0 +1,2484 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.math.BigInteger;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacml.std.datatypes.IPAddress;
+import com.att.research.xacml.std.datatypes.IPv4Address;
+import com.att.research.xacml.std.datatypes.IPv6Address;
+import com.att.research.xacml.std.datatypes.ISO8601Date;
+import com.att.research.xacml.std.datatypes.ISO8601DateTime;
+import com.att.research.xacml.std.datatypes.ISO8601Time;
+import com.att.research.xacml.std.datatypes.ISO8601TimeZone;
+import com.att.research.xacml.std.datatypes.PortRange;
+import com.att.research.xacml.std.datatypes.RFC2396DomainName;
+import com.att.research.xacml.std.datatypes.RFC822Name;
+import com.att.research.xacml.std.datatypes.XPathDayTimeDuration;
+import com.att.research.xacml.std.datatypes.XPathYearMonthDuration;
+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.std.StdFunctions;
+
+/**
+ * Tests for converting objects to/from Strings.
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionStringConversionTest {
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+
+ /**
+ * Boolean
+ */
+ @Test
+ public void testBoolean_from_string() {
+ FunctionArgumentAttributeValue attrString1 = null;
+ FunctionArgumentAttributeValue attrStringBadValue = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ try {
+ attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("true"));
+ attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_BOOLEAN_FROM_STRING;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrString1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(new Boolean(true), resValue);
+
+ // bad value
+ arguments.clear();
+ arguments.add(attrStringBadValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:boolean-from-string Cannot convert from \"java.lang.String\" with value \"not valid obj value\" to boolean", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:boolean-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+ @Test
+ public void testString_from_boolean() {
+ FunctionArgumentAttributeValue attrObj1 = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ String objValueString = "false";
+ try {
+ attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(objValueString));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_BOOLEAN;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_FROM_BOOLEAN, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrObj1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(objValueString, res.getValue().getValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-from-boolean Expected data type 'boolean' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+
+ /**
+ * Integer
+ */
+ @Test
+ public void testInteger_from_string() {
+ FunctionArgumentAttributeValue attrString1 = null;
+ FunctionArgumentAttributeValue attrStringBadValue = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ try {
+ attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123456"));
+ attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_INTEGER_FROM_STRING;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_INTEGER_FROM_STRING, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrString1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ BigInteger resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("123456"), resValue);
+
+ // bad value
+ arguments.clear();
+ arguments.add(attrStringBadValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:integer-from-string For input string: \"n\"", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:integer-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+ @Test
+ public void testString_from_integer() {
+ FunctionArgumentAttributeValue attrObj1 = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ String objValueString = "1234";
+ try {
+ attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(objValueString));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_INTEGER;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_FROM_INTEGER, fd.getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrObj1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(objValueString, res.getValue().getValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-from-integer Expected data type 'integer' saw 'double' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+ /**
+ * Double
+ */
+ @Test
+ public void testDouble_from_string() {
+ FunctionArgumentAttributeValue attrString1 = null;
+ FunctionArgumentAttributeValue attrStringBadValue = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ try {
+ attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("5.432"));
+ attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DOUBLE_FROM_STRING;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DOUBLE_FROM_STRING, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrString1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Double resValue = (Double)res.getValue().getValue();
+ assertEquals(new Double(5.432), resValue);
+
+ // bad value
+ arguments.clear();
+ arguments.add(attrStringBadValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:double-from-string For input string: \"not valid obj value\"", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:double-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+ @Test
+ public void testString_from_double() {
+ FunctionArgumentAttributeValue attrObj1 = null;
+ FunctionArgumentAttributeValue attrObjBig = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ String objValueString = "5.432";
+ String objValueStringBig = "55555555555555555555.123455";
+ try {
+ attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(objValueString));
+ attrObjBig = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(objValueStringBig));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DOUBLE;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DOUBLE, fd.getId());
+ assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrObj1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(objValueString, res.getValue().getValue());
+
+ arguments.clear();
+ arguments.add(attrObjBig);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals("5.555555555555556E19", res.getValue().getValue());
+
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-from-double Expected data type 'double' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+
+
+ /**
+ * Time
+ */
+ @Test
+ public void testTime_from_string() {
+ FunctionArgumentAttributeValue attrString1 = null;
+ FunctionArgumentAttributeValue attrString2 = null;
+ FunctionArgumentAttributeValue attrString3 = null;
+ FunctionArgumentAttributeValue attrString4 = null;
+ FunctionArgumentAttributeValue attrStringTimeZone = null;
+ FunctionArgumentAttributeValue attrStringBadValue = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ try {
+ attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12:34.323"));
+ attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("5:12:34.323"));
+ attrString3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12"));
+ attrString4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12:34"));
+ attrStringTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12:34.323+03:00"));
+ attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_TIME_FROM_STRING;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_TIME_FROM_STRING, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrString1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ ISO8601Time resValue = (ISO8601Time)res.getValue().getValue();
+ assertEquals(new ISO8601Time(5, 12, 34, 323), resValue);
+
+ // check missing 0 in front
+ arguments.clear();
+ arguments.add(attrString2);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:time-from-string Invalid hour of day", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // check missing seconds/msecs
+ arguments.clear();
+ arguments.add(attrString3);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:time-from-string Time string too short", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // check missing just msecs
+ arguments.clear();
+ arguments.add(attrString4);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (ISO8601Time)res.getValue().getValue();
+ assertEquals(new ISO8601Time(5, 12, 34, 0), resValue);
+
+ // check TimeZone
+ arguments.clear();
+ arguments.add(attrStringTimeZone);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (ISO8601Time)res.getValue().getValue();
+ assertEquals(new ISO8601Time(new ISO8601TimeZone(180), 5, 12, 34, 323), resValue);
+
+ // bad value
+ arguments.clear();
+ arguments.add(attrStringBadValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:time-from-string Invalid hour of day", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:time-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+ @Test
+ public void testString_from_time() {
+ FunctionArgumentAttributeValue attrObj1 = null;
+ FunctionArgumentAttributeValue attrObj2 = null;
+ FunctionArgumentAttributeValue attrObjTimeZone = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ try {
+ attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue("05:12:34.323"));
+ attrObj2 = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue("05:01:02.323"));
+ attrObjTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue("05:12:34.323+03:00"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_TIME;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_FROM_TIME, fd.getId());
+ assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrObj1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals("05:12:34.323", res.getValue().getValue());
+
+ // missing digits in string value?
+ arguments.clear();
+ arguments.add(attrObj2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals("05:01:02.323", res.getValue().getValue());
+
+ // include TimeZone
+ arguments.clear();
+ arguments.add(attrObjTimeZone);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals("05:12:34.323+03:00", res.getValue().getValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-from-time Expected data type 'time' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+
+
+ /**
+ * Date
+ */
+ @Test
+ public void testDate_from_string() {
+ FunctionArgumentAttributeValue attrString1 = null;
+ FunctionArgumentAttributeValue attrString2 = null;
+ FunctionArgumentAttributeValue attrString3 = null;
+ FunctionArgumentAttributeValue attrString4 = null;
+ FunctionArgumentAttributeValue attrString5 = null;
+ FunctionArgumentAttributeValue attrString6 = null;
+ FunctionArgumentAttributeValue attrString7 = null;
+ FunctionArgumentAttributeValue attrString8 = null;
+ FunctionArgumentAttributeValue attrString9 = null;
+ FunctionArgumentAttributeValue attrStringDateZone = null;
+ FunctionArgumentAttributeValue attrStringBadValue = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ try {
+ attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12"));
+ attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-2013-05-12"));
+ attrString3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("1232013-05-12"));
+ attrString4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-1232013-05-12"));
+ attrString5 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("213-05-12"));
+ attrString6 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-5-12"));
+ attrString7 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-2"));
+ attrString8 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-32-12"));
+ attrString9 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-45"));
+ attrStringDateZone = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12+03:00"));
+ attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DATE_FROM_STRING;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATE_FROM_STRING, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrString1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ ISO8601Date resValue = (ISO8601Date)res.getValue().getValue();
+ assertEquals(new ISO8601Date(2013, 5, 12), resValue);
+
+ // check negative
+ arguments.clear();
+ arguments.add(attrString2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ assertEquals(new ISO8601Date(-2013, 5, 12), resValue);
+
+ // check big
+ arguments.clear();
+ arguments.add(attrString3);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ assertEquals(new ISO8601Date(1232013, 5, 12), resValue);
+
+ // check big negative
+ arguments.clear();
+ arguments.add(attrString4);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ assertEquals(new ISO8601Date(-1232013, 5, 12), resValue);
+
+ // bad year
+ arguments.clear();
+ arguments.add(attrString5);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-from-string Invalid year (must be at least 4 digits)", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad month
+ arguments.clear();
+ arguments.add(attrString6);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-from-string Invalid month", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad day format
+ arguments.clear();
+ arguments.add(attrString7);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-from-string Invalid day", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // month out of range
+ arguments.clear();
+ arguments.add(attrString8);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-from-string Invalid month", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // day out of range
+ arguments.clear();
+ arguments.add(attrString9);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-from-string Invalid day", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // check TimeZone
+ arguments.clear();
+ arguments.add(attrStringDateZone);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (ISO8601Date)res.getValue().getValue();
+ assertEquals(new ISO8601Date(new ISO8601TimeZone(180), 2013, 5, 12), resValue);
+
+ // bad value
+ arguments.clear();
+ arguments.add(attrStringBadValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-from-string Invalid year", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:date-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+ @Test
+ public void testString_from_date() {
+ FunctionArgumentAttributeValue attrObj1 = null;
+ FunctionArgumentAttributeValue attrObj2 = null;
+ FunctionArgumentAttributeValue attrObjDateZone = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ try {
+ attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue("2013-05-12"));
+ attrObj2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue("0001-01-01"));
+ attrObjDateZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue("2013-05-12+03:00"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DATE;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DATE, fd.getId());
+ assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrObj1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals("2013-05-12", res.getValue().getValue());
+
+ // missing digits in string value?
+ arguments.clear();
+ arguments.add(attrObj2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals("1-01-01", res.getValue().getValue());
+
+ // include DateZone
+ arguments.clear();
+ arguments.add(attrObjDateZone);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals("2013-05-12+03:00", res.getValue().getValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-from-date Expected data type 'date' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+
+
+
+ /**
+ * DateTime
+ */
+ @Test
+ public void testDateTime_from_string() {
+ FunctionArgumentAttributeValue attrString1 = null;
+ FunctionArgumentAttributeValue attrString2 = null;
+ FunctionArgumentAttributeValue attrString3 = null;
+ FunctionArgumentAttributeValue attrString4 = null;
+ FunctionArgumentAttributeValue attrString5 = null;
+ FunctionArgumentAttributeValue attrString6 = null;
+ FunctionArgumentAttributeValue attrString7 = null;
+ FunctionArgumentAttributeValue attrString8 = null;
+ FunctionArgumentAttributeValue attrString9 = null;
+ FunctionArgumentAttributeValue attrStringDateTimeZone = null;
+ FunctionArgumentAttributeValue attrStringBadValue = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ try {
+ attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12T12:14:15.323"));
+ attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-2013-05-12T12:14:15.323"));
+ attrString3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("1232013-05-12T12:14:15.323"));
+ attrString4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-1232013-05-12T12:14:15.323"));
+ attrString5 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("213-05-12T12:14:15.323"));
+ attrString6 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-5-12T12:14:15.323"));
+ attrString7 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-2T12:14:15.323"));
+ attrString8 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-32-12T12:14:15.323"));
+ attrString9 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-45T12:14:15.323"));
+ attrStringDateTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12T12:14:15.323+03:00"));
+ attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DATETIME_FROM_STRING;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DATETIME_FROM_STRING, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrString1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue();
+ assertEquals(new ISO8601DateTime(null, new ISO8601Date(2013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue);
+
+ // check negative
+ arguments.clear();
+ arguments.add(attrString2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ assertEquals(new ISO8601DateTime(null, new ISO8601Date(-2013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue);
+
+
+ // check big
+ arguments.clear();
+ arguments.add(attrString3);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ assertEquals(new ISO8601DateTime(null, new ISO8601Date(1232013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue);
+
+ // check big negative
+ arguments.clear();
+ arguments.add(attrString4);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ assertEquals(new ISO8601DateTime(null, new ISO8601Date(-1232013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue);
+
+ // bad year
+ arguments.clear();
+ arguments.add(attrString5);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-from-string Invalid year (must be at least 4 digits)", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad month
+ arguments.clear();
+ arguments.add(attrString6);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-from-string Invalid month", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad day format
+ arguments.clear();
+ arguments.add(attrString7);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-from-string Invalid day", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // month out of range
+ arguments.clear();
+ arguments.add(attrString8);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-from-string Invalid month", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // day out of range
+ arguments.clear();
+ arguments.add(attrString9);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-from-string Invalid day", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // check TimeZone
+ arguments.clear();
+ arguments.add(attrStringDateTimeZone);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (ISO8601DateTime)res.getValue().getValue();
+ assertEquals(new ISO8601DateTime(new ISO8601TimeZone(180), new ISO8601Date(new ISO8601TimeZone(180), 2013, 5, 12), new ISO8601Time(new ISO8601TimeZone(180),12, 14, 15, 323)), resValue);
+
+ // bad value
+ arguments.clear();
+ arguments.add(attrStringBadValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-from-string Invalid year", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dateTime-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+ @Test
+ public void testString_from_dateTime() {
+ FunctionArgumentAttributeValue attrObj1 = null;
+ FunctionArgumentAttributeValue attrObj2 = null;
+ FunctionArgumentAttributeValue attrObjDateTimeZone = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ try {
+ attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue("2013-05-12T12:14:15.323"));
+ attrObj2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue("0001-01-01T12:14:15.323"));
+ attrObjDateTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue("2013-05-12T12:14:15.323+03:00"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DATETIME;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DATETIME, fd.getId());
+ assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrObj1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals("2013-05-12T12:14:15.323", res.getValue().getValue());
+
+ // missing digits in string value?
+ arguments.clear();
+ arguments.add(attrObj2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals("1-01-01T12:14:15.323", res.getValue().getValue());
+
+ // include DateTimeZone
+ arguments.clear();
+ arguments.add(attrObjDateTimeZone);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals("2013-05-12T12:14:15.323+03:00", res.getValue().getValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-from-dateTime Expected data type 'dateTime' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+
+
+ /**
+ * URI
+ */
+ @Test
+ public void testURI_from_string() {
+ FunctionArgumentAttributeValue attrString1 = null;
+ FunctionArgumentAttributeValue attrStringBadValue = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ try {
+ attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("http://someMachine.com/subdir"));
+ attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_ANYURI_FROM_STRING;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_ANYURI_FROM_STRING, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrString1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ URI resValue = (URI)res.getValue().getValue();
+ try {
+ assertEquals(new URI("http://someMachine.com/subdir"), resValue);
+ } catch (URISyntaxException e) {
+ fail("uri generation e="+e);
+ }
+
+ // bad value
+ arguments.clear();
+ arguments.add(attrStringBadValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-from-string Illegal character in path at index 3: not valid obj value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+ @Test
+ public void testString_from_anyURI() {
+ FunctionArgumentAttributeValue attrObj1 = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ String objValueString = "http://aMachine.com:8080/aRef";
+ try {
+ attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(objValueString));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_ANYURI;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_FROM_ANYURI, fd.getId());
+ assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrObj1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(objValueString, res.getValue().getValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-from-anyURI Expected data type 'anyURI' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+ /**
+ * XPathDayTimeDuration
+ */
+ @Test
+ public void testXPathDayTimeDuration_from_string() {
+ FunctionArgumentAttributeValue attrString1 = null;
+ FunctionArgumentAttributeValue attrStringNeg1 = null;
+ FunctionArgumentAttributeValue attrStringNeg2 = null;
+ FunctionArgumentAttributeValue attrStringNoDay = null;
+ FunctionArgumentAttributeValue attrStringNoHour = null;
+ FunctionArgumentAttributeValue attrStringNoMin = null;
+ FunctionArgumentAttributeValue attrStringNoSec = null;
+ FunctionArgumentAttributeValue attrStringNoP = null;
+ FunctionArgumentAttributeValue attrStringSecondsDot = null;
+ FunctionArgumentAttributeValue attrStringMissingTOk = null;
+ FunctionArgumentAttributeValue attrStringMissingTBad = null;
+ FunctionArgumentAttributeValue attrStringBadValue = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ try {
+ attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H30M23S"));
+ attrStringNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-P3DT10H30M23S"));
+ attrStringNeg2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P-3DT10H30M23S"));
+ attrStringNoDay = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("PT10H30M23S"));
+ attrStringNoHour = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT30M23S"));
+ attrStringNoMin = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H23S"));
+ attrStringNoSec = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H30M"));
+ attrStringNoP = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("3DT10H30M"));
+ attrStringSecondsDot = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H30M23.456S"));
+ attrStringMissingTOk = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D"));
+ attrStringMissingTBad = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D10H30M23S"));
+
+ attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DAYTIMEDURATION_FROM_STRING;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DAYTIMEDURATION_FROM_STRING, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrString1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ XPathDayTimeDuration resValue = (XPathDayTimeDuration)res.getValue().getValue();
+ assertEquals(new XPathDayTimeDuration(1, 3, 10, 30, 23), resValue);
+
+
+ // negative values in front is allowed
+ arguments.clear();
+ arguments.add(attrStringNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (XPathDayTimeDuration)res.getValue().getValue();
+ assertEquals(new XPathDayTimeDuration(-1, 3, 10, 30, 23), resValue);
+
+ // negative in middle of string not ok
+ arguments.clear();
+ arguments.add(attrStringNeg2);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dayTimeDuration-from-string Invalid chunk \"P-3DT10H30M23S\" at position 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // omit parts that are 0
+ arguments.clear();
+ arguments.add(attrStringNoDay);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (XPathDayTimeDuration)res.getValue().getValue();
+ assertEquals(new XPathDayTimeDuration(1, 0, 10, 30, 23), resValue);
+
+ arguments.clear();
+ arguments.add(attrStringNoHour);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (XPathDayTimeDuration)res.getValue().getValue();
+ assertEquals(new XPathDayTimeDuration(1, 3, 0, 30, 23), resValue);
+
+ arguments.clear();
+ arguments.add(attrStringNoMin);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (XPathDayTimeDuration)res.getValue().getValue();
+ assertEquals(new XPathDayTimeDuration(1, 3, 10, 0, 23), resValue);
+
+ arguments.clear();
+ arguments.add(attrStringNoSec);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (XPathDayTimeDuration)res.getValue().getValue();
+ assertEquals(new XPathDayTimeDuration(1, 3, 10, 30, 0), resValue);
+
+ // P must always be present
+ arguments.clear();
+ arguments.add(attrStringNoP);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dayTimeDuration-from-string Invalid ISO8601 duration string \"3DT10H30M\" at position 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // seconds may contain decimal
+ arguments.clear();
+ arguments.add(attrStringSecondsDot);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (XPathDayTimeDuration)res.getValue().getValue();
+ assertEquals(new XPathDayTimeDuration(1, 3, 10, 30, 23.456), resValue);
+
+ // T must be absent iff all time items are absent
+ arguments.clear();
+ arguments.add(attrStringMissingTOk);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (XPathDayTimeDuration)res.getValue().getValue();
+ assertEquals(new XPathDayTimeDuration(1, 3, 0, 0, 0), resValue);
+
+ // negative in middle of string not ok
+ arguments.clear();
+ arguments.add(attrStringMissingTBad);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dayTimeDuration-from-string Invalid ISO8601 duration string \"P3D10H30M23S\" at position 6: out of order component", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // bad value
+ arguments.clear();
+ arguments.add(attrStringBadValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dayTimeDuration-from-string Invalid ISO8601 duration string \"not valid obj value\" at position 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dayTimeDuration-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+ @Test
+ public void testString_from_dayTimeDuration() {
+ FunctionArgumentAttributeValue attrObj1 = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ String objValueString = "P3DT10H30M23S";
+ try {
+ attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(objValueString));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DAYTIMEDURATION;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DAYTIMEDURATION, fd.getId());
+ assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrObj1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(objValueString, res.getValue().getValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-from-dayTimeDuration Expected data type 'dayTimeDuration' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+
+
+
+
+
+
+ /**
+ * XPathYearMonthDuration
+ */
+ @Test
+ public void testXPathYearMonthDuration_from_string() {
+ FunctionArgumentAttributeValue attrString1 = null;
+ FunctionArgumentAttributeValue attrStringNeg1 = null;
+ FunctionArgumentAttributeValue attrStringNeg2 = null;
+ FunctionArgumentAttributeValue attrStringNoYear1 = null;
+ FunctionArgumentAttributeValue attrStringNoYear2 = null;
+ FunctionArgumentAttributeValue attrStringNoMonth1 = null;
+ FunctionArgumentAttributeValue attrStringNoMonth2 = null;
+ FunctionArgumentAttributeValue attrStringNoValue = null;
+ FunctionArgumentAttributeValue attrStringNoP = null;
+ FunctionArgumentAttributeValue attrStringBigMonths = null;
+ FunctionArgumentAttributeValue attrStringMissingTOk = null;
+ FunctionArgumentAttributeValue attrStringMissingTBad = null;
+ FunctionArgumentAttributeValue attrStringZeroMonths = null;
+ FunctionArgumentAttributeValue attrStringBadValue = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ try {
+ attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1Y2M"));
+ attrStringNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-P1Y2M"));
+ attrStringNeg2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P-1Y2M"));
+ attrStringNoYear1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P2M"));
+ attrStringNoYear2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("PY2M"));
+ attrStringNoMonth1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1Y"));
+ attrStringNoMonth2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1YM"));
+ attrStringNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P"));
+ attrStringNoP = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("1Y2M"));
+ attrStringBigMonths = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1Y12M"));
+ attrStringMissingTOk = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D"));
+ attrStringMissingTBad = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D10H30M23S"));
+ attrStringZeroMonths = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P0M"));
+
+ attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_YEARMONTHDURATION_FROM_STRING;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_YEARMONTHDURATION_FROM_STRING, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrString1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ XPathYearMonthDuration resValue = (XPathYearMonthDuration)res.getValue().getValue();
+ assertEquals(new XPathYearMonthDuration(1,1, 2), resValue);
+
+
+ // negative values in front is allowed
+ arguments.clear();
+ arguments.add(attrStringNeg1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (XPathYearMonthDuration)res.getValue().getValue();
+ assertEquals(new XPathYearMonthDuration(-1, 1, 2), resValue);
+
+ // negative in middle of string not ok
+ arguments.clear();
+ arguments.add(attrStringNeg2);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:yearMonthDuration-from-string Invalid chunk \"P-1Y2M\" at position 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // omit parts that are 0
+ arguments.clear();
+ arguments.add(attrStringNoYear1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (XPathYearMonthDuration)res.getValue().getValue();
+ assertEquals(new XPathYearMonthDuration(1, 0, 2), resValue);
+
+ arguments.clear();
+ arguments.add(attrStringNoYear2);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:yearMonthDuration-from-string Invalid chunk \"PY2M\" at position 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ arguments.clear();
+ arguments.add(attrStringNoMonth1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (XPathYearMonthDuration)res.getValue().getValue();
+ assertEquals(new XPathYearMonthDuration(1, 1, 0), resValue);
+
+ arguments.clear();
+ arguments.add(attrStringNoMonth2);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:yearMonthDuration-from-string Invalid chunk \"P1YM\" at position 3", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // No field with a value
+ arguments.clear();
+ arguments.add(attrStringNoValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"P\": No duration components following P", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // P must always be present
+ arguments.clear();
+ arguments.add(attrStringNoP);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"1Y2M\" at position 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // Canonical Form of output may not have more than 12 months, but input as string is ok?
+ arguments.clear();
+ arguments.add(attrStringBigMonths);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (XPathYearMonthDuration)res.getValue().getValue();
+ assertEquals(new XPathYearMonthDuration(1, 1, 12), resValue);
+
+ // Canonical representation of 0 Months
+ arguments.clear();
+ arguments.add(attrStringZeroMonths);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (XPathYearMonthDuration)res.getValue().getValue();
+ assertEquals(new XPathYearMonthDuration(1, 0, 0), resValue);
+
+ // T must be absent iff all time items are absent
+ arguments.clear();
+ arguments.add(attrStringMissingTOk);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:yearMonthDuration-from-string Invalid XPath yearMonthDuraiton \"{durationSign=1years=0months=0days=3hours=0minutes=0seconds=0millis=0}\": includes days, hours, minutes, or seconds", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // negative in middle of string not ok
+ arguments.clear();
+ arguments.add(attrStringMissingTBad);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"P3D10H30M23S\" at position 6: out of order component", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // bad value
+ arguments.clear();
+ arguments.add(attrStringBadValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"not valid obj value\" at position 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:yearMonthDuration-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+ @Test
+ public void testString_from_yearMonthDuration() {
+ FunctionArgumentAttributeValue attrObj1 = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ String objValueString = "P1Y2M";
+ try {
+ attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(objValueString));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_YEARMONTHDURATION;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_FROM_YEARMONTHDURATION, fd.getId());
+ assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrObj1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(objValueString, res.getValue().getValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-from-yearMonthDuration Expected data type 'yearMonthDuration' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+
+
+
+ /**
+ * X500Principal
+ *
+ * See http://www.ietf.org/rfc/rfc2253.txt and http://www.ietf.org/rfc/rfc2251.txt
+ */
+ @Test
+ public void testX500Principal_from_string() {
+ FunctionArgumentAttributeValue attrString1 = null;
+ FunctionArgumentAttributeValue attrStringNoComma = null;
+ FunctionArgumentAttributeValue attrStringEmpty = null;
+ FunctionArgumentAttributeValue attrStringNoValue = null;
+ FunctionArgumentAttributeValue attrStringOrder = null;
+ FunctionArgumentAttributeValue attrStringDottedDecimalOID = null;
+ FunctionArgumentAttributeValue attrStringBadValue = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ try {
+ attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("CN=Name, L=local, ST=NJ, O=ATT, C=USA"));
+ attrStringNoComma = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("CN=Name, L=local ST=NJ, O=ATT, C=USA"));
+ attrStringEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));
+ attrStringNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("CN=Name, L=, ST=NJ, O=ATT, C=USA"));
+ attrStringOrder = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("L=local, ST=NJ, O=ATT, CN=Name, C=USA"));
+ attrStringDottedDecimalOID = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2.5.4.3=A. N. Other"));
+
+ attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_X500NAME_FROM_STRING;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_X500NAME_FROM_STRING, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrString1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ X500Principal resValue = (X500Principal)res.getValue().getValue();
+ assertEquals(new X500Principal("CN=Name, L=local, ST=NJ, O=ATT, C=USA"), resValue);
+
+ // no comma between components => next attribute/value is included as part of first value
+ arguments.clear();
+ arguments.add(attrStringNoComma);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (X500Principal)res.getValue().getValue();
+ assertEquals(new X500Principal("CN=Name, L=local ST=NJ, O=ATT, C=USA"), resValue);
+
+ // nothing in name (fail)
+ arguments.clear();
+ arguments.add(attrStringEmpty);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (X500Principal)res.getValue().getValue();
+ assertEquals(new X500Principal(""), resValue);
+
+ // type value with no =
+ arguments.clear();
+ arguments.add(attrStringNoValue);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (X500Principal)res.getValue().getValue();
+ assertEquals(new X500Principal("CN=Name, L=, ST=NJ, O=ATT, C=USA"), resValue);
+
+ // different order
+ arguments.clear();
+ arguments.add(attrStringOrder);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (X500Principal)res.getValue().getValue();
+ assertNotEquals(new X500Principal("CN=Name, L=local, ST=NJ, O=ATT, C=USA"), resValue);
+
+ // dotted-decimal name with numbers
+ arguments.clear();
+ arguments.add(attrStringDottedDecimalOID);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (X500Principal)res.getValue().getValue();
+ assertEquals(new X500Principal("2.5.4.3=A. N. Other"), resValue);
+
+
+
+ // bad value
+ arguments.clear();
+ arguments.add(attrStringBadValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:x500Name-from-string improperly specified input name: not valid obj value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:x500Name-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+ @Test
+ public void testString_from_x500Name() {
+ FunctionArgumentAttributeValue attrObj1 = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ String objValueString = "CN=Name, L=local, ST=NJ, O=ATT, C=USA";
+ try {
+ attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(objValueString));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_X500NAME;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_FROM_X500NAME, fd.getId());
+ assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrObj1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(objValueString, res.getValue().getValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-from-x500Name Expected data type 'x500Name' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+
+ /**
+ * RFC822Name
+ */
+ @Test
+ public void testRFC822Name_from_string() {
+ FunctionArgumentAttributeValue attrString1 = null;
+ FunctionArgumentAttributeValue attrStringCapsDomain = null;
+ FunctionArgumentAttributeValue attrStringCapsLocal = null;
+ FunctionArgumentAttributeValue attrStringMissingAt = null;
+ FunctionArgumentAttributeValue attrStringMissingLocal = null;
+ FunctionArgumentAttributeValue attrStringMissingDomain = null;
+ FunctionArgumentAttributeValue attrStringEmpty = null;
+ FunctionArgumentAttributeValue attrStringBadValue = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ try {
+ attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("local@Domain"));
+ attrStringCapsDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("local@DOMAIN"));
+ attrStringCapsLocal = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("LOCAL@Domain"));
+ attrStringMissingAt = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("localDomain"));
+ attrStringMissingLocal = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("@Domain"));
+ attrStringMissingDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("local@"));
+ attrStringEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));
+
+ attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_RFC822NAME_FROM_STRING;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_RFC822NAME_FROM_STRING, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_RFC822NAME.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrString1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ RFC822Name resValue = (RFC822Name)res.getValue().getValue();
+ assertEquals(new RFC822Name("local", "domain"), resValue);
+
+ // caps domain
+ arguments.clear();
+ arguments.add(attrStringCapsDomain);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (RFC822Name)res.getValue().getValue();
+ assertEquals(new RFC822Name("local", "domain"), resValue);
+
+ // caps local
+ arguments.clear();
+ arguments.add(attrStringCapsLocal);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (RFC822Name)res.getValue().getValue();
+ assertNotEquals(new RFC822Name("local", "domain"), resValue);
+
+ // missing at
+ arguments.clear();
+ arguments.add(attrStringMissingAt);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"localDomain\": missing local part", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // missing local
+ arguments.clear();
+ arguments.add(attrStringMissingLocal);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"@Domain\": empty parts", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // missing domain
+ arguments.clear();
+ arguments.add(attrStringMissingDomain);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"local@\": empty parts", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // empty
+ arguments.clear();
+ arguments.add(attrStringEmpty);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"\": missing local part", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // bad value
+ arguments.clear();
+ arguments.add(attrStringBadValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"not valid obj value\": missing local part", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:rfc822Name-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+ @Test
+ public void testString_from_rfc822Name() {
+ FunctionArgumentAttributeValue attrObj1 = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ String objValueString = "local@DOMAIN";
+ try {
+ attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(objValueString));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_RFC822NAME;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_FROM_RFC822NAME, fd.getId());
+ assertEquals(DataTypes.DT_RFC822NAME.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrObj1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals("local@domain", res.getValue().getValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-from-rfc822Name Expected data type 'rfc822Name' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+
+ /**
+ * IPAddress
+ */
+ @Test
+ public void testIPAddress_from_string() {
+ FunctionArgumentAttributeValue attrString1 = null;
+ FunctionArgumentAttributeValue attrStringFull = null;
+ FunctionArgumentAttributeValue attrStringMissingElement = null;
+ FunctionArgumentAttributeValue attrStringTooManyElement = null;
+ FunctionArgumentAttributeValue attrStringIllegalElement = null;
+ FunctionArgumentAttributeValue attrStringOutOfOrder = null;
+
+ FunctionArgumentAttributeValue attrStringMask = null;
+ FunctionArgumentAttributeValue attrStringMissingMaskElement = null;
+ FunctionArgumentAttributeValue attrStringTooManyMaskElement = null;
+ FunctionArgumentAttributeValue attrStringIllegalMaskElement = null;
+ FunctionArgumentAttributeValue attrStringMaskNoValue = null;
+
+ FunctionArgumentAttributeValue attrStringMinusPort = null;
+ FunctionArgumentAttributeValue attrStringPortMinus = null;
+ FunctionArgumentAttributeValue attrStringPortPort = null;
+ FunctionArgumentAttributeValue attrStringNoPort = null;
+ FunctionArgumentAttributeValue attrStringBadPort = null;
+ FunctionArgumentAttributeValue attrStringTooManyPorts = null;
+ FunctionArgumentAttributeValue attrStringBadValue = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+
+ // set up for v4 address tests - this setup and the tests are repeated for V6
+ short[] addrShorts= {123, 134, 156, 255 };
+ short[] addrMaskShorts= {255, 255, 255, 255 };
+ try {
+ attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255"));
+ attrStringFull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/255.255.255.255:123-456"));
+ attrStringMissingElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.255"));
+ attrStringTooManyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.255.111.222"));
+ attrStringIllegalElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.256.255"));
+ attrStringOutOfOrder = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.256.255:123-456/255.255.255.255"));
+
+ attrStringMask = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/255.255.255.255"));
+ attrStringMissingMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/123.134.255"));
+ attrStringTooManyMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/122.134.155.111.222"));
+ attrStringIllegalMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/123.134.256.255"));
+ attrStringMaskNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255/"));
+ // optional mask
+ // "/" with no mask (fail)
+
+ attrStringMinusPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:-123"));
+ attrStringPortMinus = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:123-"));
+ attrStringPortPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:1234567-432"));
+ attrStringNoPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:"));
+ attrStringBadPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:12.34"));
+ attrStringTooManyPorts = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123.134.156.255:-123-456"));
+
+
+
+ attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_IPADDRESS_FROM_STRING;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_IPADDRESS_FROM_STRING, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_IPADDRESS.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrString1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ IPAddress resValue = (IPAddress)res.getValue().getValue();
+ assertEquals(new IPv4Address(addrShorts, null, null), resValue);
+
+ // fully-loaded address
+ arguments.clear();
+ arguments.add(attrStringFull);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (IPAddress)res.getValue().getValue();
+ try {
+ assertEquals(new IPv4Address(addrShorts, addrMaskShorts, PortRange.newInstance("123-456")), resValue);
+ } catch (Exception e) {
+ fail("port error e="+e);
+ }
+
+ // missing element
+ arguments.clear();
+ arguments.add(attrStringMissingElement);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.255\": invalid address", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many elements
+ arguments.clear();
+ arguments.add(attrStringTooManyElement);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.255.111.222\": invalid address", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // illegal element
+ arguments.clear();
+ arguments.add(attrStringIllegalElement);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.256.255\": invalid octet: \"256", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // Out of order
+ arguments.clear();
+ arguments.add(attrStringOutOfOrder);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.256.255:123-456/255.255.255.255\": out of order components", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // simple mask
+ arguments.clear();
+ arguments.add(attrStringMask);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (IPAddress)res.getValue().getValue();
+ try {
+ assertEquals(new IPv4Address(addrShorts, addrMaskShorts, null), resValue);
+ } catch (Exception e) {
+ fail("port error e="+e);
+ }
+
+ // missing mask element
+ arguments.clear();
+ arguments.add(attrStringMissingMaskElement);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.255\": invalid address", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many mask elements
+ arguments.clear();
+ arguments.add(attrStringTooManyMaskElement);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"122.134.155.111.222\": invalid address", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // illegal Mask element
+ arguments.clear();
+ arguments.add(attrStringIllegalMaskElement);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.256.255\": invalid octet: \"256", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ //mask indicator without value
+ arguments.clear();
+ arguments.add(attrStringMaskNoValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"\": invalid address", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // portrange (-port, port-, port-port)
+ arguments.clear();
+ arguments.add(attrStringMinusPort);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (IPAddress)res.getValue().getValue();
+ try {
+ assertEquals(new IPv4Address(addrShorts, null, PortRange.newInstance("-123")), resValue);
+ } catch (ParseException e) {
+ fail("port error e="+e);
+ }
+
+ arguments.clear();
+ arguments.add(attrStringPortMinus);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (IPAddress)res.getValue().getValue();
+ try {
+ assertEquals(new IPv4Address(addrShorts, null, PortRange.newInstance("123-")), resValue);
+ } catch (ParseException e) {
+ fail("port error e="+e);
+ }
+
+ arguments.clear();
+ arguments.add(attrStringPortPort);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (IPAddress)res.getValue().getValue();
+ try {
+ assertEquals(new IPv4Address(addrShorts, null, PortRange.newInstance("1234567-432")), resValue);
+ } catch (ParseException e) {
+ fail("port error e="+e);
+ }
+
+ // ":" without port
+ arguments.clear();
+ arguments.add(attrStringNoPort);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"123.134.156.255:\": no portrange given after ':'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // bad port number
+ arguments.clear();
+ arguments.add(attrStringBadPort);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid PortRange \"12.34\": invalid port number", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad port range
+ arguments.clear();
+ arguments.add(attrStringTooManyPorts);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid PortRange \"-123-456\": too many ranges", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // bad value
+ arguments.clear();
+ arguments.add(attrStringBadValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Unknown IPAddress type for \"not valid obj value\"", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ //
+ // V6 IP Addresses
+ //
+
+ // reset the variable for IPv6 tests
+ FunctionArgumentAttributeValue attrStringAlternateFull = null;
+ FunctionArgumentAttributeValue attrStringEmptyElement = null;
+ FunctionArgumentAttributeValue attrString2xEmptyElement = null;
+ FunctionArgumentAttributeValue attrStringNoStartBracket = null;
+ FunctionArgumentAttributeValue attrStringNoEndBracket = null;
+ short[] addrv6Shorts = {(short)0x2001, (short)0xdb8, (short)0x85a3, (short)0x0, (short)0x0, (short)0x8a2e, (short)0x370, (short)0x1};
+ Short prefix = new Short((short) 121);
+ try {
+ attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]"));
+ attrStringFull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/121]:123-456"));
+ attrStringAlternateFull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]/121:123-456"));
+ attrStringEmptyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3::8a2e:370:1]"));
+ attrString2xEmptyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3::8a2e::1]"));
+ attrStringNoStartBracket = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2002:db8:85a3::8a2e::1]"));
+ attrStringNoEndBracket = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3::8a2e::1"));
+
+ attrStringMissingElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:1]"));
+ attrStringTooManyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1:123]"));
+ attrStringIllegalElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:mnop:85a3:0:0:8a2e:370:1]"));
+ attrStringOutOfOrder = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:mnop:85a3:0:0:8a2e:370:1:123-456/121]"));
+
+ attrStringMask = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/21]"));
+ attrStringIllegalMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/130]"));
+ attrStringMaskNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/]"));
+
+ attrStringMinusPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:-123"));
+ attrStringPortMinus = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:123-"));
+ attrStringPortPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:1234567-432"));
+ attrStringNoPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:"));
+ attrStringBadPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:12.34"));
+ attrStringTooManyPorts = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:-123-456"));
+
+ attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrString1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (IPAddress)res.getValue().getValue();
+ assertEquals(new IPv6Address(addrv6Shorts, null, null), resValue);
+
+ // fully-loaded address - "prefix" is inside the brackets (not clear if this is correct)
+ arguments.clear();
+ arguments.add(attrStringFull);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (IPAddress)res.getValue().getValue();
+ try {
+ assertEquals(new IPv6Address(addrv6Shorts, new Short(prefix), PortRange.newInstance("123-456")), resValue);
+ } catch (Exception e) {
+ fail("port error e="+e);
+ }
+
+ // Alternate way of identifying "prefix" - outside the brackets
+ arguments.clear();
+ arguments.add(attrStringAlternateFull);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (IPAddress)res.getValue().getValue();
+ try {
+ assertEquals(new IPv6Address(addrv6Shorts, prefix, PortRange.newInstance("123-456")), resValue);
+ } catch (Exception e) {
+ fail("port error e="+e);
+ }
+
+
+ // consecutive zero elements removed
+ arguments.clear();
+ arguments.add(attrStringEmptyElement);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (IPAddress)res.getValue().getValue();
+ try {
+ assertEquals(new IPv6Address(addrv6Shorts, prefix, null), resValue);
+ } catch (Exception e) {
+ fail("port error e="+e);
+ }
+
+ // consecutive zero elements removed in two locations (no-no)
+ arguments.clear();
+ arguments.add(attrString2xEmptyElement);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:db8:85a3::8a2e::1\": multiple zero runs", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // address must have [] on it
+ arguments.clear();
+ arguments.add(attrStringNoStartBracket);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2002:db8:85a3::8a2e::1]\": missing opening bracket", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrStringNoEndBracket);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"[2001:db8:85a3::8a2e::1\": missing closing bracket", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // missing element
+ arguments.clear();
+ arguments.add(attrStringMissingElement);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:db8:85a3:0:0:8a2e:1\": not enough address fields", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many elements
+ arguments.clear();
+ arguments.add(attrStringTooManyElement);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:db8:85a3:0:0:8a2e:370:1:123\"", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // illegal element
+ arguments.clear();
+ arguments.add(attrStringIllegalElement);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv6Address component \"mnop\": invalid hex", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // Out of order
+ arguments.clear();
+ arguments.add(attrStringOutOfOrder);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:mnop:85a3:0:0:8a2e:370:1:123-456\"", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // simple mask
+ arguments.clear();
+ arguments.add(attrStringMask);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (IPAddress)res.getValue().getValue();
+ try {
+ assertEquals(new IPv6Address(addrv6Shorts, prefix, null), resValue);
+ } catch (Exception e) {
+ fail("port error e="+e);
+ }
+
+ // illegal Mask element
+ arguments.clear();
+ arguments.add(attrStringIllegalMaskElement);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid Ipv6Address string \"[2001:db8:85a3:0:0:8a2e:370:1/130]\": prefix is larger than 128", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ //mask indicator without value
+ arguments.clear();
+ arguments.add(attrStringMaskNoValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid Ipv6Address string \"[2001:db8:85a3:0:0:8a2e:370:1/]\": prefix designation without value", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // portrange (-port, port-, port-port)
+ arguments.clear();
+ arguments.add(attrStringMinusPort);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (IPAddress)res.getValue().getValue();
+ try {
+ assertEquals(new IPv6Address(addrv6Shorts, null, PortRange.newInstance("-123")), resValue);
+ } catch (ParseException e) {
+ fail("port error e="+e);
+ }
+
+ arguments.clear();
+ arguments.add(attrStringPortMinus);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (IPAddress)res.getValue().getValue();
+ try {
+ assertEquals(new IPv6Address(addrv6Shorts, null, PortRange.newInstance("123-")), resValue);
+ } catch (ParseException e) {
+ fail("port error e="+e);
+ }
+
+ arguments.clear();
+ arguments.add(attrStringPortPort);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (IPAddress)res.getValue().getValue();
+ try {
+ assertEquals(new IPv6Address(addrv6Shorts, null, PortRange.newInstance("1234567-432")), resValue);
+ } catch (ParseException e) {
+ fail("port error e="+e);
+ }
+
+ // ":" without port
+ arguments.clear();
+ arguments.add(attrStringNoPort);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid IPv6 address string \"[2001:db8:85a3:0:0:8a2e:370:1]:\": no portrange given after ':'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // bad port number
+ arguments.clear();
+ arguments.add(attrStringBadPort);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid PortRange \"12.34\": invalid port number", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad port range
+ arguments.clear();
+ arguments.add(attrStringTooManyPorts);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:ipAddress-from-string Invalid PortRange \"-123-456\": too many ranges", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+
+
+
+ }
+
+ @Test
+ public void testString_from_ipAddress() {
+ FunctionArgumentAttributeValue attrObj1 = null;
+ FunctionArgumentAttributeValue attrObjV6 = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ String objValueString = "123.145.255.255";
+ String objValueStringV6 = "[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]";
+ try {
+ attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(objValueString));
+ attrObjV6 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(objValueStringV6));
+
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_IPADDRESS;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_FROM_IPADDRESS, fd.getId());
+ assertEquals(DataTypes.DT_IPADDRESS.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal V4
+ arguments.clear();
+ arguments.add(attrObj1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(objValueString, res.getValue().getValue());
+
+ // test normal V6
+ arguments.clear();
+ arguments.add(attrObjV6);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(objValueStringV6.toLowerCase(), res.getValue().getValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-from-ipAddress Expected data type 'ipAddress' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+
+
+
+
+
+
+
+ /**
+ * RFC2396DomainName
+ */
+ @Test
+ public void testRFC2396DomainName_from_string() {
+ FunctionArgumentAttributeValue attrString1 = null;
+ FunctionArgumentAttributeValue attrString2 = null;
+ FunctionArgumentAttributeValue attrStringMinusPort = null;
+ FunctionArgumentAttributeValue attrStringPortMinus = null;
+ FunctionArgumentAttributeValue attrStringPortPort = null;
+ FunctionArgumentAttributeValue attrStringNoPort = null;
+ FunctionArgumentAttributeValue attrStringBadPort = null;
+ FunctionArgumentAttributeValue attrStringTooManyPorts = null;
+
+ FunctionArgumentAttributeValue attrStringBadValue = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ try {
+ attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host"));
+ attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host"));
+
+ attrStringMinusPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:-123"));
+ attrStringPortMinus = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:123-"));
+ attrStringPortPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:1234567-432"));
+ attrStringNoPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:"));
+ attrStringBadPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:12.34"));
+ attrStringTooManyPorts = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:-123-456"));
+
+ attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value"));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DNSNAME_FROM_STRING;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_DNSNAME_FROM_STRING, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_DNSNAME.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrString1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ RFC2396DomainName resValue = (RFC2396DomainName)res.getValue().getValue();
+ assertEquals(new RFC2396DomainName("host", null), resValue);
+
+ arguments.clear();
+ arguments.add(attrString2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (RFC2396DomainName)res.getValue().getValue();
+ assertEquals(new RFC2396DomainName("host.host", null), resValue);
+
+
+ // portrange (-port, port-, port-port)
+ arguments.clear();
+ arguments.add(attrStringMinusPort);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (RFC2396DomainName)res.getValue().getValue();
+ try {
+ assertEquals(new RFC2396DomainName("host.host", PortRange.newInstance("-123")), resValue);
+ } catch (ParseException e) {
+ fail("port error e="+e);
+ }
+
+ arguments.clear();
+ arguments.add(attrStringPortMinus);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (RFC2396DomainName)res.getValue().getValue();
+ try {
+ assertEquals(new RFC2396DomainName("host.host", PortRange.newInstance("123-")), resValue);
+ } catch (ParseException e) {
+ fail("port error e="+e);
+ }
+
+ arguments.clear();
+ arguments.add(attrStringPortPort);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (RFC2396DomainName)res.getValue().getValue();
+ try {
+ assertEquals(new RFC2396DomainName("host.host", PortRange.newInstance("1234567-432")), resValue);
+ } catch (ParseException e) {
+ fail("port error e="+e);
+ }
+
+ // ":" without port
+ arguments.clear();
+ arguments.add(attrStringNoPort);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dnsName-from-string Invalid RFC 2396 port range \"host.host:\": no port numbers", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad port number
+ arguments.clear();
+ arguments.add(attrStringBadPort);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dnsName-from-string Invalid RFC 2396 port range \"12.34\"", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad port range
+ arguments.clear();
+ arguments.add(attrStringTooManyPorts);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dnsName-from-string Invalid RFC 2396 port range \"-123-456\"", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad value
+ arguments.clear();
+ arguments.add(attrStringBadValue);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dnsName-from-string Invalid RFC 2396 host name \"not valid obj value\"", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:dnsName-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+ @Test
+ public void testString_from_dnsName() {
+ FunctionArgumentAttributeValue attrObj1 = null;
+ FunctionArgumentAttributeValue attrStringBadType = null;
+ String objValueString = "someName.com";
+ try {
+ attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DNSNAME.createAttributeValue(objValueString));
+ attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123));
+
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DNSNAME;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DNSNAME, fd.getId());
+ assertEquals(DataTypes.DT_DNSNAME.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+ // test normal
+ arguments.clear();
+ arguments.add(attrObj1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(objValueString, res.getValue().getValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrStringBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-from-dnsName Expected data type 'dnsName' saw 'integer' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+ }
+
+
+
+
+
+
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCaseTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCaseTest.java
new file mode 100755
index 0000000..81fc048
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringEqualIgnoreCaseTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.DataTypes;
+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.std.StdFunctions;
+
+/**
+ * Only one function to test here. Code copy/pasted from FunctionDefinitionEqualityTest
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * 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-ignore-case
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionStringEqualIgnoreCaseTest {
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+ FunctionArgumentAttributeValue stringAttr1 = null;
+ FunctionArgumentAttributeValue stringAttr2 = null;
+ FunctionArgumentAttributeValue stringAttr3 = null;
+ FunctionArgumentAttributeValue stringAttr4 = null;
+
+ FunctionArgumentAttributeValue intAttr1 = null;
+
+ public FunctionDefinitionStringEqualIgnoreCaseTest() {
+ try {
+ stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc"));
+ stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc"));
+ stringAttr3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ABC"));
+ stringAttr4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def"));
+ intAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+ }
+
+
+ /**
+ * String match even when Case is different
+ */
+ @Test
+ public void testFunctionDefinitionStringEqualIgnoreCase() {
+
+ FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_STRING_EQUAL_IGNORE_CASE;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_EQUAL_IGNORE_CASE, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+
+
+ // test normal equals and non-equals
+ // check "abc" with "abc"
+ arguments.add(stringAttr1);
+ arguments.add(stringAttr2);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // check "abc" with "ABC" (should be same)
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(stringAttr3);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // test bad args data types? Not needed?
+ arguments.clear();
+ arguments.add(stringAttr1);
+ arguments.add(intAttr1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+
+
+//TODO - null in either first or 2nd arg => NullPointerException
+ }
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctionsTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctionsTest.java
new file mode 100755
index 0000000..7a3b1c5
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringFunctionsTest.java
@@ -0,0 +1,1477 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.DataTypes;
+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.std.StdFunctions;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionStringFunctionsTest {
+
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+ ExpressionResult res;
+
+
+ @Test
+ public void testConcatenate() {
+ String v1 = new String("abc");
+ String v2 = new String("def");
+
+ FunctionArgumentAttributeValue attrV1 = null;
+ FunctionArgumentAttributeValue attrV2 = null;
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrBlank = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ try {
+ attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));
+ attrV2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v2));
+ attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_CONCATENATE;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_CONCATENATE, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // match
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrV2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ String resValue = (String)res.getValue().getValue();
+ assertEquals(v1 + v2, resValue);
+
+ // empty non-null first arg
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrV2);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ resValue = (String)res.getValue().getValue();
+ assertEquals(v2, resValue);
+
+ // empty non-null second arg
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ resValue = (String)res.getValue().getValue();
+ assertEquals(v1, resValue);
+
+ // two blanks
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ resValue = (String)res.getValue().getValue();
+ assertEquals("", resValue);
+
+ // null firat arg
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-concatenate Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-concatenate Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrInteger);
+ arguments.add(attrV2);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-concatenate Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-concatenate Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+ @Test
+ public void testStringStartsWith() {
+ String v1 = new String("abc");
+ String bigger = new String("abc some string");
+ String biggerNoMatch = new String(" abc some string");
+ String caps = new String("AbC");
+
+ FunctionArgumentAttributeValue attrV1 = null;
+ FunctionArgumentAttributeValue attrBigger = null;
+ FunctionArgumentAttributeValue attrBiggerNoMatch = null;
+ FunctionArgumentAttributeValue attrCaps = null;
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrBlank = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ try {
+ attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));
+ attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigger));
+ attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(biggerNoMatch));
+ attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps));
+ attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_STARTS_WITH;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_STARTS_WITH, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // match
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // no match
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBiggerNoMatch);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // caps no match
+ arguments.clear();
+ arguments.add(attrCaps);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // bigger on the inside
+ arguments.clear();
+ arguments.add(attrBigger);
+ arguments.add(attrV1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // empty non-null first arg
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // empty non-null second arg
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // two blanks
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // null firat arg
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-starts-with Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-starts-with Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // illegal arg type
+ arguments.clear();
+ arguments.add(attrInteger);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-starts-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+ @Test
+ public void testAnyuriStartsWith() {
+
+
+ FunctionArgumentAttributeValue attrV1 = null;
+ FunctionArgumentAttributeValue attrBigger = null;
+ FunctionArgumentAttributeValue attrBiggerNoMatch = null;
+ FunctionArgumentAttributeValue attrCaps = null;
+ FunctionArgumentAttributeValue attrBigString = null;
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrBlankString = null;
+ FunctionArgumentAttributeValue attrBlankURI = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ try {
+ String v1 = new String("abc");
+ URI bigger = new URI("abc.some.string");
+ URI biggerNoMatch = new URI("Zabc.some.string");
+ String caps = new String("AbC");
+ String bigString = "thisIsSomeReallyBigStringToMatch";
+
+ attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));
+ attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigger));
+ attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(biggerNoMatch));
+ attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps));
+ attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString));
+ attrBlankString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));
+ attrBlankURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(""));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_STARTS_WITH;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_ANYURI_STARTS_WITH, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // match
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // no match
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBiggerNoMatch);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // caps no match
+ arguments.clear();
+ arguments.add(attrCaps);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // bigger on the inside
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // empty non-null first arg
+ arguments.clear();
+ arguments.add(attrBlankString);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // empty non-null second arg
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBlankURI);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+
+ // two blanks
+ arguments.clear();
+ arguments.add(attrBlankString);
+ arguments.add(attrBlankURI);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // arguments reversed
+ arguments.clear();
+ arguments.add(attrBigger);
+ arguments.add(attrV1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-starts-with Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // null firat arg
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrBlankURI);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-starts-with Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-starts-with Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // illegal arg type
+ arguments.clear();
+ arguments.add(attrInteger);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-starts-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+ @Test
+ public void testStringEndsWith() {
+ String v1 = new String("abc");
+ String bigger = new String("abc some string abc");
+ String biggerNoMatch = new String(" abc some string abc ");
+ String caps = new String("AbC");
+
+ FunctionArgumentAttributeValue attrV1 = null;
+ FunctionArgumentAttributeValue attrBigger = null;
+ FunctionArgumentAttributeValue attrBiggerNoMatch = null;
+ FunctionArgumentAttributeValue attrCaps = null;
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrBlank = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ try {
+ attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));
+ attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigger));
+ attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(biggerNoMatch));
+ attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps));
+ attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_ENDS_WITH;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_ENDS_WITH, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // match
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // no match
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBiggerNoMatch);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // caps no match
+ arguments.clear();
+ arguments.add(attrCaps);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // bigger on the inside
+ arguments.clear();
+ arguments.add(attrBigger);
+ arguments.add(attrV1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // empty non-null first arg
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // empty non-null second arg
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // two blanks
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // null firat arg
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-ends-with Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-ends-with Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // illegal arg type
+ arguments.clear();
+ arguments.add(attrInteger);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-ends-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+ @Test
+ public void testAnyuriEndsWith() {
+
+
+ FunctionArgumentAttributeValue attrV1 = null;
+ FunctionArgumentAttributeValue attrBigger = null;
+ FunctionArgumentAttributeValue attrBiggerNoMatch = null;
+ FunctionArgumentAttributeValue attrCaps = null;
+ FunctionArgumentAttributeValue attrBigString = null;
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrBlankString = null;
+ FunctionArgumentAttributeValue attrBlankURI = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ try {
+ String v1 = new String("abc");
+ URI bigger = new URI("abc.some.stringabc");
+ URI biggerNoMatch = new URI("Zabc.some.stringabcZ");
+ String caps = new String("AbC");
+ String bigString = "thisIsSomeReallyBigStringToMatch";
+
+ attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));
+ attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigger));
+ attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(biggerNoMatch));
+ attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps));
+ attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString));
+ attrBlankString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));
+ attrBlankURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(""));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_ENDS_WITH;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_ANYURI_ENDS_WITH, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // match
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // no match
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBiggerNoMatch);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // caps no match
+ arguments.clear();
+ arguments.add(attrCaps);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // bigger on the inside
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // empty non-null first arg
+ arguments.clear();
+ arguments.add(attrBlankString);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // empty non-null second arg
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBlankURI);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+
+ // two blanks
+ arguments.clear();
+ arguments.add(attrBlankString);
+ arguments.add(attrBlankURI);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // arguments reversed
+ arguments.clear();
+ arguments.add(attrBigger);
+ arguments.add(attrV1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-ends-with Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // null firat arg
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrBlankURI);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-ends-with Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-ends-with Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // illegal arg type
+ arguments.clear();
+ arguments.add(attrInteger);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-ends-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+ @Test
+ public void testStringSubstring() {
+ String bigString = new String("abc some string abc");
+
+ FunctionArgumentAttributeValue attrBigString = null;
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrBlank = null;
+ FunctionArgumentAttributeValue attrDouble = null;
+
+ FunctionArgumentAttributeValue attrInteger0 = null;
+ FunctionArgumentAttributeValue attrInteger1 = null;
+ FunctionArgumentAttributeValue attrIntegerM1 = null;
+ FunctionArgumentAttributeValue attrInteger8 = null;
+ FunctionArgumentAttributeValue attrInteger19 = null;
+ FunctionArgumentAttributeValue attrInteger20 = null;
+
+
+
+ try {
+ attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString));
+ attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));
+ attrInteger0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));
+ attrInteger1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));
+ attrIntegerM1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1));
+ attrInteger8 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(8));
+ attrInteger19 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(19));
+ attrInteger20 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(20));
+ attrDouble = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(123.4));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_SUBSTRING;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_SUBSTRING, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // match
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrInteger1);
+ arguments.add(attrInteger8);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ String resValue = (String)res.getValue().getValue();
+ assertEquals("bc some", resValue);
+
+ // edge: start
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrInteger0);
+ arguments.add(attrInteger8);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ resValue = (String)res.getValue().getValue();
+ assertEquals("abc some", resValue);
+
+ // edge: end
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrInteger8);
+ arguments.add(attrInteger19);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ resValue = (String)res.getValue().getValue();
+ assertEquals(" string abc", resValue);
+
+ // from index to end of string
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrInteger8);
+ arguments.add(attrIntegerM1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ resValue = (String)res.getValue().getValue();
+ assertEquals(" string abc", resValue);
+
+ // first index too low
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrIntegerM1);
+ arguments.add(attrInteger8);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-substring Start point '-1' out of range 0-19 for string='abc some string abc'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // second index too big
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrInteger8);
+ arguments.add(attrInteger20);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-substring End point '20' out of range 0-19 for string='abc some string abc'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // indexes reversed
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrInteger8);
+ arguments.add(attrInteger1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-substring End point '1' less than start point 'null' for string='abc some string abc'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // indexes the same
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrInteger8);
+ arguments.add(attrInteger8);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ resValue = (String)res.getValue().getValue();
+ assertEquals("", resValue);
+
+ // blank string with indexes both 0
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrInteger0);
+ arguments.add(attrInteger0);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ resValue = (String)res.getValue().getValue();
+ assertEquals("", resValue);
+
+ // non-string first attribute
+ arguments.clear();
+ arguments.add(attrDouble);
+ arguments.add(attrInteger8);
+ arguments.add(attrInteger1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-substring Expected data type 'string' saw 'double'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // non-integer 2nd attr
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrDouble);
+ arguments.add(attrInteger1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // non-integer 3rd attr
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrInteger8);
+ arguments.add(attrDouble);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // 4 args
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrInteger8);
+ arguments.add(attrInteger1);
+ arguments.add(attrInteger1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-substring Expected 3 arguments, got 4", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // 2 args
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrInteger8);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-substring Expected 3 arguments, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null 1st arg
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrInteger8);
+ arguments.add(attrInteger1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-substring Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // null 2nd arg
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrNull);
+ arguments.add(attrInteger1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-substring Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ }
+
+
+
+
+ @Test
+ public void testAnyURISubstring() {
+ String bigString = new String("http://company.com:8080/this/is/some/long/uri");
+
+ FunctionArgumentAttributeValue attrURI = null;
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrBlank = null;
+ FunctionArgumentAttributeValue attrDouble = null;
+
+ FunctionArgumentAttributeValue attrInteger0 = null;
+ FunctionArgumentAttributeValue attrInteger1 = null;
+ FunctionArgumentAttributeValue attrIntegerM1 = null;
+ FunctionArgumentAttributeValue attrInteger8 = null;
+ FunctionArgumentAttributeValue attrInteger45 = null;
+ FunctionArgumentAttributeValue attrInteger46 = null;
+
+
+
+ try {
+ attrURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigString));
+ attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(""));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(null));
+ attrInteger0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0));
+ attrInteger1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1));
+ attrIntegerM1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1));
+ attrInteger8 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(8));
+ attrInteger45 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(45));
+ attrInteger46 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(46));
+ attrDouble = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(123.4));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_SUBSTRING;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_ANYURI_SUBSTRING, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // match
+ arguments.clear();
+ arguments.add(attrURI);
+ arguments.add(attrInteger1);
+ arguments.add(attrInteger8);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ String resValue = (String)res.getValue().getValue();
+ assertEquals("ttp://c", resValue);
+
+ // edge: start
+ arguments.clear();
+ arguments.add(attrURI);
+ arguments.add(attrInteger0);
+ arguments.add(attrInteger8);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ resValue = (String)res.getValue().getValue();
+ assertEquals("http://c", resValue);
+
+ // edge: end
+ arguments.clear();
+ arguments.add(attrURI);
+ arguments.add(attrInteger8);
+ arguments.add(attrInteger45);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ resValue = (String)res.getValue().getValue();
+ assertEquals("ompany.com:8080/this/is/some/long/uri", resValue);
+
+ // from index to end of string
+ arguments.clear();
+ arguments.add(attrURI);
+ arguments.add(attrInteger8);
+ arguments.add(attrIntegerM1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ resValue = (String)res.getValue().getValue();
+ assertEquals("ompany.com:8080/this/is/some/long/uri", resValue);
+
+ // first index too low
+ arguments.clear();
+ arguments.add(attrURI);
+ arguments.add(attrIntegerM1);
+ arguments.add(attrInteger8);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-substring Start point '-1' out of range 0-45 for string='http://company.com:8080/this/is/some/long/uri'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // second index too big
+ arguments.clear();
+ arguments.add(attrURI);
+ arguments.add(attrInteger8);
+ arguments.add(attrInteger46);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-substring End point '46' out of range 0-45 for string='http://company.com:8080/this/is/some/long/uri'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // indexes reversed
+ arguments.clear();
+ arguments.add(attrURI);
+ arguments.add(attrInteger8);
+ arguments.add(attrInteger1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-substring End point '1' less than start point 'null' for string='http://company.com:8080/this/is/some/long/uri'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // indexes the same
+ arguments.clear();
+ arguments.add(attrURI);
+ arguments.add(attrInteger8);
+ arguments.add(attrInteger8);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ resValue = (String)res.getValue().getValue();
+ assertEquals("", resValue);
+
+ // blank string with indexes both 0
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrInteger0);
+ arguments.add(attrInteger0);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(String.class, res.getValue().getValue().getClass());
+ resValue = (String)res.getValue().getValue();
+ assertEquals("", resValue);
+
+ // non-string first attribute
+ arguments.clear();
+ arguments.add(attrDouble);
+ arguments.add(attrInteger8);
+ arguments.add(attrInteger1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-substring Expected data type 'anyURI' saw 'double'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // non-integer 2nd attr
+ arguments.clear();
+ arguments.add(attrURI);
+ arguments.add(attrDouble);
+ arguments.add(attrInteger1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // non-integer 3rd attr
+ arguments.clear();
+ arguments.add(attrURI);
+ arguments.add(attrInteger8);
+ arguments.add(attrDouble);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // 4 args
+ arguments.clear();
+ arguments.add(attrURI);
+ arguments.add(attrInteger8);
+ arguments.add(attrInteger1);
+ arguments.add(attrInteger1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-substring Expected 3 arguments, got 4", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // 2 args
+ arguments.clear();
+ arguments.add(attrURI);
+ arguments.add(attrInteger8);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-substring Expected 3 arguments, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null 1st arg
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrInteger8);
+ arguments.add(attrInteger1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-substring Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // null 2nd arg
+ arguments.clear();
+ arguments.add(attrURI);
+ arguments.add(attrNull);
+ arguments.add(attrInteger1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-substring Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @Test
+ public void testStringContains() {
+ String v1 = new String("abc");
+ String bigger = new String("abc some string abc");
+ String biggerNoMatch = new String(" abc some string abc ");
+ String caps = new String("AbC");
+
+ FunctionArgumentAttributeValue attrV1 = null;
+ FunctionArgumentAttributeValue attrBigger = null;
+ FunctionArgumentAttributeValue attrBiggerNoMatch = null;
+ FunctionArgumentAttributeValue attrCaps = null;
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrBlank = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ try {
+ attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));
+ attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigger));
+ attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(biggerNoMatch));
+ attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps));
+ attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_CONTAINS;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_CONTAINS, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // match
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // no match
+ arguments.clear();
+ arguments.add(attrBiggerNoMatch);
+ arguments.add(attrV1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // caps no match
+ arguments.clear();
+ arguments.add(attrCaps);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // bigger on the inside
+ arguments.clear();
+ arguments.add(attrBigger);
+ arguments.add(attrV1);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // empty non-null first arg
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // empty non-null second arg
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // two blanks
+ arguments.clear();
+ arguments.add(attrBlank);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // null firat arg
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrBlank);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-contains Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-contains Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // illegal arg type
+ arguments.clear();
+ arguments.add(attrInteger);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:string-contains Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+ @Test
+ public void testAnyuriContains() {
+
+
+ FunctionArgumentAttributeValue attrV1 = null;
+ FunctionArgumentAttributeValue attrBigger = null;
+ FunctionArgumentAttributeValue attrBiggerNoMatch = null;
+ FunctionArgumentAttributeValue attrCaps = null;
+ FunctionArgumentAttributeValue attrBigString = null;
+ FunctionArgumentAttributeValue attrNull = null;
+ FunctionArgumentAttributeValue attrBlankString = null;
+ FunctionArgumentAttributeValue attrBlankURI = null;
+ FunctionArgumentAttributeValue attrInteger = null;
+ try {
+ String v1 = new String("abc");
+ URI bigger = new URI("abc.some.stringabc");
+ URI biggerNoMatch = new URI("Zabc.some.stringabcZ");
+ String caps = new String("AbC");
+ String bigString = "thisIsSomeReallyBigStringToMatch";
+
+ attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1));
+ attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigger));
+ attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(biggerNoMatch));
+ attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps));
+ attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString));
+ attrBlankString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));
+ attrBlankURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(""));
+ attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null));
+ attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_CONTAINS;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_ANYURI_CONTAINS, fd.getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // match
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // no match
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrBiggerNoMatch);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // caps no match
+ arguments.clear();
+ arguments.add(attrCaps);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // bigger on the inside
+ arguments.clear();
+ arguments.add(attrBigString);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+ // empty non-null first arg
+ arguments.clear();
+ arguments.add(attrBlankString);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // empty non-null second arg
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrBlankURI);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(false, resValue);
+
+
+ // two blanks
+ arguments.clear();
+ arguments.add(attrBlankString);
+ arguments.add(attrBlankURI);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(Boolean.class, res.getValue().getValue().getClass());
+ resValue = (Boolean)res.getValue().getValue();
+ assertEquals(true, resValue);
+
+ // arguments reversed
+ arguments.clear();
+ arguments.add(attrBigger);
+ arguments.add(attrV1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-contains Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // null firat arg
+ arguments.clear();
+ arguments.add(attrNull);
+ arguments.add(attrBlankURI);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-contains Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null second arg
+ arguments.clear();
+ arguments.add(attrV1);
+ arguments.add(attrNull);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-contains Got null attribute", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // illegal arg type
+ arguments.clear();
+ arguments.add(attrInteger);
+ arguments.add(attrBigger);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:anyURI-contains Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalizeTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalizeTest.java
new file mode 100755
index 0000000..a09a696
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionStringNormalizeTest.java
@@ -0,0 +1,98 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.datatypes.DataTypes;
+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.std.StdFunctions;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionStringNormalizeTest {
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+ @Test
+ public void testString_normalize_space() {
+ String initialString = " First and last are whitespace ";
+ FunctionArgumentAttributeValue attr1 = null;
+ try {
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(initialString));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringNormalize fd = (FunctionDefinitionStringNormalize) StdFunctions.FD_STRING_NORMALIZE_SPACE;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_NORMALIZE_SPACE, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+
+ // test normal add
+ arguments.add(attr1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ String resValue = (String)res.getValue().getValue();
+ assertEquals(initialString.length() - 4, resValue.length());
+ assertTrue(initialString.trim().equals(resValue));
+ }
+
+
+ @Test
+ public void testString_normalize_to_lower_case() {
+ String initialString = " First and last are whitespace ";
+ FunctionArgumentAttributeValue attr1 = null;
+ try {
+ attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(initialString));
+ } catch (Exception e) {
+ fail("creating attribute e="+ e);
+ }
+
+ FunctionDefinitionStringNormalize fd = (FunctionDefinitionStringNormalize) StdFunctions.FD_STRING_NORMALIZE_TO_LOWER_CASE;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_STRING_NORMALIZE_TO_LOWER_CASE, fd.getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+
+ // test normal add
+ arguments.add(attr1);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ String resValue = (String)res.getValue().getValue();
+ assertTrue(initialString.toLowerCase().equals(resValue));
+ }
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenateTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenateTest.java
new file mode 100755
index 0000000..9da1f13
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionURIStringConcatenateTest.java
@@ -0,0 +1,165 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.XACML2;
+import com.att.research.xacml.std.datatypes.DataTypes;
+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.std.StdFunctions;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionURIStringConcatenateTest {
+
+ /*
+ * THE FUNCTION BEING TESTED BY THIS CLASS IS DEPRECATED
+ * uri-string-concatenate has been deprecated in XACML 3.0
+ */
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void testURI_string_concatenate() {
+
+ // URI args
+ FunctionArgumentAttributeValue attrURI1 = null;
+
+
+ FunctionArgumentAttributeValue attrStrAbc = null;
+ FunctionArgumentAttributeValue attrStrSlashMno = null;
+ FunctionArgumentAttributeValue attrStrSlashInMiddle = null;
+ FunctionArgumentAttributeValue attrStrWithSpace = null;
+
+
+ try {
+ attrURI1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("http://someplace"));
+
+
+ attrStrAbc = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("Abc"));
+ attrStrSlashMno = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("/Mno"));
+ attrStrSlashInMiddle = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("hij/pqr"));
+ attrStrWithSpace = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("x y z"));
+
+
+ } catch (Exception e) {
+ fail("creating attributes e="+ e);
+ }
+
+ // deprecation marking in the following line is correct - this function IS deprecated but still valid for XACML 3.0
+ FunctionDefinitionURIStringConcatenate fd = (FunctionDefinitionURIStringConcatenate) StdFunctions.FD_URI_STRING_CONCATENATE;
+
+ // check identity and type of the thing created
+ assertEquals(XACML2.ID_FUNCTION_URI_STRING_CONCATENATE, fd.getId());
+ assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+
+
+ // add one string to uri
+ arguments.clear();
+ arguments.add(attrURI1);
+ arguments.add(attrStrAbc);
+ ExpressionResult res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(URI.class, res.getValue().getValue().getClass());
+ URI resValue = (URI)res.getValue().getValue();
+ assertEquals("http://someplaceAbc", resValue.toString());
+
+
+ // add 2 strings to uri
+ arguments.clear();
+ arguments.add(attrURI1);
+ arguments.add(attrStrAbc);
+ arguments.add(attrStrSlashMno);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(URI.class, res.getValue().getValue().getClass());
+ resValue = (URI)res.getValue().getValue();
+ assertEquals("http://someplaceAbc/Mno", resValue.toString());
+
+ // slash in middle of string
+ arguments.clear();
+ arguments.add(attrURI1);
+ arguments.add(attrStrSlashInMiddle);
+ arguments.add(attrStrSlashMno);
+ res = fd.evaluate(null, arguments);
+ assertTrue(res.isOk());
+ assertEquals(URI.class, res.getValue().getValue().getClass());
+ resValue = (URI)res.getValue().getValue();
+ assertEquals("http://someplacehij/pqr/Mno", resValue.toString());
+
+ // create bad uri
+ arguments.clear();
+ arguments.add(attrURI1);
+ arguments.add(attrStrWithSpace);
+ arguments.add(attrStrSlashMno);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:uri-string-concatenate Final string 'http://someplacex y z/Mno' not URI, Illegal character in authority at index 7: http://someplacex y z/Mno", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // no args
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:uri-string-concatenate Expected 2 or more arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // one arg
+ arguments.clear();
+ arguments.add(attrURI1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:uri-string-concatenate Expected 2 or more arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // first arg not uri
+ arguments.clear();
+ arguments.add(attrStrAbc);
+ arguments.add(attrURI1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:uri-string-concatenate Expected data type 'anyURI' saw 'string' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // 2nd arg not string
+ arguments.clear();
+ arguments.add(attrURI1);
+ arguments.add(attrURI1);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.isOk());
+ assertEquals("function:uri-string-concatenate Expected data type 'string' saw 'anyURI' at arg index 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPathTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPathTest.java
new file mode 100755
index 0000000..5e622ab
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/functions/FunctionDefinitionXPathTest.java
@@ -0,0 +1,1107 @@
+package com.att.research.xacmlatt.pdp.std.functions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathFactory;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdRequest;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.datatypes.DataTypes;
+import com.att.research.xacml.std.datatypes.XPathExpressionWrapper;
+import com.att.research.xacml.std.dom.DOMRequest;
+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.std.StdEvaluationContext;
+import com.att.research.xacmlatt.pdp.std.StdFunctions;
+
+/**
+ * Test of PDP Functions (See XACML core spec section A.3)
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * @author glenngriffin
+ *
+ */
+public class FunctionDefinitionXPathTest {
+
+ //
+ // Strings for the Request contents
+ //
+
+ String reqStrMainStart = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ + "<Request xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
+ + " http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\""
+ + " ReturnPolicyIdList=\"false\""
+ + " CombinedDecision=\"false\""
+ + " xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\""
+ + " xmlns:md=\"http://www.medico.com/schemas/record\""
+ + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+ + " <Attributes Category=\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\">"
+ + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\">"
+ + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Julius Hibbert</AttributeValue>"
+ + " </Attribute>"
+ + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">"
+ + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>"
+ + " </Attribute>"
+ + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">"
+ + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>"
+ + " </Attribute>"
+ + "</Attributes>";
+
+ String reqStrResourceStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\">";
+
+ String reqStrContentMdRecord =
+ " <Content>" +
+ "<md:record>" +
+ "<md:hospital_info>" +
+ "<md:name>ABC Hospital</md:name>" +
+ "<md:department>Surgery</md:department>" +
+ "</md:hospital_info>" +
+ "<md:patient_info>" +
+ "<md:name>Bart Simpson</md:name>" +
+ "<md:age>60</md:age>" +
+ "<md:sex>male</md:sex>" +
+ "<md:health_insurance>123456</md:health_insurance>" +
+ "</md:patient_info>" +
+ "<md:diagnosis_info>" +
+ "<md:diagnosis>" +
+ "<md:item type=\"primary\">Gastric Cancer</md:item>" +
+ "<md:item type=\"secondary\">Hyper tension</md:item>" +
+ "</md:diagnosis>" +
+ "<md:pathological_diagnosis>" +
+ "<md:diagnosis>" +
+ "<md:item type=\"primary\">Well differentiated adeno carcinoma</md:item>" +
+ "</md:diagnosis>" +
+ "<md:date>2000-10-05</md:date>" +
+ "<md:malignancy type=\"yes\"/>" +
+ "</md:pathological_diagnosis>" +
+ "</md:diagnosis_info> " +
+ " </md:record>" +
+ "</Content>";
+ String reqStrMalformedContent =
+ " <Content>" +
+ "<md:record>" +
+ "<md:hospital_info>" +
+ "<md:name>ABC Hospital</md:name>" +
+ "<md:malignancy type=\"yes\"/>" +
+ "</Content>";
+ String reqStrResourceEnd = " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\">"
+ + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#anyURI\">http://medico.com/record/patient/BartSimpson</AttributeValue>"
+ + " </Attribute>"
+ + "</Attributes> ";
+ String reqStrActionStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\">";
+
+ String reqStrActionEnd = "<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\">"
+ + "<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">read</AttributeValue>"
+ + "</Attribute>"
+ + "</Attributes> ";
+ String reqStrEnvironmentStartEnd = " <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\" />";
+ String reqStrMainEnd = " </Request>";
+
+
+ // combined strings for convenience
+ String reqStrMainResourceStart = reqStrMainStart + reqStrResourceStart;
+ String reqStrResourceAllEnd = reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrEnvironmentStartEnd + reqStrMainEnd;
+
+
+ /*
+ * variables useful in the following tests
+ */
+ List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
+
+
+
+ // Name Spaces used in the XML as part of these examples (copied from the Conformance tests) - needed for compiling XPaths
+ NamespaceContext nameSpaceContext = new NamespaceContext() {
+ @Override
+ public Iterator<?> getPrefixes(String arg0) { return null;}
+
+ @Override
+ public String getPrefix(String arg0) {return null;}
+
+ @Override
+ public String getNamespaceURI(String arg0) {
+ if("md".equals(arg0)) {
+ return "http://www.medico.com/schemas/record";
+ } else if ("xacml-context".equals(arg0)) {
+ return "urn:oasis:names:tc:xacml:3.0:context:schema:os";
+ } else if ("xsi".equals(arg0)) {
+ return "http://www.w3.org/2001/XMLSchema-instance";
+ }
+ return null;
+ }
+ };
+
+
+
+ //
+ // XPath Function Attributes available for use in tests (representing appropriate fragment of Policy)
+ //
+
+ FunctionArgumentAttributeValue attrXnull = null;
+ FunctionArgumentAttributeValue attrXEmpty = null;
+ FunctionArgumentAttributeValue attrXNoCategory = null;
+ FunctionArgumentAttributeValue attrXNoValue = null;
+ FunctionArgumentAttributeValue attrXSlashSlashMdRecord = null;
+ FunctionArgumentAttributeValue attrXSlashSlashStar = null;
+ FunctionArgumentAttributeValue attrXSlashSlashMdName = null;
+ FunctionArgumentAttributeValue attrXSlashSlashMdMalignancy = null;
+ FunctionArgumentAttributeValue attrXNotInRequest = null;
+ FunctionArgumentAttributeValue attrXSlashSlashMdRecordSlashStar = null;
+ FunctionArgumentAttributeValue attrXMdPatientInfo = null;
+
+ FunctionArgumentAttributeValue attrBadType = null;
+
+ // String version of attrs for use in Deprecated functions
+ FunctionArgumentAttributeValue attrStrnull = null;
+ FunctionArgumentAttributeValue attrStrEmpty = null;
+ FunctionArgumentAttributeValue attrStrNoCategory = null;
+ FunctionArgumentAttributeValue attrStrNoValue = null;
+ FunctionArgumentAttributeValue attrStrSlashSlashMdRecord = null;
+ FunctionArgumentAttributeValue attrStrSlashSlashStar = null;
+ FunctionArgumentAttributeValue attrStrSlashSlashMdName = null;
+ FunctionArgumentAttributeValue attrStrSlashSlashMdMalignancy = null;
+ FunctionArgumentAttributeValue attrStrNotInRequest = null;
+ FunctionArgumentAttributeValue attrStrSlashSlashMdRecordSlashStar = null;
+ FunctionArgumentAttributeValue attrStrMdPatientInfo = null;
+
+
+ //
+ // REQUEST objects available for use in tests
+ //
+ Request requestEmpty = new StdRequest(StdStatus.STATUS_OK);
+ Request requestMdRecord = null;
+ Request requestDoubleResources = null;
+ Request requestResourceActionContent = null;
+ Request requestContentInAction = null;
+
+
+
+
+ /**
+ * Set up all variables in one place because it is complicated (lots of steps needed for each attribute)
+ */
+ public FunctionDefinitionXPathTest() {
+ try {
+ XPathFactory xPathFactory = XPathFactory.newInstance();
+ XPath xpath = xPathFactory.newXPath();
+ xpath.setNamespaceContext(nameSpaceContext);
+
+ // Create XPaths to use in expressions
+ XPathExpressionWrapper xEmpty = new XPathExpressionWrapper("");
+ XPathExpressionWrapper xSlashSlashMdRecord = new XPathExpressionWrapper(xpath.compile("//md:record"));
+ XPathExpressionWrapper xSlashSlashStar = new XPathExpressionWrapper(xpath.compile("//*"));
+ XPathExpressionWrapper xSlashSlashMdName = new XPathExpressionWrapper(xpath.compile("//md:name"));
+ XPathExpressionWrapper xSlashSlashMdMalignancy = new XPathExpressionWrapper(xpath.compile("//md:malignancy"));
+ XPathExpressionWrapper xNotInRequest = new XPathExpressionWrapper(xpath.compile("value_Not_in_request"));
+ XPathExpressionWrapper xSlashSlashMdRecordSlashStar = new XPathExpressionWrapper(xpath.compile("//md:record/*"));
+ XPathExpressionWrapper xMdPatientInfo = new XPathExpressionWrapper(xpath.compile("md:patient_info"));
+
+
+
+ // create Function Attributes out of the XPathExpressions
+ attrXnull = new FunctionArgumentAttributeValue(null);
+ attrXEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xEmpty));
+ attrXNoCategory = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdRecord));
+ attrXNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xEmpty,
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+ attrXSlashSlashMdRecord = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdRecord,
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+ attrXSlashSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashStar,
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+ attrXSlashSlashMdName = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdName,
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+ attrXSlashSlashMdMalignancy = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdMalignancy,
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+ attrXNotInRequest = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xNotInRequest,
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+
+ attrXSlashSlashMdRecordSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdRecordSlashStar,
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+ attrXMdPatientInfo = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xMdPatientInfo,
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+
+
+ // Deprecated versions of args
+ attrStrnull = new FunctionArgumentAttributeValue(null);
+ attrStrEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));
+ attrStrNoCategory = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:record"));
+ attrStrNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("",
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+ attrStrSlashSlashMdRecord = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:record",
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+ attrStrSlashSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//*",
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+ attrStrSlashSlashMdName = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:name",
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+ attrStrSlashSlashMdMalignancy = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:malignancy",
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+ attrStrNotInRequest = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("value_Not_in_request",
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+
+ attrStrSlashSlashMdRecordSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:record/*",
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+ attrStrMdPatientInfo = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("md:patient_info",
+ new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" )));
+
+
+
+
+ attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("some string"));
+
+
+
+ // Request objects
+ // to create a Request object the easiest way is to put the xml into a file and use the DOMRequest to load it.
+
+ // single Content in the Resources section (normal valid request)
+ String reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrResourceAllEnd;
+ File tFile = File.createTempFile("functionJunit", "request");
+ BufferedWriter bw = new BufferedWriter(new FileWriter(tFile));
+ bw.append(reqString);
+ bw.flush();
+ bw.close();
+ requestMdRecord = DOMRequest.load(tFile);
+ tFile.delete();
+
+ // Resources included twice
+ reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrResourceEnd + reqStrResourceStart + reqStrContentMdRecord +reqStrResourceAllEnd;
+ tFile = File.createTempFile("functionJunit", "request");
+ bw = new BufferedWriter(new FileWriter(tFile));
+ bw.append(reqString);
+ bw.flush();
+ bw.close();
+ requestDoubleResources = DOMRequest.load(tFile);
+ tFile.delete();
+
+
+ // content included in both Resource and Action - ok
+ reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecord + reqStrActionEnd + reqStrMainEnd;
+ tFile = File.createTempFile("functionJunit", "request");
+ bw = new BufferedWriter(new FileWriter(tFile));
+ bw.append(reqString);
+ bw.flush();
+ bw.close();
+ requestResourceActionContent = DOMRequest.load(tFile);
+ tFile.delete();
+
+ // Content included only in Action - missing content produces non-error result according to spec
+ reqString = reqStrMainResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecord + reqStrActionEnd + reqStrMainEnd;
+ tFile = File.createTempFile("functionJunit", "request");
+ bw = new BufferedWriter(new FileWriter(tFile));
+ bw.append(reqString);
+ bw.flush();
+ bw.close();
+ requestContentInAction = DOMRequest.load(tFile);
+ tFile.delete();
+
+
+
+ // Test that Bad XML is caught
+ @SuppressWarnings("unused")
+ Request requestContentMisplaced = null;
+ @SuppressWarnings("unused")
+ Request requestMalformedContent = null;
+ @SuppressWarnings("unused")
+ Request requestDoubleContent = null;
+
+
+ // Content included twice - error
+ reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrContentMdRecord +reqStrResourceAllEnd;
+ tFile = File.createTempFile("functionJunit", "request");
+ bw = new BufferedWriter(new FileWriter(tFile));
+ bw.append(reqString);
+ bw.flush();
+ bw.close();
+ try {
+ requestDoubleContent = DOMRequest.load(tFile);
+ tFile.delete();
+ } catch (com.att.research.xacml.std.dom.DOMStructureException e) {
+ // this is what it should do, so just continue
+ } catch (Exception e) {
+ fail("Unexpected exception for bad XML, e="+e);
+ }
+
+ // Bad XML - Content not under a Category
+ reqString = reqStrMainStart + reqStrContentMdRecord + reqStrResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrMainEnd;
+ tFile = File.createTempFile("functionJunit", "request");
+ bw = new BufferedWriter(new FileWriter(tFile));
+ bw.append(reqString);
+ bw.flush();
+ bw.close();
+ try {
+ requestContentMisplaced = DOMRequest.load(tFile);
+ tFile.delete();
+ } catch (com.att.research.xacml.std.dom.DOMStructureException e) {
+ // this is what it should do, so just continue
+ } catch (Exception e) {
+ fail("Unexpected exception for bad XML, e="+e);
+ }
+
+ // Bad XML - Content is not valid XML
+ reqString = reqStrMainResourceStart + reqStrMalformedContent + reqStrResourceAllEnd;
+ tFile = File.createTempFile("functionJunit", "request");
+ bw = new BufferedWriter(new FileWriter(tFile));
+ bw.append(reqString);
+ bw.flush();
+ bw.close();
+ try {
+ requestMalformedContent = DOMRequest.load(tFile);
+ tFile.delete();
+ } catch (com.att.research.xacml.std.dom.DOMStructureException e) {
+ // this is what it should do, so just continue
+ } catch (Exception e) {
+ fail("Unexpected exception for bad XML, e="+e);
+ }
+
+ } catch (Exception e) {
+ fail("Constructor initializing variables, e="+ e + " cause="+e.getCause());
+ }
+
+ }
+
+
+
+
+
+
+
+
+ @Test
+ public void testXpath_node_count() {
+
+
+
+ FunctionDefinitionXPath<?> fd = (FunctionDefinitionXPath<?>) StdFunctions.FD_XPATH_NODE_COUNT;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_XPATH_NODE_COUNT, fd.getId());
+ assertEquals(DataTypes.DT_XPATHEXPRESSION.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(1), fd.getNumArgs());
+
+
+ // match all elements within context
+ arguments.clear();
+ arguments.add(attrXSlashSlashStar);
+ ExpressionResult res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ BigInteger resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("18"), resValue);
+
+ // match exactly 1 element
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdMalignancy);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("1"), resValue);
+
+ // match a few but not all
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("2"), resValue);
+
+
+ // verify variables using in other tests: count nodes immediately under md:record
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecordSlashStar);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("3"), resValue);
+
+ // verify variables using in other tests: count number of records containing patient_info
+ arguments.clear();
+ arguments.add(attrXMdPatientInfo);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("1"), resValue);
+
+ // verify variables using in other tests: count number of records containing md:name
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("2"), resValue);
+
+ // verify variables using in other tests: count number of records containing md:malignancy
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdMalignancy);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("1"), resValue);
+
+
+
+
+ // match no element
+ arguments.clear();
+ arguments.add(attrXNotInRequest);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("0"), resValue);
+
+ // Resources included twice
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestDoubleResources, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-count More than one Content section for id 'urn:oasis:names:tc:xacml:3.0:attribute-category:resource'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // Content in both Resource and Action categories (ok)
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestResourceActionContent, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("2"), resValue);
+
+ // Content only in Action category (missing in Resources -> 0 according to spec)
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestContentInAction, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (BigInteger)res.getValue().getValue();
+ assertEquals(new BigInteger("0"), resValue);
+
+
+
+
+//TODO - any other tests????
+
+ // null Evaluation Context
+ arguments.clear();
+ arguments.add(attrXEmpty);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-count Got null EvaluationContext", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null Request
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecord);
+ res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-count Got null Request in EvaluationContext", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null attribute
+ arguments.clear();
+ arguments.add(attrXnull);
+ res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-count Got null attribute at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // no value
+ arguments.clear();
+ arguments.add(attrXNoValue);
+ res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-count XPathExpression returned null at index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // no category
+ arguments.clear();
+ arguments.add(attrXNoCategory);
+ res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-count Got null Category at index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // too many args
+ arguments.clear();
+ arguments.add(attrXEmpty);
+ arguments.add(attrXEmpty);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-count Expected 1 arguments, got 2", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too few args
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-count Expected 1 arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-count Expected data type 'xpathExpression' saw 'string' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null args
+ arguments.clear();
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-count Got null argument at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+ @Test
+ public void testXpath_node_equal() {
+
+
+ FunctionDefinitionXPath<?> fd = (FunctionDefinitionXPath<?>) StdFunctions.FD_XPATH_NODE_EQUAL;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_XPATH_NODE_EQUAL, fd.getId());
+ assertEquals(DataTypes.DT_XPATHEXPRESSION.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+
+ // test normal success - exactly the same set
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ arguments.add(attrXSlashSlashMdName);
+ ExpressionResult res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // success - second list is subset of first list
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecordSlashStar);
+ arguments.add(attrXMdPatientInfo);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // success - first list is subset of second list
+ arguments.clear();
+ arguments.add(attrXMdPatientInfo);
+ arguments.add(attrXSlashSlashMdRecordSlashStar);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // success - second list contains children of first list
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecord);
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // success - first list contains children of second list
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ arguments.add(attrXSlashSlashMdRecord);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+
+
+ // two non-overlapping sets
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdMalignancy);
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first list contains nothing
+ arguments.clear();
+ arguments.add(attrXNotInRequest);
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // second list contains nothing
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ arguments.add(attrXNotInRequest);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+
+
+//TODO
+ //?????
+ ///??????? add real tests
+ //////
+
+
+ // Resources included twice
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestDoubleResources, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal More than one Content section for id 'urn:oasis:names:tc:xacml:3.0:attribute-category:resource'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+
+ // Content in both Resource and Action categories (ok)
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestResourceActionContent, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // Content only in Action category (missing in Resources -> 0 according to spec)
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestContentInAction, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+
+ // null Evaluation Context
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecord);
+ arguments.add(attrXSlashSlashMdRecord);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal Got null EvaluationContext", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null Request
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecord);
+ arguments.add(attrXSlashSlashMdRecord);
+ res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal Got null Request in EvaluationContext", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null attribute
+ arguments.clear();
+ arguments.add(attrXnull);
+ arguments.add(attrXSlashSlashMdRecord);
+ res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal Got null attribute at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecord);
+ arguments.add(attrXnull);
+ res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal Got null attribute at arg index 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // no value
+ arguments.clear();
+ arguments.add(attrXNoValue);
+ arguments.add(attrXSlashSlashMdRecord);
+ res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal XPathExpression returned null at index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecord);
+ arguments.add(attrXNoValue);
+ res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal XPathExpression returned null at index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // no category
+ arguments.clear();
+ arguments.add(attrXNoCategory);
+ arguments.add(attrXSlashSlashMdRecord);
+ res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal Got null Category at index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecord);
+ arguments.add(attrXNoCategory);
+ res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal XPathExpression returned null at index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many args
+ arguments.clear();
+ arguments.add(attrXEmpty);
+ arguments.add(attrXEmpty);
+ arguments.add(attrXEmpty);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal Expected 2 arguments, got 3", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too few args
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal Expected 2 arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrXEmpty);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrBadType);
+ arguments.add(attrXEmpty);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal Expected data type 'xpathExpression' saw 'string' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrXEmpty);
+ arguments.add(attrBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal Expected data type 'xpathExpression' saw 'string' at arg index 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null args
+ arguments.clear();
+ arguments.add(attrXEmpty);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal Got null argument at arg index 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrXEmpty);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-equal Got null argument at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ }
+
+
+
+
+ @Test
+ public void testXpath_node_match() {
+
+
+ FunctionDefinitionXPath<?> fd = (FunctionDefinitionXPath<?>) StdFunctions.FD_XPATH_NODE_MATCH;
+
+ // check identity and type of the thing created
+ assertEquals(XACML3.ID_FUNCTION_XPATH_NODE_MATCH, fd.getId());
+ assertEquals(DataTypes.DT_XPATHEXPRESSION.getId(), fd.getDataTypeArgs().getId());
+ assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
+
+ // just to be safe... If tests take too long these can probably be eliminated
+ assertFalse(fd.returnsBag());
+ assertEquals(new Integer(2), fd.getNumArgs());
+
+
+ // test normal success - exactly the same set
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ arguments.add(attrXSlashSlashMdName);
+ ExpressionResult res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ Boolean resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // success - second list is subset of first list
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecordSlashStar);
+ arguments.add(attrXMdPatientInfo);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // success - first list is subset of second list
+ arguments.clear();
+ arguments.add(attrXMdPatientInfo);
+ arguments.add(attrXSlashSlashMdRecordSlashStar);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // success - second list contains children of first list
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecord);
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // success - first list contains children of second list
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ arguments.add(attrXSlashSlashMdRecord);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+
+
+ // two non-overlapping sets
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdMalignancy);
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // first list contains nothing
+ arguments.clear();
+ arguments.add(attrXNotInRequest);
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+ // second list contains nothing
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ arguments.add(attrXNotInRequest);
+ res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+//TODO
+ //?????
+ ///??????? add real tests
+ //////
+
+
+ // Resources included twice
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestDoubleResources, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match More than one Content section for id 'urn:oasis:names:tc:xacml:3.0:attribute-category:resource'", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+ // Content in both Resource and Action categories (ok)
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestResourceActionContent, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertTrue(resValue);
+
+ // Content only in Action category (missing in Resources -> 0 according to spec)
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdName);
+ arguments.add(attrXSlashSlashMdName);
+ res = fd.evaluate(new StdEvaluationContext(requestContentInAction, null, null), arguments);
+ assertTrue(res.isOk());
+ resValue = (Boolean)res.getValue().getValue();
+ assertFalse(resValue);
+
+
+ // null Evaluation Context
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecord);
+ arguments.add(attrXSlashSlashMdRecord);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match Got null EvaluationContext", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null Request
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecord);
+ arguments.add(attrXSlashSlashMdRecord);
+ res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match Got null Request in EvaluationContext", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null attribute
+ arguments.clear();
+ arguments.add(attrXnull);
+ arguments.add(attrXSlashSlashMdRecord);
+ res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match Got null attribute at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecord);
+ arguments.add(attrXnull);
+ res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match Got null attribute at arg index 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // no value
+ arguments.clear();
+ arguments.add(attrXNoValue);
+ arguments.add(attrXSlashSlashMdRecord);
+ res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match XPathExpression returned null at index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecord);
+ arguments.add(attrXNoValue);
+ res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match XPathExpression returned null at index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // no category
+ arguments.clear();
+ arguments.add(attrXNoCategory);
+ arguments.add(attrXSlashSlashMdRecord);
+ res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match Got null Category at index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrXSlashSlashMdRecord);
+ arguments.add(attrXNoCategory);
+ res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match XPathExpression returned null at index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too many args
+ arguments.clear();
+ arguments.add(attrXEmpty);
+ arguments.add(attrXEmpty);
+ arguments.add(attrXEmpty);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match Expected 2 arguments, got 3", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // too few args
+ arguments.clear();
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match Expected 2 arguments, got 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrXEmpty);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // bad arg type
+ arguments.clear();
+ arguments.add(attrBadType);
+ arguments.add(attrXEmpty);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match Expected data type 'xpathExpression' saw 'string' at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(attrXEmpty);
+ arguments.add(attrBadType);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match Expected data type 'xpathExpression' saw 'string' at arg index 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ // null args
+ arguments.clear();
+ arguments.add(attrXEmpty);
+ arguments.add(null);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match Got null argument at arg index 1", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+ arguments.clear();
+ arguments.add(null);
+ arguments.add(attrXEmpty);
+ res = fd.evaluate(null, arguments);
+ assertFalse(res.getStatus().isOk());
+ assertEquals( "function:xpath-node-match Got null argument at arg index 0", res.getStatus().getStatusMessage());
+ assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
+
+
+
+ }
+
+
+
+ //
+ // DEPRECATED versions that use String arguments rather than XPATHEXPRESSIONs
+ // are NOT supported due to ambiguity in the semantics between 2.0 (<Request> is root and has only one <Content> in resources)
+ // and 3.0 (<Content> is root and there are multiple <Content> sections in any category)
+ //
+
+
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestCategoryTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestCategoryTest.java
new file mode 100755
index 0000000..c5c40e3
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestCategoryTest.java
@@ -0,0 +1,4165 @@
+/*
+ * 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.json;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.std.json.JSONRequest;
+import com.att.research.xacml.std.json.JSONStructureException;
+
+/**
+ * Test JSON Request convert to object - Category sub-component. Does not include "Default" Categories (Subject, Action, Resource, Environment).
+ * Basic existance/absence of Category is tested in RequestMainTest.
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * NOTE:
+ * The "correct" way to verify that each JSON string gets translated into our internal Objects correctly is to look explicitly at each of the child objects
+ * and verify that they are correct. This would involve a lot of coding to get child of child of child and individually verify each property of each element.
+ * To simplify testing we assume that request.toString() correctly includes a complete text representation of every sub-component of the Request object
+ * and we compare the resulting String to our expected String.
+ * This has two possible sources of error:
+ * - toString might not include some sub-component, and
+ * - the initial verification of the resulting string is done by hand and may have been incorrect.
+ *
+ * @author glenngriffin
+ *
+ */
+public class RequestCategoryTest {
+
+ // The request object output from each test conversion from JSON string
+ Request request;
+
+
+ /*
+ * Request that uses all fields with both single and multiple entries
+ */
+ String allFieldsRequest =
+ "{\"Request\": {" +
+ "\"ReturnPolicyIdList\" : true ," +
+ "\"CombinedDecision\" : true ," +
+ "\"XPathVersion\" : \"http://www.w3.org/TR/1999/REC-xpath-19991116\"," +
+ "\"MultiRequests\" : {" +
+ "\"RequestReference\": [" +
+ "{ " +
+ "\"ReferenceId\" : [\"foo1\",\"bar1\"]" +
+ "}," +
+ "{" +
+ "\"ReferenceId\" : [\"foo2\",\"bar1\"]" +
+ "}]" +
+ "}," +
+
+ "\"Category\": [" +
+ "{ " +
+ "\"CategoryId\": \"custom-category\", " +
+ "\"Id\" : \"customId\", " +
+ "\"Attribute\" : [" +
+ "{" +
+ "\"AttributeId\" : \"document-id\", " +
+ "\"DataType\" : \"integer\", " +
+ "\"Value\" : 123 " +
+ "}, " +
+ "{" +
+ "\"AttributeId\" : \"document-url\", " +
+ "\"DataType\" : \"anyURI\", " +
+ "\"Value\" : \"http://somewhere.over.the.com/rainbow\" " +
+ "}, " +
+ "{" +
+ "\"AttributeId\" : \"page-list\", " +
+ "\"Value\" : [1, 2, 3, 4.5, 3, 2, 1] " +
+ "} " +
+ "]" +
+ "}, " +
+ "{ " +
+ "\"CategoryId\": \"another-custom-cat\", " +
+ "\"Id\" : \"anotherXmlId\", " +
+ "\"Attribute\" : []" +
+ "} " +
+ "], " +
+
+ "\"AccessSubject\":{ " +
+ "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" +
+ "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" +
+ "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+
+ "</book></catalog>\"," +
+ "\"Attribute\" : []" +
+ "}, " +
+
+ "\"Resource\" : {" +
+ "\"Content\" : \"PD94bWwgdmVyc2lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9yPkdhbWJhcmRlbGxhLCBNYXR0aGV3PC9hdXRob3I+PHRpdGxlPlhNT" +
+ "CBEZXZlbG9wZXIncyBHdWlkZTwvdGl0bGU+PGdlbnJlPkNvbXB1dGVyPC9nZW5yZT48cHJpY2U+NDQuOTU8L3ByaWNlPjxwdWJsaXNoX2RhdGU+MjAwMC0xMC0wMTwvcHVibGlzaF"+
+ "9kYXRlPjxkZXNjcmlwdGlvbj5BbiBpbi1kZXB0aCBsb29rIGF0IGNyZWF0aW5nIGFwcGxpY2F0aW9ucyB3aXRoIFhNTC48L2Rlc2NyaXB0aW9uPjwvYm9vaz48L2NhdGFsb2c+\"" +
+
+
+ "} " +
+
+
+ "}}";
+
+ /*
+ * The following example comes directly from the JSON Profile Spec
+ */
+ String exampleFromSpec = "{ " +
+ "\"Request\" : { " +
+ "\"AccessSubject\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "}, " +
+ "\"Action\" : { " +
+ "\"Attribute\": " +
+ "{ " +
+ "\"Id\" : \"action-id\", " +
+ "\"Value\" : \"http://www.xacml.eu/buy\", " +
+ "\"DataType\" : \"anyURI\" " +
+ "} " +
+ "}, " +
+ "\"Resource\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"book-title\", " +
+ "\"Value\" : \"Learn German in 90 days\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"currency\", " +
+ "\"Value\" : \"SEK\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"price\", " +
+ "\"Value\" : 123.34 " +
+ "} " +
+ "] " +
+ "} " +
+ "} " +
+ "} ";
+
+
+ /*
+ * The following example comes directly from the JSON Profile Spec (modified to include a "</Catalog>" missing from both examples).
+ * It shows the two ways of handling XPath content, as escaped XML and as Base64 encoding.
+ */
+ String xPathExampleFromSpec = "{ " +
+ "\"Request\" : { " +
+ "\"Resource\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"urn:oasis:names:tc:xacml:3.0:content-selector\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : { " +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", " +
+ "\"Namespaces\" : [{ " +
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}, " +
+ "{ " +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "} " +
+ "], " +
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" " +
+ "} " +
+ "} " +
+ "] " +
+ "} " +
+ "} " +
+ "} ";
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ // Top-level of Category
+ @Test
+ public void testCategoryTopLevel() {
+
+ // empty Category
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Missing value
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\" }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\" : }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category without CategoryId
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{}] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category with CategoryId value missing or =""
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\"] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"\" ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // CategoryId wrong type
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : true } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : 123 } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category with Id
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Id\" : \"customId\" } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category},xmlId=customId}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category with Id - wrong type
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Id\" : true } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Id\" : 123 } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // Category without Id
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\" } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // Category with standard CategoryId
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\" } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category with extra unknown field
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", unknown } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"unknown\" : 123 } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category with multiple sub-Category objects using same CategoryId
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"category1\" }, {\"CategoryId\" : \"category1\" } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=category1}}{super={category=category1}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ }
+
+
+
+ // Tests related to Attributes
+ @Test
+ public void testCategoryAttributes() {
+
+ // Category with Attribute but none given ("Attribute" : [] )
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with empty attribute (missing both AttributeId and Id)
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with AttributeId and no Value
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"AttributeId\" : \"document-id\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute missing AttributeId but with Id
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"AttributeId\" : \"document-id\", " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute missing AttributeId but with Id
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute including both AttributeId and Id with same value
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"AttributeId\" : \"document-id\", " +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute missing both AttributeId and Id
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute AttributeId not string
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"AttributeId\" : true, " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"AttributeId\" : 123, " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute Id not string
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : true, " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : 123, " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // Category Attribute with DataType
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"integer\", " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with DataType not string (e.g. "DataType" : 55.5 )
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : true, " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with unknown DataType
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"no such data type\", " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : 321, " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with multiple value array
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"dayTimeDuration\", " +
+ "\"Value\" : [\"P3D\", \"P2DT12H34M\", \"PT15M\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=3hours=0minutes=0seconds=0millis=0},factionalSeconds=0.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=2hours=12minutes=34seconds=0millis=0},factionalSeconds=0.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=0hours=0minutes=15seconds=0millis=0},factionalSeconds=0.0}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute multiple value with null in array
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"dayTimeDuration\", " +
+ "\"Value\" : [\"P3D\", , \"P15M\"] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with array value with no values ("Attribute": [ {"AttributeId" :"a", Value:[] } ] } )
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"dayTimeDuration\", " +
+ "\"Value\" : [ ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with no DataType and array with no values
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with Issuer
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Issuer\" : \"University Press\", " +
+ "\"DataType\" : \"integer\", " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],issuer=University Press,includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with Issuer not string
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Issuer\" : true, " +
+ "\"DataType\" : \"integer\", " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Issuer\" : 4.56, " +
+ "\"DataType\" : \"integer\", " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with includeInResult=true
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : 123, " +
+ "\"IncludeInResult\" : true " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=true}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with includeInResult = false
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : 123, " +
+ "\"IncludeInResult\" : false " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with includeInResult not boolean
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : 123, " +
+ "\"IncludeInResult\" : \"abc\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : 123, " +
+ "\"IncludeInResult\" : 123.45 " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ }
+
+
+
+ // Tests related to DataTypes within Attributes
+ @Test
+ public void testCategoryAttributesDataTypesSimple() {
+
+ // Category Attribute using full Identifier for each data type
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : \"abc\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " +
+ "\"Value\" : true " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " +
+ "\"Value\" : 123.34 " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " +
+ "\"Value\" : \"12:00:00Z\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " +
+ "\"Value\" : \"2002-10-10\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " +
+ "\"Value\" : \"2002-10-10T12:00:00Z\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " +
+ "\"Value\" : \"P23DT7H12M54S\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " +
+ "\"Value\" : \"P165Y8M\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " +
+ "\"Value\" : \"aValue\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " +
+ "\"Value\" : \"FA027B7D12CC34DDD20012AEEF\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#base64Binary\", " +
+ "\"Value\" : \"lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,2,35,-13,-29,-58,54,23,70,22,-58,-10,115,-29,-58,38,-10,-10,-78,6,-106,67,-46,38,38,-77,19,3,18,35,-29,-58,23,87,70,-122,-9]}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " +
+ "\"Value\" : \"someone.else@A.COMPANY.com\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.COMPANY.com}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +
+ "\"Value\" : \"cn=Julius Hibbert, o=Medi Corporation, c=US\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " +
+ "\"Value\" : \"121.221.43.58:12345\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " +
+ "\"Value\" : \"aValue\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : ["
+ + "{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}" +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString());
+
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // Category Attribute shorthand notation for each data type
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"string\", " +
+ "\"Value\" : \"abc\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"boolean\", " +
+ "\"Value\" : true " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"integer\", " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"double\", " +
+ "\"Value\" : 123.34 " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"time\", " +
+ "\"Value\" : \"12:00:00Z\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"date\", " +
+ "\"Value\" : \"2002-10-10\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"dateTime\", " +
+ "\"Value\" : \"2002-10-10T12:00:00Z\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"dayTimeDuration\", " +
+ "\"Value\" : \"P23DT7H12M54S\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"yearMonthDuration\", " +
+ "\"Value\" : \"P165Y8M\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"anyURI\", " +
+ "\"Value\" : \"aValue\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"hexBinary\", " +
+ "\"Value\" : \"FA027B7D12CC34DDD20012AEEF\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"base64Binary\", " +
+ "\"Value\" : \"lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,2,35,-13,-29,-58,54,23,70,22,-58,-10,115,-29,-58,38,-10,-10,-78,6,-106,67,-46,38,38,-77,19,3,18,35,-29,-58,23,87,70,-122,-9]}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"rfc822Name\", " +
+ "\"Value\" : \"someone.else@A.COMPANY.com\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.COMPANY.com}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"x500Name\", " +
+ "\"Value\" : \"cn=Julius Hibbert, o=Medi Corporation, c=US\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"ipAddress\", " +
+ "\"Value\" : \"121.221.43.58:12345\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"dnsName\", " +
+ "\"Value\" : \"aValue\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : ["
+ + "{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}" +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString());
+
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+
+ // infer data type - only integer, boolean and double are distinguishable from strings; everything else is treated as a string
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"abc\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : true " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : 123.34 " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"12:00:00Z\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"2002-10-10\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"2002-10-10T12:00:00Z\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"P23DT7H12M54S\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"P165Y8M\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"aValue\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"FA027B7D12CC34DDD20012AEEF\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"someone.else@A.COMPANY.com\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.COMPANY.com}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +
+ "\"Value\" : \"cn=Julius Hibbert, o=Medi Corporation, c=US\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"121.221.43.58:12345\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"aValue\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"aValue\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : ["
+ + "{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}" +
+ "}] } ] }}");
+ // gets inferred to a String containing the whole structure under Value as a String
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value={XPathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource, Namespaces=[{Namespace=urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}, {Prefix=md, Namespace=urn:example:med:schemas:record}], XPath=md:record/md:patient/md:patientDoB}}],includeInResults=false}]}}]}", request.toString());
+
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ }
+
+
+
+ @Test
+ public void testCategoryAttributesDataTypesNotMatchValue() {
+
+ // Category Attribute with DataType not matching value type (JSON type derived from syntax)
+ // AUTO-CONVERSION from Boolean to String!
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : true " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // SUCCESSFUL AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // SUCCESSFUL AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : 123.34 " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123.34}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " +
+ "\"Value\" : \"abc\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " +
+ "\"Value\" : 123.45 " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // SUCCESSFUL AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " +
+ "\"Value\" : \"123\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " +
+ "\"Value\" : true " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " +
+ "\"Value\" : 123.45 " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // SUCCESSFUL AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " +
+ "\"Value\" : \"123.34\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " +
+ "\"Value\" : true " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // allow integer to auto-convert to double when DataType is given
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " +
+ "\"Value\" : 123 " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.0}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // special JavaScript values not allowed except for -0 (inappropriate requirement in spec - check it anyway)
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " +
+ "\"Value\" : \"NaN\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " +
+ "\"Value\" : \"INF\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " +
+ "\"Value\" : \"-INF\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // JavaScript 0 and -0 are ok
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " +
+ "\"Value\" : 0 " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=0}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " +
+ "\"Value\" : -0 " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=0}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // All other data types are checked when we convert internally, so value must be syntactically correct
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " +
+ "\"Value\" : \"syntactically incorrect value\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " +
+ "\"Value\" : \"syntactically incorrect value\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " +
+ "\"Value\" : \"syntactically incorrect value\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " +
+ "\"Value\" : \"syntactically incorrect value\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " +
+ "\"Value\" : \"syntactically incorrect value\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " +
+ "\"Value\" : \"syntactically incorrect value\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " +
+ "\"Value\" : \"syntactically incorrect value\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Base64 convert does not throw an exception if the contents are not Base64, so cannot test for this.
+ // Any problem with the data will have to be discovered later when the data is used.
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " +
+ "\"Value\" : \"syntactically incorrect value\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +
+ "\"Value\" : \"syntactically incorrect value\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " +
+ "\"Value\" : \"syntactically incorrect value\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " +
+ "\"Value\" : \"syntactically incorrect value\" " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // Cannot test XPathExpressions here. The XPathExpression gets converted into a simple String value within the XPathExpression object,
+ // but it is not evaluated or compiled at that time. Therefore we do not know whether or not the value is valid until it is used in a computation.
+
+ }
+
+
+ @Test
+ public void testArrayDataTypes() {
+
+ // array of size 0
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : [] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // Category Attribute value array DataType given (repeat for all data types)
+ // Category Attribute using full Identifier for each data type
+ // Category Attribute shorthand notation for each data type
+ // Also tests for mixes of different JSON types (trying incorrect strings for XACML data types whenever possible)
+ // string
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : [\"abc\", \"def\", \"hig\", \"lmn\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=def}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"string\", " +
+ "\"Value\" : [\"abc\", \"def\", \"hig\", \"lmn\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=def}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // SUCCESSFUL AUTO-CONVERT to DataType
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : [\"abc\", true, \"hig\", \"lmn\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // SUCCESSFUL AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : [\"abc\",123, \"hig\", \"lmn\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // SUCCESSFUL AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : [\"abc\", 34.34, \"hig\", \"lmn\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=34.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // boolean
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " +
+ "\"Value\" : [true, true, false, true, false ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"boolean\", " +
+ "\"Value\" : [true, true, false, true, false ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " +
+ "\"Value\" : [true, \"abc\", false, true, false ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " +
+ "\"Value\" : [true, 123, false, true, false ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " +
+ "\"Value\" : [true, 12.34, false, true, false ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+
+ // integer
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " +
+ "\"Value\" : [123, 456, 765, 234] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=456}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=765}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=234}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"integer\", " +
+ "\"Value\" : [123, 456, 765, 234] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=456}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=765}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=234}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " +
+ "\"Value\" : [123, \"abc\", 765, 234] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " +
+ "\"Value\" : [123, true, 765, 234] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " +
+ "\"Value\" : [123, 34.56, 765, 234] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // double
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " +
+ "\"Value\" : [ 123.34, 543.54, 3445.455, 4543,543 ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.54}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"double\", " +
+ "\"Value\" : [ 123.34, 543.54, 3445.455, 4543,543 ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.54}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // special case - auto-convert integer to boolean
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " +
+ "\"Value\" : [ 123.34, 111122, 3445.455, 4543,543 ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=111122.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " +
+ "\"Value\" : [ 123.34, true, 3445.455, 4543,543 ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " +
+ "\"Value\" : [ 123.34, \"abb\", 3445.455, 4543,543 ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // time
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " +
+ "\"Value\" : [ \"12:00:00Z\", \"12:00:00Z\", \"12:00:00Z\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"time\", " +
+ "\"Value\" : [ \"12:00:00Z\", \"12:00:00Z\", \"12:00:00Z\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " +
+ "\"Value\" : [ \"12:00:00Z\", \"not a time\", \"12:00:00Z\"] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " +
+ "\"Value\" : [ \"12:00:00Z\", true, \"12:00:00Z\"] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " +
+ "\"Value\" : [ \"12:00:00Z\", 123, \"12:00:00Z\"] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " +
+ "\"Value\" : [ \"12:00:00Z\", 12.34, \"12:00:00Z\"] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // date
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " +
+ "\"Value\" : [\"2002-10-10\",\"2002-10-10\",\"2002-10-10\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"date\", " +
+ "\"Value\" : [\"2002-10-10\",\"2002-10-10\",\"2002-10-10\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " +
+ "\"Value\" : [\"2002-10-10\",\"not a date\",\"2002-10-10\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " +
+ "\"Value\" : [\"2002-10-10\",true,\"2002-10-10\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " +
+ "\"Value\" : [\"2002-10-10\",123,\"2002-10-10\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " +
+ "\"Value\" : [\"2002-10-10\",123.45,\"2002-10-10\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // dateTime
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " +
+ "\"Value\" : [ \"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"dateTime\", " +
+ "\"Value\" : [ \"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " +
+ "\"Value\" : [ \"2002-10-10T12:00:00Z\",\"not a dateTime\",\"2002-10-10T12:00:00Z\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " +
+ "\"Value\" : [ \"2002-10-10T12:00:00Z\",true,\"2002-10-10T12:00:00Z\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " +
+ "\"Value\" : [ \"2002-10-10T12:00:00Z\",123,\"2002-10-10T12:00:00Z\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " +
+ "\"Value\" : [ \"2002-10-10T12:00:00Z\",12.34,\"2002-10-10T12:00:00Z\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // dayTimeDuration
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " +
+ "\"Value\" : [ \"P23DT7H12M54S\",\"P23DT7H12M54S\",\"P23DT7H12M54S\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"dayTimeDuration\", " +
+ "\"Value\" : [ \"P23DT7H12M54S\",\"P23DT7H12M54S\",\"P23DT7H12M54S\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " +
+ "\"Value\" : [ \"P23DT7H12M54S\",\"not a duration\",\"P23DT7H12M54S\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " +
+ "\"Value\" : [ \"P23DT7H12M54S\",true,\"P23DT7H12M54S\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " +
+ "\"Value\" : [ \"P23DT7H12M54S\",123,\"P23DT7H12M54S\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " +
+ "\"Value\" : [ \"P23DT7H12M54S\",11.22,\"P23DT7H12M54S\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // yearMonth duration
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " +
+ "\"Value\" : [ \"P165Y8M\",\"P165Y8M\",\"P165Y8M\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"yearMonthDuration\", " +
+ "\"Value\" : [ \"P165Y8M\",\"P165Y8M\",\"P165Y8M\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " +
+ "\"Value\" : [ \"P165Y8M\",\"not a duration\",\"P165Y8M\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " +
+ "\"Value\" : [ \"P165Y8M\",true,\"P165Y8M\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " +
+ "\"Value\" : [ \"P165Y8M\",123,\"P165Y8M\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " +
+ "\"Value\" : [ \"P165Y8M\",11.22,\"P165Y8M\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // anyURI
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " +
+ "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"anyURI\", " +
+ "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // SUCCESSFUL AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " +
+ "\"Value\" : [ \"aValue\",true,\"aValue\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // SUCCESSFUL AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " +
+ "\"Value\" : [ \"aValue\",123,\"aValue\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " +
+ "\"Value\" : [ \"aValue\",11.111,\"aValue\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=11.111}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // hexBinary
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " +
+ "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"hexBinary\", " +
+ "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " +
+ "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",true,\"012AEEF\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " +
+ "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",123,\"012AEEF\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " +
+ "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",11.44,\"012AEEF\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // base64Binary
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#base64Binary\", " +
+ "\"Value\" : [ \"aG9y\",\"lvbj0iMS4xIj48YXV0aG9y\",\"lvbjIj48YXV0aG9y\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,18,35,-29,-58,23,87,70,-122,-9]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"base64Binary\", " +
+ "\"Value\" : [ \"aG9y\",\"lvbj0iMS4xIj48YXV0aG9y\",\"lvbjIj48YXV0aG9y\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,18,35,-29,-58,23,87,70,-122,-9]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#base64Binary\", " +
+ "\"Value\" : [ \"aG9y\",true,\"lvbjIj48YXV0aG9y\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-74,-69,-98]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#base64Binary\", " +
+ "\"Value\" : [ \"aG9y\",1123,\"lvbjIj48YXV0aG9y\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-41,93,-73]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#base64Binary\", " +
+ "\"Value\" : [ \"aG9y\",11.22,\"lvbjIj48YXV0aG9y\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-41,93,-74]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // RFC822 name
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " +
+ "\"Value\" : [ \"sne.else@A.COMPANY.com\",\"one.else@A.COMPANY.com\",\"someone.else@A.CONY.com\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=sne.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=one.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.CONY.com}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"rfc822Name\", " +
+ "\"Value\" : [ \"sne.else@A.COMPANY.com\",\"one.else@A.COMPANY.com\",\"someone.else@A.CONY.com\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=sne.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=one.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.CONY.com}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " +
+ "\"Value\" : [ \"sne.else@A.COMPANY.com\",\"not a dns\",\"someone.else@A.CONY.com\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " +
+ "\"Value\" : [ \"sne.else@A.COMPANY.com\",true,\"someone.else@A.CONY.com\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " +
+ "\"Value\" : [ \"sne.else@A.COMPANY.com\",111,\"someone.else@A.CONY.com\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " +
+ "\"Value\" : [ \"sne.else@A.COMPANY.com\",11.22,\"someone.else@A.CONY.com\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // x500
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +
+ "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"x500Name\", " +
+ "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +
+ "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"non-x500 string\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +
+ "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", true, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +
+ "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 1111, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " +
+ "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 11.22, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // ipAddress
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " +
+ "\"Value\" : [ \"121.221.43.58:12345\",\"121.221.43.58:12345\",\"121.221.43.58:12345\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"ipAddress\", " +
+ "\"Value\" : [ \"121.221.43.58:12345\",\"121.221.43.58:12345\",\"121.221.43.58:12345\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=121.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " +
+ "\"Value\" : [ \"121.221.43.58:12345\",\"not an ip address\",\"121.221.43.58:12345\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " +
+ "\"Value\" : [ \"121.221.43.58:12345\",true,\"121.221.43.58:12345\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " +
+ "\"Value\" : [ \"121.221.43.58:12345\",1111,\"121.221.43.58:12345\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " +
+ "\"Value\" : [ \"121.221.43.58:12345\",11.22,\"121.221.43.58:12345\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // dnsName
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " +
+ "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"dnsName\", " +
+ "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " +
+ "\"Value\" : [ \"aValue\", true, \"aValue\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=true}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " +
+ "\"Value\" : [ \"aValue\", 1111, \"aValue\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " +
+ "\"Value\" : [ \"aValue\", 11.22, \"aValue\" ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // xPathExpression
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " +
+ "\"Value\" : [ "
+ + "{" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : ["
+ + "{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}," +
+ "{" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : ["
+ + "{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}," +
+ "{" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : ["
+ + "{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}"
+ + "] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " +
+ "\"Value\" : [ "
+ + "{" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : ["
+ + "{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}," +
+ "\"simpleString\"," +
+ "{" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : ["
+ + "{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}"
+ + "] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " +
+ "\"Value\" : [ "
+ + "{" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : ["
+ + "{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}," +
+ "true," +
+ "{" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : ["
+ + "{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}"
+ + "] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " +
+ "\"Value\" : [ "
+ + "{" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : ["
+ + "{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}," +
+ "123," +
+ "{" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : ["
+ + "{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}"
+ + "] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " +
+ "\"Value\" : [ "
+ + "{" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : ["
+ + "{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}," +
+ "12.34," +
+ "{" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : ["
+ + "{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}"
+ + "] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ }
+
+
+
+
+
+
+
+ @Test
+ public void testArrayNoDataTypes() {
+
+ // array of size 0
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // Category Attribute value array DataType Not given (repeat for all data types)
+ // Also tests for mixes of different JSON types (trying incorrect strings for XACML data types whenever possible)
+ // string
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [\"abc\", \"def\", \"hig\", \"lmn\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=def}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // SUCCESSFUL AUTO-CONVERT to DataType
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [\"abc\", true, \"hig\", \"lmn\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // SUCCESSFUL AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [\"abc\",123, \"hig\", \"lmn\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // SUCCESSFUL AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [\"abc\", 34.34, \"hig\", \"lmn\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=34.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // boolean
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [true, true, false, true, false ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [true, \"abc\", false, true, false ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [true, 123, false, true, false ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [true, 12.34, false, true, false ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+
+ // integer
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [123, 456, 765, 234] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=456}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=765}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=234}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [123, \"abc\", 765, 234] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [123, true, 765, 234] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+
+ // double
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ 123.34, 543.54, 3445.455, 4543,543 ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.54}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // special case - auto-convert integer to boolean
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ 123.34, 111122, 3445.455, 4543,543 ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=111122.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ 123.34, true, 3445.455, 4543,543 ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ 123.34, \"abb\", 3445.455, 4543,543 ] " +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // time - defaults to String
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"12:00:00Z\", \"12:00:00Z\", \"12:00:00Z\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // SUCCESSFUL AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"12:00:00Z\", true, \"12:00:00Z\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // SUCCESSFUL AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"12:00:00Z\", 123, \"12:00:00Z\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"12:00:00Z\", 12.34, \"12:00:00Z\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // date - defaults to String
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [\"2002-10-10\",\"2002-10-10\",\"2002-10-10\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [\"2002-10-10\",true,\"2002-10-10\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [\"2002-10-10\",123,\"2002-10-10\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [\"2002-10-10\",123.45,\"2002-10-10\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123.45}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // dateTime - defaults to String
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"2002-10-10T12:00:00Z\",true,\"2002-10-10T12:00:00Z\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"2002-10-10T12:00:00Z\",123,\"2002-10-10T12:00:00Z\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"2002-10-10T12:00:00Z\",12.34,\"2002-10-10T12:00:00Z\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // dayTimeDuration - defaults to String
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"P23DT7H12M54S\",\"P23DT7H12M54S\",\"P23DT7H12M54S\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ //AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"P23DT7H12M54S\",true,\"P23DT7H12M54S\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"P23DT7H12M54S\",123,\"P23DT7H12M54S\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"P23DT7H12M54S\",11.22,\"P23DT7H12M54S\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // yearMonth duration - defaults to String
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"P165Y8M\",\"P165Y8M\",\"P165Y8M\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"P165Y8M\",true,\"P165Y8M\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"P165Y8M\",123,\"P165Y8M\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"P165Y8M\",11.22,\"P165Y8M\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // anyURI - defaults to String
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\",true,\"aValue\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\",123,\"aValue\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\",11.111,\"aValue\"] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // hexBinary - defaults to String
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",true,\"012AEEF\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=012AEEF}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",123,\"012AEEF\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=012AEEF}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",11.44,\"012AEEF\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.44}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=012AEEF}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // base64Binary - defaults to String
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aG9y\",\"lvbj0iMS4xIj48YXV0aG9y\",\"lvbjIj48YXV0aG9y\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbj0iMS4xIj48YXV0aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aG9y\",true,\"lvbjIj48YXV0aG9y\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aG9y\",1123,\"lvbjIj48YXV0aG9y\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aG9y\",11.22,\"lvbjIj48YXV0aG9y\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // RFC822 name - defaults to String
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"sne.else@A.COMPANY.com\",\"one.else@A.COMPANY.com\",\"someone.else@A.CONY.com\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=one.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"sne.else@A.COMPANY.com\",true,\"someone.else@A.CONY.com\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"sne.else@A.COMPANY.com\",111,\"someone.else@A.CONY.com\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"sne.else@A.COMPANY.com\",11.22,\"someone.else@A.CONY.com\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // x500 - defaults to String
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", true, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 1111, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 11.22, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // ipAddress - defaults to String
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"121.221.43.58:12345\",\"121.221.43.58:12345\",\"121.221.43.58:12345\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"121.221.43.58:12345\",true,\"121.221.43.58:12345\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"121.221.43.58:12345\",1111,\"121.221.43.58:12345\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"121.221.43.58:12345\",11.22,\"121.221.43.58:12345\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=121.221.43.58:12345}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // dnsName - defaults to String
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", true, \"aValue\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", 1111, \"aValue\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", 11.22, \"aValue\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // xPathExpression - defaults to String
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", true, \"aValue\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", 1111, \"aValue\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ // AUTO-CONVERT
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", 11.22, \"aValue\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ }
+
+
+
+
+ @Test
+ public void testXPathExpression() {
+ // Category Attribute with XPathExpression including XPathCategory and XPath
+ // Category Attribute with XPathExpression with Namespaces with/without Prefix
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : ["
+ + "{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{ "+
+ "\"Prefix\" : \"lab\", " +
+ "\"Namespace\" : \"http://somewhere/uri.html\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}" +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{lab,http://somewhere/uri.html}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with XPathExpression missing XPathCategory
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"Namespaces\" : [{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}" +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with XPathExpression missing XPath
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : [{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}] "+
+ "}" +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with XPathExpression without Namespaces
+ // (path does not contain namespace references)
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"XPath\" : \"record/patient/patientDoB\" "+
+ "}" +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=record/patient/patientDoB,Namespace=null,status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with XPathExpression with 0 Namespaces
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : [], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}" +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace=null,status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // Category Attribute with XPathExpression with Namespaces without mandatory Namespace
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : [{ "+
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}" +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : [{ "+
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}" +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with XPathExpression with Namespaces with 2 namespaces using same prefix
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : [{ "+
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}" +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with XPathExpression without Namespaces which are used within the XPathExpression (NOTE: Error is not syntactic and is not found by converter)
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}" +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace=null,status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with XPathExpression containing simple value (must be object)
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : \"simple Value\"" +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with Namespaces containing simple value (must be object)
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : [ \"simpleValue\"," +
+ "{" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}" +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // Category Attribute with Namespaces non-string Namespace
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : [ {" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : 123 " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}" +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with Namespaces non-string prefix
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : [ {" +
+ "\"Prefix\" : 123, " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}" +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with Namespaces non-string XPathCategory
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : 123," +
+ "\"Namespaces\" : [ {" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+
+ "}" +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category Attribute with Namespaces non-string XPath
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : {" +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," +
+ "\"Namespaces\" : [ {" +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "}], "+
+ "\"XPath\" : 123 "+
+ "}" +
+ "}] } ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ }
+
+
+
+ @Test
+ public void testContent() {
+
+ // Category with Content in XML, escaped properly
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " +
+ "}]," +
+ "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" +
+ "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" +
+ "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+
+ "</book></catalog>\"" +
+ "} ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]},contentRoot=[catalog: null]}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category with Content in XML, double quotes and back-slashes NOT escaped properly?
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " +
+ "}]," +
+ "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" +
+ "<book id=\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" +
+ "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+
+ "</book></catalog>\"" +
+ "} ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category with Content in Base64
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " +
+ "}]," +
+ "\"Content\" : \"PD94bWwgdmVyc2lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9yPkdhbWJhcmRlbGxhLCBNYXR0aGV3PC9hdXRob3I+PHRpdGxlPlhNT" +
+ "CBEZXZlbG9wZXIncyBHdWlkZTwvdGl0bGU+PGdlbnJlPkNvbXB1dGVyPC9nZW5yZT48cHJpY2U+NDQuOTU8L3ByaWNlPjxwdWJsaXNoX2RhdGU+MjAwMC0xMC0wMTwvcHVibGlzaF"+
+ "9kYXRlPjxkZXNjcmlwdGlvbj5BbiBpbi1kZXB0aCBsb29rIGF0IGNyZWF0aW5nIGFwcGxpY2F0aW9ucyB3aXRoIFhNTC48L2Rlc2NyaXB0aW9uPjwvYm9vaz48L2NhdGFsb2c+\"" +
+ "} ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]},contentRoot=[catalog: null]}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Category with Bad Content in Base64
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " +
+ "}]," +
+ "\"Content\" : \"PD94bWwgdmV\"" +
+ "} ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ }
+
+
+
+
+ @Test
+ public void testDuplicates() {
+ // duplicate of same element within Category array is ok
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : \"abc\" " +
+ "}] }, " +
+ "{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : \"abc\" " +
+ "}] } "
+ + "] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // duplicate Attribute
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [" +
+ "{\"CategoryId\" : \"custom-category\","
+ + " \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : \"abc\" " +
+ "}], "
+ + " \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : \"abc\" " +
+ "}] "
+ + "} "
+ + " }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // dup id
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : \"abc\" " +
+ "}] } "
+ + "] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // dup DataType
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : \"abc\" " +
+ "}] } "
+ + "] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // dup Value
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " +
+ "\"Value\" : \"abc\" " +
+ "\"Value\" : \"abc\" " +
+ "}] } "
+ + "] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // duplicate Content
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{"
+ + "\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " +
+ "}]," +
+ "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" +
+ "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" +
+ "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+
+ "</book></catalog>\" , " +
+ "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" +
+ "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" +
+ "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+
+ "</book></catalog>\"" +
+ "} ] }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ }
+
+
+
+//TODO - Shorthand for CategoryId ????
+
+
+}
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestConformanceTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestConformanceTest.java
new file mode 100755
index 0000000..85c3bed
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestConformanceTest.java
@@ -0,0 +1,349 @@
+/*
+ * 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.json;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.RequestAttributes;
+import com.att.research.xacml.api.RequestReference;
+import com.att.research.xacml.std.dom.DOMRequest;
+import com.att.research.xacml.std.json.JSONRequest;
+import com.att.research.xacml.std.json.JSONStructureException;
+/**
+ * Test JSON Request convert to object - Conformance tests
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * NOTE:
+ * The "correct" way to verify that each JSON string gets translated into our internal Objects correctly is to look explicitly at each of the child objects
+ * and verify that they are correct. This would involve a lot of coding to get child of child of child and individually verify each property of each element.
+ * To simplify testing we assume that request.toString() correctly includes a complete text representation of every sub-component of the Request object
+ * and we compare the resulting String to our expected String.
+ * This has two possible sources of error:
+ * - toString might not include some sub-component, and
+ * - the initial verification of the resulting string is done by hand and may have been incorrect.
+ *
+ * @author glenngriffin
+ *
+ */
+public class RequestConformanceTest {
+
+ // where to find the conformance test XML files
+ private final String CONFORMANCE_DIRECTORY_PATH = "testsets/conformance/xacml3.0-ct-v.0.4";
+
+ // The request object output from each test conversion from JSON string
+ Request request;
+
+
+
+
+
+ // test just one of each top-level element.
+ // For simple elements also test for incorrect type
+ @Test
+ public void testConformanceRequests() {
+
+ List<File> filesInDirectory = null;
+
+ File conformanceDirectory = null;
+
+ File currentFile = null;
+
+ try {
+ conformanceDirectory = new File(CONFORMANCE_DIRECTORY_PATH);
+ filesInDirectory = getRequestsInDirectory(conformanceDirectory);
+ } catch (Exception e) {
+ fail("Unable to set up Conformance tests for dir '" + conformanceDirectory.getAbsolutePath()+"' e="+ e);
+ }
+
+ // run through each XML file
+ // - load the file from XML into an internal Request object
+ // - generate the JSON representation of that Request object
+ // - load that JSON representation into a new Request object
+ // - compare the 2 Request objects
+ Request xmlRequest = null;
+ Request jsonRequest = null;
+ try {
+ for (File f : filesInDirectory) {
+ currentFile = f;
+
+//// This is a simple way to select just one file for debugging - comment out when not being used
+//if ( ! f.getName().equals("IIA023Request.xml")) { continue; }
+
+// during debugging it is helpful to know what file it is starting to work on
+// System.out.println("starting file="+currentFile.getName());
+
+ try {
+ // load XML into a Request object
+ xmlRequest = DOMRequest.load(f);
+ xmlRequest.getStatus();
+ } catch (Exception e) {
+ // if XML does not load, just note it and continue with next file
+ System.out.println("XML file did not load: '" + f.getName() + " e=" + e);
+ continue;
+ }
+
+//System.out.println(JSONRequest.toString(xmlRequest, false));
+
+ // generate JSON from the Request
+ String jsonString = JSONRequest.toString(xmlRequest, false);
+
+
+// single-value elements
+//jsonString = "{\"Request\":{\"Category\":[{\"CategoryId\":\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\",\"Attribute\":["
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"Julius Hibbert\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":\"true\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":123,\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-string\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"true\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#boolean\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-boolean\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"56\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-integer\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"27.5\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#double\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-double\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"2002-03-22\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#date\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-date\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"2002-03-22T08:23:47-05:00\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#dateTime\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dateTime\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"P50DT5H4M3S\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#dayTimeDuration\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dayTimeDuration\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"-P5Y3M\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-yearMonthDuration\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"0bf7a9876cde\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#hexBinary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-hexBinary\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"c3VyZS4=\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#base64Binary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"j_hibbert@medico.com\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"CN=Julius Hibbert, O=Medi Corporation, C=US\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-x500Name\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"122.45.38.245/255.255.255.64:8080-8080\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-ipAddress\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"some.host.name:147-874\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dnsName\"}"
+// + "]},"
+// + "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"Attribute\":["
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":{\"Namespaces\":[{\"Namespace\":\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\"},{\"Namespace\":\"http://www.medico.com/schemas/record\",\"Prefix\":\"md\"},{\"Namespace\":\"http://www.w3.org/2001/XMLSchema-instance\",\"Prefix\":\"xsi\"}],\"XPathCategory\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"XPath\":\"//md:records/md:record\"},\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:xpathExpression\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"http://medico.com/record/patient/BartSimpson\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#anyURI\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\"}"
+// + "]},"
+// + "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\",\"Attribute\":["
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"read\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:action:action-id\"}"
+// + "]},"
+// + "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\",\"Attribute\":["
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"08:23:47-05:00\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#time\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:environment:current-time\"}"
+// + "]}],\"ReturnPolicyIdList\":false,\"CombinedDecision\":false}}";
+
+
+
+
+
+
+// array attributes WITH explicit data types
+
+
+
+
+// String for testing Arrays of Attribute values
+//jsonString = "{\"Request\":{\"Category\":[{\"CategoryId\":\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\",\"Attribute\":["
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":[\"test string\",\"Julius Hibbert\",\"Julius Hibbert as string\"],\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":[true, false],\"DataType\":\"http://www.w3.org/2001/XMLSchema#boolean\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-boolean\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":[56, 12],\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-integer\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":[27.12, 12112.344],\"DataType\":\"http://www.w3.org/2001/XMLSchema#double\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-double\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":[\"2002-03-22\",\"1256-11-11\"],\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-date\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":[\"2002-03-22T08:23:47-05:00\",\"1056-11-05T19:08:12-14:30\"],\"DataType\":\"http://www.w3.org/2001/XMLSchema#dateTime\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dateTime\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":[\"P50DT5H4M3S\",\"P12DT148H18M21S\"],\"DataType\":\"http://www.w3.org/2001/XMLSchema#dayTimeDuration\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dayTimeDuration\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"-P5Y3M\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-yearMonthDuration\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"-P28Y7M\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-yearMonthDuration\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"0bf7a9876cde\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#hexBinary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-hexBinary\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"0fb8\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#hexBinary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-hexBinary\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"c3VyZS4=\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#base64Binary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"YXN1cmUu\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#base64Binary\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"j_hibbert@medico.com\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"c_clown@nose_medico.com\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-rfc822Name\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"CN=Julius Hibbert, O=Medi Corporation, C=US\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-x500Name\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"CN=Crusty Clown, O=Red Nose Corporation, C=US\",\"DataType\":\"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-x500Name\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"122.45.38.245/255.255.255.64:8080-8080\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-ipAddress\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"35.123.111.56/255.64.32.255:9999-9999\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-ipAddress\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"some.host.name:147-874\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dnsName\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"a.different.host:-45\",\"DataType\":\"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject:subject-dnsName\"}"
+// + "]},"
+// + "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"Attribute\":["
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":{\"Namespaces\":[{\"Namespace\":\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\"},{\"Namespace\":\"http://www.medico.com/schemas/record\",\"Prefix\":\"md\"},{\"Namespace\":\"http://www.w3.org/2001/XMLSchema-instance\",\"Prefix\":\"xsi\"}],\"XPathCategory\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"XPath\":\"//md:records/md:record\"},\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:xpathExpression\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":{\"Namespaces\":[{\"Namespace\":\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\"},{\"Namespace\":\"http://www.medico.com/schemas/record\",\"Prefix\":\"md\"},{\"Namespace\":\"http://www.w3.org/2001/XMLSchema-instance\",\"Prefix\":\"xsi\"}],\"XPathCategory\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"XPath\":\"//md:records/md:diagnosis_info\"},\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:xpathExpression\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"http://medico.com/record/patient/BartSimpson\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#anyURI\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"http://medico.com/record/patient/HomerSimpson\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#anyURI\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\"}"
+// + "],"
+// + "\"Content\":\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?><md:records xmlns:md=\\\"http://www.medico.com/schemas/record\\\">\\r\\n \\t<md:record>\\r\\n \\t<md:patient_info>\\r\\n \\t<md:name>Bart Simpson</md:name>\\r\\n \\t<md:age>60</md:age>\\r\\n \\t<md:sex>male</md:sex>\\r\\n \\t<md:health_insurance>123456</md:health_insurance>\\r\\n \\t</md:patient_info>\\r\\n \\t<md:diagnosis_info>\\r\\n \\t<md:diagnosis>\\r\\n \\t<md:item type=\\\"primary\\\">Gastric Cancer</md:item>\\r\\n \\t<md:item type=\\\"secondary\\\">Hyper tension</md:item>\\r\\n \\t</md:diagnosis>\\r\\n \\t<md:pathological_diagnosis>\\r\\n \\t<md:diagnosis>\\r\\n \\t<md:item type=\\\"primary\\\">Well differentiated adeno carcinoma</md:item>\\r\\n \\t</md:diagnosis>\\r\\n \\t<md:date>2000-10-05</md:date>\\r\\n \\t<md:malignancy type=\\\"yes\\\"/>\\r\\n \\t</md:pathological_diagnosis>\\r\\n \\t</md:diagnosis_info> \\r\\n \\t</md:record>\\r\\n \\t<md:record>\\r\\n \\t<md:patient_info>\\r\\n \\t<md:name>Homer Simpson</md:name>\\r\\n \\t<md:age>80</md:age>\\r\\n \\t<md:sex>male</md:sex>\\r\\n \\t<md:health_insurance>123456</md:health_insurance>\\r\\n \\t</md:patient_info>\\r\\n \\t<md:diagnosis_info>\\r\\n \\t<md:diagnosis>\\r\\n \\t<md:item type=\\\"primary\\\">Gastric Cancer</md:item>\\r\\n \\t<md:item type=\\\"secondary\\\">Hyper tension</md:item>\\r\\n \\t</md:diagnosis>\\r\\n \\t<md:pathological_diagnosis>\\r\\n \\t<md:diagnosis>\\r\\n \\t<md:item type=\\\"primary\\\">Well differentiated adeno carcinoma</md:item>\\r\\n \\t</md:diagnosis>\\r\\n \\t<md:date>2000-10-05</md:date>\\r\\n \\t<md:malignancy type=\\\"yes\\\"/>\\r\\n \\t</md:pathological_diagnosis>\\r\\n \\t</md:diagnosis_info> \\r\\n \\t</md:record>\\r\\n\\t </md:records>\"},"
+// + "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\",\"Attribute\":["
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"read\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:action:action-id\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"write\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:action:action-id\"}"
+// + "]},"
+// + "{\"CategoryId\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\",\"Attribute\":["
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"08:23:47-05:00\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#time\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:environment:current-time\"},"
+// + "{\"Issuer\":\"ConformanceTester\",\"Value\":\"22:12:10Z\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#time\",\"IncludeInResult\":true,\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:environment:current-time\"}]}]"
+// + ",\"ReturnPolicyIdList\":false,\"CombinedDecision\":false}}";
+
+
+
+
+ // load JSON into a Request
+ jsonRequest = JSONRequest.load(jsonString);
+
+ // compare the two Request objects
+
+ // check simple things first
+ assertEquals("File '" + currentFile.getName() + "' CombinedDecision", xmlRequest.getCombinedDecision(), jsonRequest.getCombinedDecision());
+ assertEquals("File '" + currentFile.getName() + "' getReturnPolicyIdList", xmlRequest.getReturnPolicyIdList(), jsonRequest.getReturnPolicyIdList());
+ assertEquals("File '" + currentFile.getName() + "' requestDefaults", xmlRequest.getRequestDefaults(), jsonRequest.getRequestDefaults());
+
+ // multiRequests (guaranteed to not be null)
+ // We do NOT care about ordering, so compare the two collections inefficiently
+ Collection<RequestReference> xmlCollection = xmlRequest.getMultiRequests();
+ Collection<RequestReference> jsonCollection = jsonRequest.getMultiRequests();
+ String errorMessage = null;
+ if (jsonCollection.size() != xmlCollection.size()) {
+ errorMessage = "File '" + currentFile.getName() + "' MultiRequests not same size. ";
+ } else if (! jsonCollection.containsAll(xmlCollection)) {
+ errorMessage = "File '" + currentFile.getName() + "' MultiRequests have different contents. ";
+ }
+ if (errorMessage != null) {
+ String xmlContents = "";
+ String jsonContents = "";
+ Iterator<RequestReference> rrIt = xmlCollection.iterator();
+ while (rrIt.hasNext()) {
+ xmlContents += "\n " + rrIt.next().toString();
+ }
+ rrIt = jsonCollection.iterator();
+ while (rrIt.hasNext()) {
+ jsonContents += "\n " + rrIt.next().toString();
+ }
+ fail(errorMessage + "\nXML(" + xmlCollection.size() + ")='" + xmlContents +
+ "' \nJSON(" + jsonCollection.size() + ")='" + jsonContents +
+ "'" +
+ "\njson='" + jsonString + "'");
+ }
+
+ // attributes (guaranteed to not be null)
+ // We do NOT care about ordering, so compare the two collections inefficiently
+ Collection<RequestAttributes> xmlAttrCollection = xmlRequest.getRequestAttributes();
+ Collection<RequestAttributes> jsonAttrCollection = jsonRequest.getRequestAttributes();
+ errorMessage = null;
+ if (jsonAttrCollection.size() != xmlAttrCollection.size()) {
+ errorMessage = "File '" + currentFile.getName() + "' RequestAttributes not same size. ";
+ } else if (! jsonAttrCollection.containsAll(xmlAttrCollection)) {
+ String attrName = "";
+ Iterator<RequestAttributes> rait = xmlAttrCollection.iterator();
+ while (rait.hasNext()) {
+ RequestAttributes ra = rait.next();
+ if (jsonAttrCollection.contains(ra) == false) {
+ attrName = ra.toString();
+ }
+ }
+ errorMessage = "File '" + currentFile.getName() + "' RequestAttributes have different contents. JSON is missing attr=" + attrName;
+ }
+ if (errorMessage != null) {
+ String xmlContents = "";
+ String jsonContents = "";
+ Iterator<RequestAttributes> rrIt = xmlAttrCollection.iterator();
+ while (rrIt.hasNext()) {
+ RequestAttributes ras = rrIt.next();
+ xmlContents += "\n " + ras.toString();
+ if (ras.getContentRoot() != null) {
+ StringWriter writer = new StringWriter();
+ Transformer transformer = null;
+ try {
+ transformer = TransformerFactory.newInstance().newTransformer();
+ transformer.transform(new DOMSource(ras.getContentRoot()), new StreamResult(writer));
+ } catch (Exception e) {
+ throw new JSONStructureException("Unable to Content node to string; e="+e);
+ }
+
+ xmlContents += "\n Content: " + writer.toString();
+ }
+ }
+ rrIt = jsonAttrCollection.iterator();
+ while (rrIt.hasNext()) {
+ RequestAttributes ras = rrIt.next();
+ jsonContents += "\n " + ras.toString();
+ if (ras.getContentRoot() != null) {
+ StringWriter writer = new StringWriter();
+ Transformer transformer = null;
+ try {
+ transformer = TransformerFactory.newInstance().newTransformer();
+ transformer.transform(new DOMSource(ras.getContentRoot()), new StreamResult(writer));
+ } catch (Exception e) {
+ throw new JSONStructureException("Unable to Content node to string; e="+e);
+ }
+
+ jsonContents += "\n Content: " + writer.toString();
+ }
+ }
+ fail(errorMessage + "\nXML(" + xmlAttrCollection.size() + ")='" + xmlContents +
+ "' \nJSON(" + jsonAttrCollection.size() + ")='" + jsonContents +
+ "\njson='" + jsonString + "'");
+ }
+
+
+ }
+
+ } catch (Exception e) {
+ fail ("Failed test with '" + currentFile.getName() + "', e=" + e);
+ }
+
+
+ }
+
+ //
+ // HELPER to get list of all Request files in the given directory
+ //
+
+ private List<File> getRequestsInDirectory(File directory) {
+ List<File> fileList = new ArrayList<File>();
+
+ File[] fileArray = directory.listFiles();
+ for (File f : fileArray) {
+ if (f.isDirectory()) {
+ List<File> subDirList = getRequestsInDirectory(f);
+ fileList.addAll(subDirList);
+ }
+ if (f.getName().endsWith("Request.xml")) {
+ fileList.add(f);
+ }
+ }
+ return fileList;
+
+ }
+
+}
+
+
+
+
+/*
+Place to dump very long trace/exception strings that need manual editing to understand
+
+
+
+
+
+
+ */
+
+
+
+
+
+
+
+
+
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestDefaultCategoryTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestDefaultCategoryTest.java
new file mode 100755
index 0000000..f919878
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/std/json/RequestDefaultCategoryTest.java
@@ -0,0 +1,1418 @@
+/*
+ * 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.json;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.std.json.JSONRequest;
+import com.att.research.xacml.std.json.JSONStructureException;
+/**
+ * Test JSON Request convert to object - Default Category object tests
+ *
+ * TO RUN - use jUnit
+ * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
+ *
+ * NOTE:
+ * The "correct" way to verify that each JSON string gets translated into our internal Objects correctly is to look explicitly at each of the child objects
+ * and verify that they are correct. This would involve a lot of coding to get child of child of child and individually verify each property of each element.
+ * To simplify testing we assume that request.toString() correctly includes a complete text representation of every sub-component of the Request object
+ * and we compare the resulting String to our expected String.
+ * This has two possible sources of error:
+ * - toString might not include some sub-component, and
+ * - the initial verification of the resulting string is done by hand and may have been incorrect.
+ *
+ * @author glenngriffin
+ *
+ */
+public class RequestDefaultCategoryTest {
+
+ // The request object output from each test conversion from JSON string
+ Request request;
+
+
+ /*
+ * Request that uses all fields with both single and multiple entries
+ */
+ String allFieldsRequest =
+ "{\"Request\": {" +
+ "\"ReturnPolicyIdList\" : true ," +
+ "\"CombinedDecision\" : true ," +
+ "\"XPathVersion\" : \"http://www.w3.org/TR/1999/REC-xpath-19991116\"," +
+ "\"MultiRequests\" : {" +
+ "\"RequestReference\": [" +
+ "{ " +
+ "\"ReferenceId\" : [\"foo1\",\"bar1\"]" +
+ "}," +
+ "{" +
+ "\"ReferenceId\" : [\"foo2\",\"bar1\"]" +
+ "}]" +
+ "}," +
+
+ "\"Category\": [" +
+ "{ " +
+ "\"CategoryId\": \"custom-category\", " +
+ "\"Id\" : \"customId\", " +
+ "\"Attribute\" : [" +
+ "{" +
+ "\"AttributeId\" : \"document-id\", " +
+ "\"DataType\" : \"integer\", " +
+ "\"Value\" : 123 " +
+ "}, " +
+ "{" +
+ "\"AttributeId\" : \"document-url\", " +
+ "\"DataType\" : \"anyURI\", " +
+ "\"Value\" : \"http://somewhere.over.the.com/rainbow\" " +
+ "}, " +
+ "{" +
+ "\"AttributeId\" : \"page-list\", " +
+ "\"Value\" : [1, 2, 3, 4.5, 3, 2, 1] " +
+ "} " +
+ "]" +
+ "}, " +
+ "{ " +
+ "\"CategoryId\": \"another-custom-cat\", " +
+ "\"Id\" : \"anotherXmlId\", " +
+ "\"Attribute\" : []" +
+ "} " +
+ "], " +
+
+ "\"AccessSubject\":{ " +
+ "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" +
+ "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" +
+ "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+
+ "</book></catalog>\"," +
+ "\"Attribute\" : []" +
+ "}, " +
+
+ "\"Resource\" : {" +
+ "\"Content\" : \"PD94bWwgdmVyc2lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9yPkdhbWJhcmRlbGxhLCBNYXR0aGV3PC9hdXRob3I+PHRpdGxlPlhNT" +
+ "CBEZXZlbG9wZXIncyBHdWlkZTwvdGl0bGU+PGdlbnJlPkNvbXB1dGVyPC9nZW5yZT48cHJpY2U+NDQuOTU8L3ByaWNlPjxwdWJsaXNoX2RhdGU+MjAwMC0xMC0wMTwvcHVibGlzaF"+
+ "9kYXRlPjxkZXNjcmlwdGlvbj5BbiBpbi1kZXB0aCBsb29rIGF0IGNyZWF0aW5nIGFwcGxpY2F0aW9ucyB3aXRoIFhNTC48L2Rlc2NyaXB0aW9uPjwvYm9vaz48L2NhdGFsb2c+\"" +
+
+
+ "} " +
+
+
+ "}}";
+
+ /*
+ * The following example comes directly from the JSON Profile Spec
+ */
+ String exampleFromSpec = "{ " +
+ "\"Request\" : { " +
+ "\"AccessSubject\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "}, " +
+ "\"Action\" : { " +
+ "\"Attribute\": " +
+ "{ " +
+ "\"Id\" : \"action-id\", " +
+ "\"Value\" : \"http://www.xacml.eu/buy\", " +
+ "\"DataType\" : \"anyURI\" " +
+ "} " +
+ "}, " +
+ "\"Resource\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"book-title\", " +
+ "\"Value\" : \"Learn German in 90 days\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"currency\", " +
+ "\"Value\" : \"SEK\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"price\", " +
+ "\"Value\" : 123.34 " +
+ "} " +
+ "] " +
+ "} " +
+ "} " +
+ "} ";
+
+
+ /*
+ * The following example comes directly from the JSON Profile Spec (modified to include a "</Catalog>" missing from both examples).
+ * It shows the two ways of handling XPath content, as escaped XML and as Base64 encoding.
+ */
+ String xPathExampleFromSpec = "{ " +
+ "\"Request\" : { " +
+ "\"Resource\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"urn:oasis:names:tc:xacml:3.0:content-selector\", " +
+ "\"DataType\" : \"xpathExpression\", " +
+ "\"Value\" : { " +
+ "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", " +
+ "\"Namespaces\" : [{ " +
+ "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " +
+ "}, " +
+ "{ " +
+ "\"Prefix\" : \"md\", " +
+ "\"Namespace\" : \"urn:example:med:schemas:record\" " +
+ "} " +
+ "], " +
+ "\"XPath\" : \"md:record/md:patient/md:patientDoB\" " +
+ "} " +
+ "} " +
+ "] " +
+ "} " +
+ "} " +
+ "} ";
+
+
+ // test Shorthand Category notation for elements not tested in their own section below.
+ // Categories that are more commonly used are fully tested.
+ // Given that the functions within the categories are the same irrespective of the name of the category,
+ // we assume that the contents of the category will work ok once the Shorthand notation is recognized, so all we need to test is the shorthand
+ // The ones that are tested in their own sections are:
+ // AccessSubject
+ // Action
+ // Resource
+ // Environment
+ // test Subject
+ @Test
+ public void testCategoryShorthand() {
+
+ // RecipientSubject present both as element within Category and as separate RecipientSubject element at same level as Category
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ + "\"Category\": ["
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " +
+ "}] }, "
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"aValue\"" +
+ "}] } "
+ + "]," +
+ "\"RecipientSubject\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // IntermediarySubject present both as element within Category and as separate IntermediarySubject element at same level as Category
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ + "\"Category\": ["
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " +
+ "}] }, "
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"aValue\"" +
+ "}] } "
+ + "]," +
+ "\"IntermediarySubject\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // Codebase present both as element within Category and as separate Codebase element at same level as Category
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ + "\"Category\": ["
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:codebase\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " +
+ "}] }, "
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:codebase\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"aValue\"" +
+ "}] } "
+ + "]," +
+ "\"Codebase\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+
+ // RequestingMachine present both as element within Category and as separate RequestingMachine element at same level as Category
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ + "\"Category\": ["
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " +
+ "}] }, "
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"aValue\"" +
+ "}] } "
+ + "]," +
+ "\"RequestingMachine\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ // test AccessSubject
+ // Include test for backward compatibility with "Subject"
+ @Test
+ public void testAccessSubjectRequest() {
+
+ // AccessSubject absent
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // AccessSubject as normal element under Category (with CategoryId==subject category id)
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"aValue\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // multiple AccessSubjects under Category
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": ["
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " +
+ "}] }, "
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"aValue\"" +
+ "}] } "
+ + "] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // AccessSubject present both as element within Category and as separate AccessSubject element at same level as Category
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ + "\"Category\": ["
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " +
+ "}] }, "
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"aValue\"" +
+ "}] } "
+ + "]," +
+ "\"AccessSubject\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // AccessSubject present, no other Category element
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ +
+ "\"AccessSubject\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+
+ // Subject present, no other Category element (Backward Compatibility
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ +
+ "\"Subject\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // AccessSubject present, 1/multiple other Category element also present
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ + "\"Category\": ["
+ + "{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"aValue\"" +
+ "}] } "
+ + "]," +
+ "\"AccessSubject\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // 2 AccessSubjects - duplicates fail
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ +
+ "\"AccessSubject\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ +
+ "\"AccessSubject\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // AccessSubject with correct Category value
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ +
+ "\"AccessSubject\" : { " +
+ "\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\" ," +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // AccessSubject with wrong Category value
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ +
+ "\"AccessSubject\" : { " +
+ "\"CategoryId\" : \"notthesubject\" ," +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // AccessSubject with array of sub-object AccessSubjects (Multi Decision)
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ +
+ "\"AccessSubject\" : ["
+ + "{ " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "}, "
+ + "{ " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Arless\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Somewhere\" " +
+ "} " +
+ "] " +
+ "}, "
+ + "{ " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Barry\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Elsewhere\" " +
+ "} " +
+ "] " +
+ "} "
+ + "]"
+ + " }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Arless}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Somewhere}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Barry}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Elsewhere}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ }
+
+
+
+
+
+
+
+
+
+ // Action ... duplicate all AccessSubject tests...
+ // test Action
+ @Test
+ public void testActionRequest() {
+
+ // Action absent
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Action as normal element under Category (with CategoryId==subject category id)
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"aValue\" " +
+ "}] } ] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // multiple Actions under Category
+ try {
+ request = JSONRequest.load("{\"Request\" : {\"Category\": ["
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " +
+ "}] }, "
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"aValue\"" +
+ "}] } "
+ + "] }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Action present both as element within Category and as separate Action element at same level as Category
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ + "\"Category\": ["
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " +
+ "}] }, "
+ + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"aValue\"" +
+ "}] } "
+ + "]," +
+ "\"Action\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Action present, no other Category element
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ +
+ "\"Action\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Action present, 1/multiple other Category element also present
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ + "\"Category\": ["
+ + "{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" +
+ "\"Id\" : \"document-id\", " +
+ "\"Value\" : \"aValue\"" +
+ "}] } "
+ + "]," +
+ "\"Action\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // 2 Actions - duplicates fail
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ +
+ "\"Action\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ +
+ "\"Action\" : { " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Action with correct Category value
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ +
+ "\"Action\" : { " +
+ "\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:action\" ," +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString());
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Action with wrong Category value
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ +
+ "\"Action\" : { " +
+ "\"CategoryId\" : \"notthesubject\" ," +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "} "
+ + " }}");
+ fail("Operation should throw exception");
+ } catch (JSONStructureException e) {
+ // correct response
+ } catch (Exception e) {
+ fail ("Failed convert from JSON to object: " + e);
+ }
+
+ // Action with array of sub-object Actions (Multi Decision)
+ try {
+ request = JSONRequest.load("{\"Request\" : {"
+ +
+ "\"Action\" : ["
+ + "{ " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Andreas\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Gamla Stan\" " +
+ "} " +
+ "] " +
+ "}, "
+ + "{ " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Arless\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Somewhere\" " +
+ "} " +
+ "] " +
+ "}, "
+ + "{ " +
+ "\"Attribute\": [ " +
+ "{ " +
+ "\"Id\" : \"subject-id\", " +
+ "\"Value\" : \"Barry\" " +
+ "}, " +
+ "{ " +
+ "\"Id\" : \"location\", " +
+ "\"Value\" : \"Elsewhere\" " +
+ "} " +
+ "] " +
+ "} "
+ + "]"
+ + " }}");
+ assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Arless}],includeInResults=false}{attributeId=