http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTest.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTest.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTest.java
new file mode 100755
index 0000000..be0b46f
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTest.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.test.conformance;
+
+import java.io.File;
+
+/**
+ * ConformanceTest represents a collection of XACML files with a root Policy 
document, optional referenced Policy documents, a Request, and a Response.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class ConformanceTest {
+       private String testName;
+       private File request;
+       private File response;
+       private ConformanceRepository repository;
+       
+       public ConformanceTest(String name, ConformanceRepository 
conformanceRepository, File fileRequest, File fileResponse) {
+               this.testName   = name;
+               this.request    = fileRequest;
+               this.response   = fileResponse;
+               this.repository = conformanceRepository;
+       }
+       
+       public ConformanceTest(String name) {
+               this.testName   = name;
+       }
+       
+       public String getTestName() {
+               return this.testName;
+       }
+       public void setTestName(String s) {
+               this.testName   = s;
+       }
+       public ConformanceRepository getRepository() {
+               if (this.repository == null) {
+                       this.repository = new ConformanceRepository();
+               }
+               return this.repository;
+       }
+       public File getRequest() {
+               return this.request;
+       }
+       public void setRequest(File f) {
+               this.request    = f;
+       }
+       public File getResponse() {
+               return this.response;
+       }
+       public void setResponse(File f) {
+               this.response   = f;
+       }
+       
+       public boolean isComplete() {
+               return this.getTestName() != null && this.getRepository() != 
null && this.getRepository().hasRootPolicy() && this.getRequest() != null && 
this.getResponse() != null;
+       }
+       
+       @Override
+       public String toString() {
+               StringBuilder stringBuilder     = new StringBuilder();
+               boolean needColon                       = false;
+               if (this.getTestName() != null) {
+                       stringBuilder.append(this.getTestName());
+                       needColon       = true;
+               }
+               if (this.getRepository() != null) {
+                       
+               }
+               if (this.getRequest() != null) {
+                       if (needColon) {
+                               stringBuilder.append(':');
+                       }
+                       stringBuilder.append(this.getRequest().getName());
+                       needColon       = true;
+               }
+               if (this.getResponse() != null) {
+                       if (needColon) {
+                               stringBuilder.append(':');
+                       }
+                       stringBuilder.append(this.getResponse().getName());
+                       needColon       = true;
+               }
+               return stringBuilder.toString();
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestEngine.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestEngine.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestEngine.java
new file mode 100755
index 0000000..822006a
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestEngine.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) 2013 AT&T Knowledge Ventures
+ *              Unpublished and Not for Publication
+ *                     All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.test.conformance;
+
+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.Response;
+import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.api.pdp.PDPEngineFactory;
+import com.att.research.xacml.api.pdp.ScopeResolver;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMRequest;
+import com.att.research.xacml.std.dom.DOMResponse;
+import com.att.research.xacml.util.FactoryException;
+
+/**
+ * ConformanceTestEngine handles the creation of the PDPEngine for a 
ConformanceTest instance.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class ConformanceTestEngine {
+       private Log logger      = 
LogFactory.getLog(ConformanceTestEngine.class);
+       
+       private PDPEngineFactory pdpEngineFactory;
+       private ScopeResolver scopeResolver;
+       private boolean lenientRequests;
+       private boolean lenientPolicies;
+       private int iterations                  = 1;
+       
+       // total of all first calls to decide()
+       private long firstDecideTime;
+       private int numberOfFirstDecides = 0;
+       
+       // total of all non-first-calls to decide()
+       private long decideTimeMultiple;
+       
+       // total of average time each test case uses for a Request
+       // (sum of : for each test case, average of all non-first-call calls to 
decide() )
+       private long avgDecideTimeMultiple = 0;
+       
+       protected PDPEngineFactory getPDPEngineFactory() throws 
FactoryException {
+               if (this.pdpEngineFactory == null) {
+                       this.pdpEngineFactory   = 
PDPEngineFactory.newInstance();
+                       
this.pdpEngineFactory.setScopeResolver(this.scopeResolver);
+               }
+               return this.pdpEngineFactory;
+       }
+       
+       public ConformanceTestEngine(ScopeResolver scopeResolverIn, boolean 
lenientRequestsIn, boolean lenientPoliciesIn, int iterationsIn) {
+               this.scopeResolver              = scopeResolverIn;
+               this.lenientRequests    = lenientRequestsIn;
+               this.lenientPolicies    = lenientPoliciesIn;
+               this.iterations                 = iterationsIn;
+       }
+       
+       public ConformanceTestResult run(ConformanceTest conformanceTest) {
+               if (conformanceTest.getRequest() == null || 
conformanceTest.getResponse() == null || conformanceTest.getRepository() == 
null) {
+                       logger.error("Incomplete Conformance Test: " + 
conformanceTest.getTestName());
+               }
+               PDPEngineFactory thisPDPEngineFactory   = null;
+               try {
+                       thisPDPEngineFactory    = this.getPDPEngineFactory();
+               } catch (FactoryException ex) {
+                       return new ConformanceTestResult(conformanceTest, ex);
+               }
+               
+               ConformanceTestResult conformanceTestResult     = new 
ConformanceTestResult(conformanceTest, iterations);
+               
+               /*
+                * Load the request
+                */
+               Request request                 = null;
+               boolean isLenient               = DOMProperties.isLenient();
+               try {
+                       DOMProperties.setLenient(this.lenientRequests);
+                       try {
+                               request         = 
DOMRequest.load(conformanceTest.getRequest());
+                               conformanceTestResult.setRequest(request);
+                       } catch (Exception ex) {
+                               logger.error("Exception loading Request file " 
+ conformanceTest.getRequest().getAbsolutePath(), ex);
+                               conformanceTestResult.setError(ex);
+                               return conformanceTestResult;
+                               
+                       }
+                       
+                       /*
+                        * Load the expected response
+                        */
+                       Response response               = null;
+                       try {
+                               response        = 
DOMResponse.load(conformanceTest.getResponse());
+                               
conformanceTestResult.setExpectedResponse(response);
+                       } catch (Exception ex) {
+                               logger.error("Exception loading Response file " 
+ conformanceTest.getResponse().getAbsolutePath(), ex);
+                               conformanceTestResult.setError(ex);
+                               return conformanceTestResult;
+                       }
+                       
+                       /*
+                        * Set up the configuration for the policy finder
+                        */
+                       conformanceTest.getRepository().setXACMLProperties();
+                       DOMProperties.setLenient(this.lenientPolicies);
+                       
+                       /*
+                        * Create the engine
+                        */
+                       PDPEngine pdpEngine             = null;
+                       try {
+                               // pdpEngine    = 
thisPDPEngineFactory.newEngine(conformanceTest.getRootPolicy(), 
conformanceTest.getReferencedPolicies(), pipFinderEngine);
+                               pdpEngine               = 
thisPDPEngineFactory.newEngine();
+                       } catch (Exception ex) {
+                               logger.error("Exception getting PDP engine 
instance", ex);
+                               conformanceTestResult.setError(ex);
+                               return conformanceTestResult;
+                       }
+                       if (pdpEngine == null) {
+                               logger.error("Null PDP engine");
+                               conformanceTestResult.setError(new 
NullPointerException("Null engine"));
+                               return conformanceTestResult;
+                       }
+                       
+                       /*
+                        * Run the request
+                        */
+                       long startTime, endTime;
+                       long curDecideTime      = this.firstDecideTime;
+                       try {
+                               startTime       = System.nanoTime();
+                               response        = pdpEngine.decide(request);
+                               endTime = System.nanoTime();
+//System.out.println(endTime  - startTime);
+                               // add to total
+                               this.firstDecideTime    += endTime - startTime;
+                               this.numberOfFirstDecides++;
+                               // remember just this test
+                               conformanceTestResult.setFirstCallTime(endTime 
- startTime);
+                               
conformanceTestResult.setActualResponse(response);
+                       } catch (Exception ex) {
+                               logger.error("Exception in decide", ex);
+                               conformanceTestResult.setError(ex);
+                               return conformanceTestResult;
+                       }
+                       if (response == null) {
+                               logger.error("Null Response");
+                               conformanceTestResult.setError(new 
NullPointerException("Null Response"));
+                               return conformanceTestResult;                   
+                       }
+                       
+                       long localLoopTime = 0;
+                       try {
+                               // if user requested non-first-call calls to 
decide() to get performance info, run them now.
+                               // We can ignore the result since we are only 
interested in how long they take to process the Request.
+                               for (int i = 0 ; i < this.iterations ; i++) {
+                                       startTime       = System.nanoTime();
+                                       pdpEngine.decide(request);
+                                       endTime = System.nanoTime();
+//System.out.println(endTime - startTime);                                     
+                                       // add to the global total for all tests
+                                       this.decideTimeMultiple += (endTime - 
startTime);
+                                       // remember just this one test's info
+                                       localLoopTime += (endTime - startTime);
+                               }
+                       } catch (Exception ex) {
+                               logger.error("Exception in iterated decide", 
ex);
+                               return conformanceTestResult;
+                       }
+
+                       // add to total average for non-first-call times for 
all test cases
+                       avgDecideTimeMultiple += (localLoopTime / iterations);
+//System.out.println("localLoop="+localLoopTime + "   it="+iterations + "   
avg=" + (localLoopTime / iterations) );
+                       // remember average time for just this test
+                       
conformanceTestResult.setAverageTotalLoopTime(localLoopTime/iterations);
+                       
+                       long elapsedDecideTime  = this.firstDecideTime - 
curDecideTime;
+                       logger.info("Decide Time: " + elapsedDecideTime + "ns");
+                       
+                       return conformanceTestResult;
+               } finally {
+                       DOMProperties.setLenient(isLenient);
+               }
+       }
+
+       public long getFirstDecideTime() {
+               return this.firstDecideTime;
+       }
+       
+       public long getDecideTimeMultiple() {
+               return this.decideTimeMultiple;
+       }
+       
+       
+       public long getAvgFirstDecideTime() {
+               return this.firstDecideTime / numberOfFirstDecides;
+       }
+       public long getAvgDecideTimeMultiple() {
+               return this.avgDecideTimeMultiple / numberOfFirstDecides;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestResult.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestResult.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestResult.java
new file mode 100755
index 0000000..9c895c6
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestResult.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.test.conformance;
+
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.Response;
+
+/**
+ * ConformanceTestResult holds all of the objects for a single conformance 
test run.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class ConformanceTestResult {
+       private ConformanceTest         conformanceTest;
+       private Request                         request;
+       private Response                        expectedResponse;
+       private Response                        actualResponse;
+       private ResponseMatchResult     responseMatchResult;
+       private Exception                       error;
+       
+       // performance timings
+       private long                    firstCallTime;
+       private long                    averageTotalLoopTime;
+       
+       // how many non-first-call times the decide() was called
+       private int iterations;
+       
+       public ConformanceTestResult(ConformanceTest conformanceTestIn, int 
iterations) {
+               this.conformanceTest    = conformanceTestIn;
+               this.iterations = iterations;
+       }
+       
+       public ConformanceTestResult(ConformanceTest conformanceTestIn, 
Exception errorIn) {
+               this.conformanceTest    = conformanceTestIn;
+               this.error                              = errorIn;
+       }
+       
+       public int getIterations() {
+               return this.iterations;
+       }
+
+       public ConformanceTest getConformanceTest() {
+               return this.conformanceTest;
+       }
+       public void setConformanceTest(ConformanceTest conformanceTestIn) {
+               this.conformanceTest    = conformanceTestIn;
+       }
+       
+       public Request getRequest() {
+               return this.request;
+       }
+       public void setRequest(Request requestIn) {
+               this.request    = requestIn;
+       }
+       
+       public Response getExpectedResponse() {
+               return this.expectedResponse;
+       }
+       public void setExpectedResponse(Response response) {
+               this.expectedResponse           = response;
+               this.responseMatchResult        = null;
+       }
+       
+       public Response getActualResponse() {
+               return this.actualResponse;
+       }
+       public void setActualResponse(Response response) {
+               this.actualResponse             = response;
+               this.responseMatchResult        = null;
+       }
+       
+       public ResponseMatchResult getResponseMatchResult() {
+               if (this.responseMatchResult == null && (this.actualResponse != 
null && this.expectedResponse != null)) {
+                       this.computeResponseMatchResult();
+               }
+               return this.responseMatchResult;
+       }
+       public void computeResponseMatchResult() {
+               if (this.expectedResponse != null && this.actualResponse != 
null) {
+                       this.responseMatchResult        = 
ResponseMatchResult.newInstance(this.expectedResponse, this.actualResponse);
+               }
+       }
+       public Exception getError() {
+               return this.error;
+       }
+       public void setError(Exception ex) {
+               this.error      = ex;
+       }
+       
+       public long getFirstCallTime() {
+               return firstCallTime;
+       }
+       public void setFirstCallTime(long t) {
+               firstCallTime = t;
+       }
+       public long getAverageTotalLoopTime(){
+               return averageTotalLoopTime;
+       }
+       public void setAverageTotalLoopTime(long t) {
+               averageTotalLoopTime = t;
+       }
+       
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestSet.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestSet.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestSet.java
new file mode 100755
index 0000000..a04b50c
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestSet.java
@@ -0,0 +1,171 @@
+/*
+ *                        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.test.conformance;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * ConformanceTestSet represents a collection of <code>ConformanceTest</code>s 
ordered by the test name.  It has methods for
+ * scanning a directory to generate an ordered set.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class ConformanceTestSet {
+       private static final Log logger                                         
= LogFactory.getLog(ConformanceTestSet.class);
+       private List<ConformanceTest> listConformanceTests      = new 
ArrayList<ConformanceTest>();
+       
+       protected List<ConformanceTest> getListConformanceTests() {
+               return this.listConformanceTests;
+       }
+       
+       protected ConformanceTestSet() {
+               
+       }
+       
+       private static String getTestName(String fileName, int itemPos) {
+               return (itemPos == 0 ? "NULL" : fileName.substring(0, itemPos));
+       }
+       
+       private static String getTestName(File file) {
+               String fileName = file.getName();
+               int itemPos             = fileName.indexOf("Policy");
+               if (itemPos >= 0) {
+                       return getTestName(fileName, itemPos);
+               } else if ((itemPos = fileName.indexOf("Request")) >= 0) {
+                       return getTestName(fileName, itemPos);
+               } else if ((itemPos = fileName.indexOf("Response")) >= 0) {
+                       return getTestName(fileName, itemPos);
+               } else if ((itemPos = fileName.indexOf("Repository")) >= 0) {
+                       return getTestName(fileName, itemPos);
+               } else {
+                       return null;
+               }
+       }
+       
+       public static ConformanceTestSet loadDirectory(File fileDir) throws 
IOException {
+               final Map<String,ConformanceTest> mapConformanceTests   = new 
HashMap<String,ConformanceTest>();
+               
+               Files.walkFileTree(fileDir.toPath(), new FileVisitor<Path>() {
+                       @Override
+                       public FileVisitResult preVisitDirectory(Path dir, 
BasicFileAttributes attrs) throws IOException {
+                               logger.info("Scanning directory " + 
dir.getFileName());
+                               return FileVisitResult.CONTINUE;
+                       }
+
+                       @Override
+                       public FileVisitResult visitFile(Path file, 
BasicFileAttributes attrs) throws IOException {
+                               File fileVisited        = file.toFile();
+                               String fileName         = fileVisited.getName();
+                               if (fileName.endsWith(".xml") || 
fileName.endsWith(".properties")) {
+                                       String testName = 
getTestName(fileVisited);
+                                       if (testName != null) {
+                                               ConformanceTest conformanceTest 
= mapConformanceTests.get(testName);
+                                               if (conformanceTest == null) {
+                                                       logger.info("Added test 
" + testName);
+                                                       conformanceTest = new 
ConformanceTest(testName);
+                                                       
mapConformanceTests.put(testName, conformanceTest);
+                                               }
+                                               if 
(fileName.endsWith("Policy.xml")) {
+                                                       
conformanceTest.getRepository().addRootPolicy(fileVisited);
+                                               } else if 
(fileName.endsWith("Repository.properties")) {
+                                                       
conformanceTest.getRepository().load(fileVisited);
+                                               } else if 
(fileName.endsWith("Request.xml")) {
+                                                       
conformanceTest.setRequest(fileVisited);
+                                               } else if 
(fileName.endsWith("Response.xml")) {
+                                                       
conformanceTest.setResponse(fileVisited);
+                                               }
+                                       }
+                               }
+                               return FileVisitResult.CONTINUE;
+                       }
+
+                       @Override
+                       public FileVisitResult visitFileFailed(Path file, 
IOException exc)      throws IOException {
+                               logger.warn("Skipped " + file.getFileName());
+                               return FileVisitResult.CONTINUE;
+                       }
+
+                       @Override
+                       public FileVisitResult postVisitDirectory(Path dir, 
IOException exc) throws IOException {
+                               return FileVisitResult.CONTINUE;
+                       }
+               });
+               
+               /*
+                * Sort the keyset and pull out the tests that have the 
required components
+                */
+               List<String> listTestNames      = new ArrayList<String>();
+               listTestNames.addAll(mapConformanceTests.keySet());
+               Collections.sort(listTestNames);
+               
+               ConformanceTestSet conformanceTestSet   = new 
ConformanceTestSet();
+               Iterator<String> iterTestNames  = listTestNames.iterator();
+               while (iterTestNames.hasNext()) {
+                       ConformanceTest conformanceTest = 
mapConformanceTests.get(iterTestNames.next());
+                       if (conformanceTest.isComplete()) {
+                               
conformanceTestSet.addConformanceTest(conformanceTest);
+                               logger.debug("Added conformance test " + 
conformanceTest.getTestName());
+                       } else {
+                               logger.warn("Incomplete conformance test " + 
conformanceTest.getTestName());
+                       }
+               }
+               
+               return conformanceTestSet;
+               
+       }
+
+       public Iterator<ConformanceTest> getConformanceTests() {
+               return this.listConformanceTests.iterator();
+       }
+       
+       public void addConformanceTest(ConformanceTest conformanceTest) {
+               this.listConformanceTests.add(conformanceTest);
+       }
+       
+       public void addConformanceTestSet(ConformanceTestSet 
conformanceTestSet) {
+               
this.listConformanceTests.addAll(conformanceTestSet.getListConformanceTests());
+       }
+       
+       public static void main(String[] args) {
+               for (String dir : args) {
+                       try {
+                               ConformanceTestSet conformanceTestSet           
        = ConformanceTestSet.loadDirectory(new File(dir));
+                               Iterator<ConformanceTest> iterConformanceTests  
= conformanceTestSet.getConformanceTests();
+                               if (iterConformanceTests == null) {
+                                       System.out.println("No tests found in " 
+ dir);
+                               } else {
+                                       System.out.println("Tests found in " + 
dir);
+                                       while (iterConformanceTests.hasNext()) {
+                                               
System.out.println(iterConformanceTests.next().toString());
+                                       }
+                               }
+                       } catch (Exception ex) {
+                               ex.printStackTrace(System.err);
+                       }
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResponseMatchResult.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResponseMatchResult.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResponseMatchResult.java
new file mode 100755
index 0000000..00db0dc
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResponseMatchResult.java
@@ -0,0 +1,128 @@
+/*
+ *                        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.test.conformance;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Response;
+import com.att.research.xacml.api.Result;
+
+/**
+ * ResponseMatchResult provides information about how a {@link 
com.att.research.xacml.api.Response} object matches
+ * another <code>Response</code> object.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class ResponseMatchResult {
+       private List<ResultMatchResult> resultMatchResults      = new 
ArrayList<ResultMatchResult>();
+       
+       private boolean bAssociatedAdviceMatches                        = true;
+       private boolean bAttributesMatch                                        
= true;
+       private boolean bDecisionsMatch                                         
= true;
+       private boolean bStatusCodesMatch                                       
= true;
+       private boolean bObligationsMatch                                       
= true;
+       private boolean bPolicyIdentifiersMatch                         = true;
+       private boolean bPolicySetIdentifiersMatch                      = true;
+       private boolean bNumResultsMatch                                        
= true;
+       private boolean bUnknownFunction;
+       
+       protected void addResultMatchResult(ResultMatchResult 
resultMatchResult) {
+               this.resultMatchResults.add(resultMatchResult);
+               this.bAssociatedAdviceMatches   = 
resultMatchResult.associatedAdviceMatches() && this.bAssociatedAdviceMatches;
+               this.bAttributesMatch                   = 
resultMatchResult.attributesMatch() && this.bAttributesMatch;
+               this.bDecisionsMatch                    = 
resultMatchResult.decisionsMatch() && this.bDecisionsMatch;
+               this.bStatusCodesMatch                  = 
resultMatchResult.statusCodesMatch() && this.bStatusCodesMatch;
+               this.bObligationsMatch                  = 
resultMatchResult.obligationsMatch() && this.bObligationsMatch;
+               this.bPolicyIdentifiersMatch    = 
resultMatchResult.policyIdentifiersMatch() && this.bPolicyIdentifiersMatch;
+               this.bPolicySetIdentifiersMatch = 
resultMatchResult.policySetIdentifiersMatch() && 
this.bPolicySetIdentifiersMatch;
+               this.bUnknownFunction                   = 
resultMatchResult.unknownFunction() || this.bUnknownFunction;
+       }
+       
+       protected void setNumResultsMatch(boolean b) {
+               this.bNumResultsMatch   = b;
+       }
+       
+       public ResponseMatchResult() {
+       }
+       
+       public static ResponseMatchResult newInstance(Response response1, 
Response response2) {
+               ResponseMatchResult responseMatchResult = new 
ResponseMatchResult();
+
+               Collection<Result> listResultsResponse1 = 
response1.getResults();
+               Collection<Result> listResultsResponse2 = 
response2.getResults();
+               if (listResultsResponse1.size() == 1 && 
listResultsResponse2.size() == 1) {
+                       /*
+                        * Just add a single ResultMatchResult comparing the 
results in the two responses
+                        */
+                       
responseMatchResult.addResultMatchResult(ResultMatchResult.newInstance(listResultsResponse1.iterator().next(),
 listResultsResponse2.iterator().next()));
+               } else {
+                       /*
+                        * Iterate over all of the results in the two responses 
and match them
+                        */
+                       Iterator<Result> iterResponse1Results   = 
listResultsResponse1.iterator();
+                       Iterator<Result> iterResponse2Results   = 
listResultsResponse2.iterator();
+                       while ((iterResponse1Results != null && 
iterResponse1Results.hasNext()) || (iterResponse2Results != null && 
iterResponse2Results.hasNext())) {
+                               Result result1  = (iterResponse1Results != null 
&& iterResponse1Results.hasNext() ? iterResponse1Results.next() : null);
+                               Result result2  = (iterResponse2Results != null 
&& iterResponse2Results.hasNext() ? iterResponse2Results.next() : null);
+                               if ((result1 == null || result2 == null) && 
responseMatchResult.numResultsMatch()) {
+                                       
responseMatchResult.setNumResultsMatch(false);
+                               }
+                               
responseMatchResult.addResultMatchResult(ResultMatchResult.newInstance(result1, 
result2));
+                       }
+               }
+               return responseMatchResult;
+       }
+
+       public Iterator<ResultMatchResult> getResultMatchResults() {
+               return this.resultMatchResults.iterator();
+       }
+       
+       public boolean numResultsMatch() {
+               return this.bNumResultsMatch;
+       }
+       
+       public boolean associatedAdviceMatches() {
+               return this.bAssociatedAdviceMatches;
+       }
+       
+       public boolean attributesMatch() {
+               return this.bAttributesMatch;
+       }
+       
+       public boolean decisionsMatch() {
+               return this.bDecisionsMatch;
+       }
+       
+       public boolean obligationsMatch() {
+               return this.bObligationsMatch;
+       }
+       
+       public boolean policyIdentifiersMatch() {
+               return this.bPolicyIdentifiersMatch;
+       }
+       
+       public boolean policySetIdentifiersMatch() {
+               return this.bPolicySetIdentifiersMatch;
+       }
+       
+       public boolean statusCodesMatch() {
+               return this.bStatusCodesMatch;
+       }
+       
+       public boolean unknownFunction() {
+               return this.bUnknownFunction;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResultMatchResult.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResultMatchResult.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResultMatchResult.java
new file mode 100755
index 0000000..645a755
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResultMatchResult.java
@@ -0,0 +1,127 @@
+/*
+ *                        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.test.conformance;
+
+import com.att.research.xacml.api.Result;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.util.ListUtil;
+
+/**
+ * ResultMatchResult provides information about how well a {@link 
com.att.research.xacml.api.Result} object matches
+ * another <code>Result</code> object.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class ResultMatchResult {
+       private boolean bAssociatedAdviceMatches        = true;
+       private boolean bAttributesMatch                        = true;
+       private boolean bDecisionsMatch                         = true;
+       private boolean bObligationsMatch                       = true;
+       private boolean bPolicyIdentifiersMatch         = true;
+       private boolean bPolicySetIdentifiersMatch      = true;
+       private boolean bStatusCodesMatch                       = true;
+       private boolean bUnknownFunction                        = false;
+       
+       protected void setAssociatedAdviceMatches(boolean b) {
+               this.bAssociatedAdviceMatches   = b;
+       }
+       protected void setAttributesMatch(boolean b) {
+               this.bAttributesMatch   = b;
+       }
+       protected void setDecisionsMatch(boolean b) {
+               this.bDecisionsMatch    = b;
+       }
+       protected void setObligationsMatch(boolean b) {
+               this.bObligationsMatch  = b;
+       }
+       protected void setPolicyIdentifiersMatch(boolean b) {
+               this.bPolicyIdentifiersMatch    = b;
+       }
+       protected void setPolicySetIdentifiersMatch(boolean b) {
+               this.bPolicySetIdentifiersMatch = b;
+       }
+       protected void setStatusCodesMatch(boolean b) {
+               this.bStatusCodesMatch  = b;
+       }
+       protected void setUnknownFunction(boolean b) {
+               this.bUnknownFunction   = b;
+       }
+       
+       public ResultMatchResult() {
+       }
+       
+       public static ResultMatchResult newInstance(Result result1, Result 
result2) {
+               ResultMatchResult resultMatchResult     = new 
ResultMatchResult();
+               if (result2 != null && result2.getStatus() != null && 
+                       
result2.getStatus().getStatusCode().equals(StdStatusCode.STATUS_CODE_PROCESSING_ERROR)
 && 
+                       result2.getStatus().getStatusMessage() != null &&
+                       
result2.getStatus().getStatusMessage().contains("Unknown Function")
+                       ) {
+                       resultMatchResult.setUnknownFunction(true);
+               }
+               if (result1 == null || result2 == null) {
+                       resultMatchResult.setAssociatedAdviceMatches(false);
+                       resultMatchResult.setAttributesMatch(false);
+                       resultMatchResult.setDecisionsMatch(false);
+                       resultMatchResult.setObligationsMatch(false);
+                       resultMatchResult.setPolicyIdentifiersMatch(false);
+                       resultMatchResult.setPolicySetIdentifiersMatch(false);
+                       resultMatchResult.setStatusCodesMatch(false);
+               } else {
+                       
resultMatchResult.setAssociatedAdviceMatches(ListUtil.equalsAllowNulls(result1.getAssociatedAdvice(),
 result2.getAssociatedAdvice()));
+                       
resultMatchResult.setAttributesMatch(ListUtil.equalsAllowNulls(result1.getAttributes(),
 result2.getAttributes()));
+                       
resultMatchResult.setDecisionsMatch(result1.getDecision() == 
result2.getDecision());
+                       
resultMatchResult.setObligationsMatch(ListUtil.equalsAllowNulls(result1.getObligations(),
 result2.getObligations()));
+                       
resultMatchResult.setPolicyIdentifiersMatch(ListUtil.equalsAllowNulls(result1.getPolicyIdentifiers(),
 result2.getPolicyIdentifiers()));
+                       
resultMatchResult.setPolicySetIdentifiersMatch(ListUtil.equalsAllowNulls(result1.getPolicySetIdentifiers(),
 result2.getPolicySetIdentifiers()));
+                       if (result1.getStatus() == null || 
result1.getStatus().getStatusCode() == null || result2.getStatus() == null || 
result2.getStatus().getStatusCode() == null) {
+                               resultMatchResult.setStatusCodesMatch(false);
+                       } else {
+                               
resultMatchResult.setStatusCodesMatch(result1.getStatus().getStatusCode().equals(result2.getStatus().getStatusCode()));
+                       }
+               }
+               return resultMatchResult;
+       }
+       
+       public boolean associatedAdviceMatches() {
+               return this.bAssociatedAdviceMatches;
+       }
+       
+       public boolean attributesMatch() {
+               return this.bAttributesMatch;
+       }
+       
+       public boolean decisionsMatch() {
+               return this.bDecisionsMatch;
+       }
+       
+       public boolean obligationsMatch() {
+               return this.bObligationsMatch;
+       }
+       
+       public boolean policyIdentifiersMatch() {
+               return this.bPolicyIdentifiersMatch;
+       }
+       
+       public boolean policySetIdentifiersMatch() {
+               return this.bPolicySetIdentifiersMatch;
+       }
+       
+       public boolean statusCodesMatch() {
+               return this.bStatusCodesMatch;
+       }
+       
+       public boolean unknownFunction() {
+               return this.bUnknownFunction;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomDataTypeFactory.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomDataTypeFactory.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomDataTypeFactory.java
new file mode 100755
index 0000000..b3e6cc4
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomDataTypeFactory.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) 2014 AT&T Knowledge Ventures
+ *              Unpublished and Not for Publication
+ *                     All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.test.custom;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.DataTypeFactory;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.datatypes.DataTypes;
+
+public class CustomDataTypeFactory extends DataTypeFactory {
+       private static final Map<Identifier,DataType<?>> 
mapIdentifiersToDataTypes      = new HashMap<Identifier,DataType<?>>();
+       private static boolean mapNeedsInit                                     
                                                        = true;
+       
+       public static final DataTypePrivateKey                          
DT_PRIVATEKEY                           = DataTypePrivateKey.newInstance();
+       public static final DataTypePublicKey                           
DT_PUBLICKEY                            = DataTypePublicKey.newInstance();
+       
+       private static void registerDataType(DataType<?> dataType) {
+               if (dataType != null && dataType.getId() != null) {
+                       mapIdentifiersToDataTypes.put(dataType.getId(), 
dataType);
+               }
+       }
+       
+       private static void initMap() {
+               if (mapNeedsInit) {
+                       synchronized(mapIdentifiersToDataTypes) {
+                               if (mapNeedsInit) {
+                                       registerDataType(DataTypes.DT_ANYURI);
+                                       
registerDataType(DataTypes.DT_BASE64BINARY);
+                                       registerDataType(DataTypes.DT_BOOLEAN);
+                                       registerDataType(DataTypes.DT_DATE);
+                                       registerDataType(DataTypes.DT_DATETIME);
+                                       
registerDataType(DataTypes.DT_DAYTIMEDURATION);
+                                       registerDataType(DataTypes.DT_DNSNAME);
+                                       registerDataType(DataTypes.DT_DOUBLE);
+                                       
registerDataType(DataTypes.DT_HEXBINARY);
+                                       registerDataType(DataTypes.DT_INTEGER);
+                                       
registerDataType(DataTypes.DT_IPADDRESS);
+                                       
registerDataType(DataTypes.DT_RFC822NAME);
+                                       registerDataType(DataTypes.DT_STRING);
+                                       registerDataType(DataTypes.DT_TIME);
+                                       registerDataType(DataTypes.DT_X500NAME);
+                                       
registerDataType(DataTypes.DT_XPATHEXPRESSION);
+                                       
registerDataType(DataTypes.DT_YEARMONTHDURATION);
+                                       //
+                                       // These are the custom data types!
+                                       //
+                                       registerDataType(DT_PRIVATEKEY);
+                                       registerDataType(DT_PUBLICKEY);
+                                       //
+                                       // Done
+                                       //
+                                       mapNeedsInit    = false;
+                               }
+                       }
+               }
+       }
+
+       public CustomDataTypeFactory() {
+               initMap();
+       }
+
+       @Override
+       public DataType<?> getDataType(Identifier dataTypeId) {
+               return mapIdentifiersToDataTypes.get(dataTypeId);
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunctionDefinitionFactory.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunctionDefinitionFactory.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunctionDefinitionFactory.java
new file mode 100755
index 0000000..dd4decb
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunctionDefinitionFactory.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) 2014 AT&T Knowledge Ventures
+ *              Unpublished and Not for Publication
+ *                     All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.test.custom;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinitionFactory;
+import com.att.research.xacmlatt.pdp.std.StdFunctions;
+import 
com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagOneAndOnly;
+
+public class CustomFunctionDefinitionFactory extends FunctionDefinitionFactory 
{
+       private static Map<Identifier,FunctionDefinition>       
mapFunctionDefinitions  = new HashMap<Identifier,FunctionDefinition>();
+       private static boolean                                                  
        needMapInit                             = true;
+       
+       public static final Identifier ID_FUNCTION_PRIVATEKEY_ONE_AND_ONLY = 
new 
IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:privatekey-one-and-only");
+       public static final Identifier ID_FUNCTION_PUBLICKEY_ONE_AND_ONLY = new 
IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:publickey-one-and-only");
+       
+       public static final FunctionDefinition  FD_PRIVATEKEY_ONE_AND_ONLY      
= new 
FunctionDefinitionBagOneAndOnly<PrivateKey>(ID_FUNCTION_PRIVATEKEY_ONE_AND_ONLY,
 DataTypePrivateKey.newInstance());
+       public static final FunctionDefinition  FD_PUBLICKEY_ONE_AND_ONLY       
= new 
FunctionDefinitionBagOneAndOnly<PublicKey>(ID_FUNCTION_PUBLICKEY_ONE_AND_ONLY, 
DataTypePublicKey.newInstance());
+
+       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) {
+                                                               
+                                                       }
+                                               }
+                                       }
+                                       //
+                                       // Our custom function
+                                       //
+                                       
register(FunctionDefinitionDecrypt.newInstance());
+                                       register(FD_PRIVATEKEY_ONE_AND_ONLY);
+                                       register(FD_PUBLICKEY_ONE_AND_ONLY);
+                               }
+                       }
+               }
+       }
+       
+       public CustomFunctionDefinitionFactory() {
+               initMap();
+       }
+
+       @Override
+       public FunctionDefinition getFunctionDefinition(Identifier functionId) {
+               return mapFunctionDefinitions.get(functionId);
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePrivateKey.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePrivateKey.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePrivateKey.java
new file mode 100755
index 0000000..4e12aef
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePrivateKey.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) 2014 AT&T Knowledge Ventures
+ *              Unpublished and Not for Publication
+ *                     All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.test.custom;
+
+import java.security.PrivateKey;
+
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.datatypes.DataTypeBase;
+
+public class DataTypePrivateKey extends DataTypeBase<PrivateKey> {
+       public static final Identifier DT_PRIVATEKEY = new 
IdentifierImpl("urn:com:att:research:xacml:custom:3.0:rsa:private");
+       private static final DataTypePrivateKey singleInstance = new 
DataTypePrivateKey();
+       
+       private DataTypePrivateKey() {
+               super(DT_PRIVATEKEY, PrivateKey.class);
+       }
+
+       public static DataTypePrivateKey newInstance() {
+               return singleInstance;
+       }
+       
+       @Override
+       public PrivateKey convert(Object source) throws DataTypeException {
+               if (source == null || (source instanceof PrivateKey) ) {
+                       return (PrivateKey) source;
+               } else if (source instanceof byte[]) {
+                       return (PrivateKey) source;
+               } else if (source instanceof String) {
+                       return (PrivateKey) (Object) ((String) 
source).getBytes();
+               }
+               throw new DataTypeException(this, "Failed to convert \"" + 
source.getClass().getCanonicalName());                               
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePublicKey.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePublicKey.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePublicKey.java
new file mode 100755
index 0000000..d40ee82
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePublicKey.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) 2014 AT&T Knowledge Ventures
+ *              Unpublished and Not for Publication
+ *                     All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.test.custom;
+
+import java.security.PublicKey;
+
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.datatypes.DataTypeBase;
+
+public class DataTypePublicKey extends DataTypeBase<PublicKey> {
+       public static final Identifier DT_PUBLICKEY = new 
IdentifierImpl("urn:com:att:research:xacml:custom:3.0:rsa:public");
+       private static final DataTypePublicKey singleInstance = new 
DataTypePublicKey();
+       
+       public DataTypePublicKey() {
+               super(DT_PUBLICKEY, PublicKey.class);
+       }
+       
+       public static DataTypePublicKey newInstance() {
+               return singleInstance;
+       }
+
+       @Override
+       public PublicKey convert(Object source) throws DataTypeException {
+               if (source == null || (source instanceof PublicKey) ) {
+                       return (PublicKey) source;
+               } else if (source instanceof byte[]) {
+                       return (PublicKey) source;
+               } else if (source instanceof String) {
+                       return (PublicKey) (Object) ((String) 
source).getBytes();
+               }
+               throw new DataTypeException(this, "Failed to convert \"" + 
source.getClass().getCanonicalName());                               
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDefinitionDecrypt.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDefinitionDecrypt.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDefinitionDecrypt.java
new file mode 100755
index 0000000..d51c73d
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDefinitionDecrypt.java
@@ -0,0 +1,152 @@
+/*
+ *                        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.xacmlatt.pdp.test.custom;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.List;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+
+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.XACML3;
+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.DataTypeHexBinary;
+import com.att.research.xacml.std.datatypes.DataTypeString;
+import com.att.research.xacml.std.datatypes.HexBinary;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
+import com.att.research.xacmlatt.pdp.std.functions.ConvertedArgument;
+
+public class FunctionDefinitionDecrypt implements FunctionDefinition {
+       public static final Identifier FD_RSA_DECRYPT = new 
IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:decrypt");
+       private static final FunctionDefinitionDecrypt singleInstance = new 
FunctionDefinitionDecrypt();
+       
+       public static FunctionDefinitionDecrypt newInstance() {
+               return singleInstance;
+       }
+
+       @Override
+       public Identifier getId() {
+               return FD_RSA_DECRYPT;
+       }
+
+       @Override
+       public Identifier getDataTypeId() {
+               return XACML3.ID_DATATYPE_STRING;
+       }
+
+       @Override
+       public boolean returnsBag() {
+               return 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, "Decrypt failed, 
expecting 2 arguments."));
+               }
+               //
+               // What is the first argument?
+               //
+               FunctionArgument arg0 = arguments.get(0);
+               if (arg0.isBag()) {
+                       //
+                       // We don't support bags right now
+                       //
+                       return ExpressionResult.newError(new 
StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, not 
expecting a bag for argument 0."));
+               }
+               if 
(arg0.getValue().getDataTypeId().equals(XACML3.ID_DATATYPE_HEXBINARY) == false) 
{
+                       //
+                       // Should be a String
+                       //
+                       return ExpressionResult.newError(new 
StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, expected 
a Hex Binary for argument 0."));
+               }
+               //
+               // Convert the argument
+               //
+               ConvertedArgument<HexBinary> data = new 
ConvertedArgument<HexBinary>(arg0, DataTypeHexBinary.newInstance(), false);
+               if (! data.isOk()) {
+                       return ExpressionResult.newError(new 
StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, argument 
0 failed to convert to Hex Binary."));
+               }
+               //
+               // Ok - check the 2nd argument
+               //
+               FunctionArgument arg1 = arguments.get(1);
+               if (arg1.isBag()) {
+                       //
+                       // We don't support bags right now
+                       //
+                       return ExpressionResult.newError(new 
StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, not 
expecting a bag for argument 1."));
+               }
+               if 
(arg1.getValue().getDataTypeId().equals(DataTypePrivateKey.DT_PRIVATEKEY) ||
+                               
arg1.getValue().getDataTypeId().equals(DataTypePublicKey.DT_PUBLICKEY)) {
+                       //
+                       // Ok - let's try to decrypt
+                       //
+                       Cipher cipher;
+                       try {
+                               cipher = Cipher.getInstance("RSA");
+                               if 
(arg1.getValue().getDataTypeId().equals(DataTypePrivateKey.DT_PRIVATEKEY)) {
+                                       //
+                                       // Using the private key
+                                       //
+                                       DataType<PrivateKey> pkDatatype = 
DataTypePrivateKey.newInstance();
+                                       ConvertedArgument<PrivateKey> 
privateKey = new ConvertedArgument<PrivateKey>(arg1, pkDatatype, false);
+                                       if ( ! privateKey.isOk()) {
+                                               return 
ExpressionResult.newError(new StdStatus(privateKey.getStatus().getStatusCode(), 
"Decrypt: " + privateKey.getStatus().getStatusMessage()));
+                                       }
+                                       //
+                                       // Setup decryption
+                                       //
+                                       cipher.init(Cipher.DECRYPT_MODE, 
privateKey.getValue());
+                               } else if 
(arg1.getValue().getDataTypeId().equals(DataTypePublicKey.DT_PUBLICKEY)) {
+                                       //
+                                       // Using the private key
+                                       //
+                                       DataType<PublicKey> pkDatatype = 
DataTypePublicKey.newInstance();
+                                       ConvertedArgument<PublicKey> publicKey 
= new ConvertedArgument<PublicKey>(arg1, pkDatatype, false);
+                                       if ( ! publicKey.isOk()) {
+                                               return 
ExpressionResult.newError(new StdStatus(publicKey.getStatus().getStatusCode(), 
"Decrypt: " + publicKey.getStatus().getStatusMessage()));
+                                       }
+                                       //
+                                       // Setup decryption
+                                       //
+                                       cipher.init(Cipher.DECRYPT_MODE, 
publicKey.getValue());
+                               }
+                               //
+                               // Do the decryption
+                               //
+                               byte[] decryptedData = 
cipher.doFinal(data.getValue().getData());
+                               String decryptedString = new 
String(decryptedData);
+                               //
+                               // All good, return the decrypted string
+                               //
+                               return 
ExpressionResult.newSingle(DataTypeString.newInstance().createAttributeValue(decryptedString));
+                       } catch (NoSuchAlgorithmException | 
NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | 
BadPaddingException | DataTypeException e) {
+                               return ExpressionResult.newError(new 
StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed: " + 
e.getLocalizedMessage()));
+                       }
+               }               
+               return ExpressionResult.newError(new 
StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, 
expecting public/private key datatype for argument 1."));
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom.java
----------------------------------------------------------------------
diff --git 
a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom.java
 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom.java
new file mode 100755
index 0000000..df93001
--- /dev/null
+++ 
b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom.java
@@ -0,0 +1,384 @@
+/*
+ *                        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.xacmlatt.pdp.test.custom;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.MalformedURLException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+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.Request;
+import com.att.research.xacml.api.RequestAttributes;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.api.pep.PEPException;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdMutableAttribute;
+import com.att.research.xacml.std.StdMutableRequest;
+import com.att.research.xacml.std.StdMutableRequestAttributes;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.json.JSONStructureException;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacmlatt.pdp.test.TestBase;
+
+/**
+ * TestCustom is an application that tests the extensibility and 
configurability of the AT&T XACML API.
+ * 
+ * It creates a custom datatype definition factory that adds in custom data 
types for RSA
+ * PublicKey and PrivateKey.
+ * 
+ * It creates a custom function definition factory that adds in custom 
decryption function for decrypting data. It
+ * also derives and loads custom functions for the RSA public/private key 
datatypes for the bag function: one-and-only. 
+ * 
+ * @author pameladragosh
+ *
+ */
+public class TestCustom extends TestBase {
+       private static final Log logger = LogFactory.getLog(TestCustom.class);
+       
+       //
+       // Our public's
+       //
+       public static final String ALGORITHM = "RSA";
+       public static final String PRIVATEKEY_FILE = "PrivateKey.key";
+       public static final String PUBLICKEY_FILE = "PublicKey.key";
+       
+       public static final String DECRYPTION_INPUT_STRING = "This is the 
SECRET value!";
+       
+       public static final String DECRYPTION_INPUT_ID = 
"com:att:research:xacml:test:custom:encrypted-data";
+       //
+       // Our keys
+       //
+       protected PublicKey publicKey = null;
+       protected PrivateKey privateKey = null;
+       //
+       // Our command line parameters
+       //
+       public static final String OPTION_GENERATE = "generate";
+
+       static {
+               options.addOption(new Option(OPTION_GENERATE, false, "Generate 
a private/public key pair."));
+       }
+       
+       /**
+        * This function generates the public/private key pair. Should never 
have to call this again, this was
+        * called once to generate the keys. They were saved into the 
testsets/custom/datatype-function sub-directory.
+        */
+       public void generateKeyPair() {
+               //
+               // Generate a RSA private/public key pair
+               //
+               KeyPairGenerator keyGen;
+               try {
+                       keyGen = KeyPairGenerator.getInstance(ALGORITHM);
+               } catch (NoSuchAlgorithmException e) {
+                       logger.error("failed to generate keypair: " + e);
+                       return;
+               }
+               keyGen.initialize(1024);
+               final KeyPair key = keyGen.generateKeyPair();
+               //
+               // Save the keys to disk
+               //
+               Path file = Paths.get(this.directory, PRIVATEKEY_FILE);
+               try (ObjectOutputStream os = new 
ObjectOutputStream(Files.newOutputStream(file))) {
+                       os.writeObject(key.getPrivate());
+               } catch (IOException e) {
+                       e.printStackTrace();
+               }
+               file = Paths.get(this.directory, PUBLICKEY_FILE);
+               try (ObjectOutputStream os = new 
ObjectOutputStream(Files.newOutputStream(file))) {
+                       os.writeObject(key.getPublic());
+               } catch (IOException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       public TestCustom(String[] args) throws ParseException, 
MalformedURLException, HelpException {
+               super(args);
+       }
+       
+       /* (non-Javadoc)
+        * 
+        * Simply look for command line option: -generate
+        * This generates the public/private key. Shouldn't need to call it 
again, the keys have
+        * already been generated and saved.
+        * 
+        * @see 
com.att.research.xacmlatt.pdp.test.TestBase#parseCommands(java.lang.String[])
+        */
+       @Override
+       protected void parseCommands(String[] args) throws ParseException, 
MalformedURLException, HelpException {
+               //
+               // Have our parent class parse its options out
+               //
+               super.parseCommands(args);
+               //
+               // Parse the command line options
+               //
+               CommandLine cl;
+               cl = new GnuParser().parse(options, args);
+               if (cl.hasOption(OPTION_GENERATE)) {
+                       //
+                       // Really only need to do this once to setup the test.
+                       //
+                       this.generateKeyPair();
+               }
+       }
+
+       /* (non-Javadoc)
+        * 
+        * After our parent class configure's itself, all this needs to do is 
read in
+        * the public/private key's into objects.
+        * 
+        * @see com.att.research.xacmlatt.pdp.test.TestBase#configure()
+        */
+       @Override
+       protected void configure() throws FactoryException {
+               //
+               // Have our super do its thing
+               //
+               super.configure();
+               //
+               // Read in the public key
+               //
+               try {
+                       this.publicKey = (PublicKey) new 
ObjectInputStream(Files.newInputStream(Paths.get(this.directory, 
PUBLICKEY_FILE))).readObject();
+               } catch (ClassNotFoundException | IOException e) {
+                       logger.error(e);
+               }
+               //
+               // Read in the private key
+               //
+               try {
+                       this.privateKey = (PrivateKey) new 
ObjectInputStream(Files.newInputStream(Paths.get(this.directory, 
PRIVATEKEY_FILE))).readObject();
+               } catch (ClassNotFoundException | IOException e) {
+                       logger.error(e);
+               }
+       }
+
+       /* (non-Javadoc)
+        * 
+        * Here we add 2 attributes into the request: 1) the private key, and 
2) a String that was encrypted using the public key.
+        * 
+        * The goal is to have the custom decrypt function use the private key 
to decrypt that string.
+        * 
+        * @see 
com.att.research.xacmlatt.pdp.test.TestBase#generateRequest(java.nio.file.Path, 
java.lang.String)
+        */
+       @Override
+       protected Request generateRequest(Path file, String group) throws 
JSONStructureException, DOMStructureException, PEPException {
+               //
+               // Have our super class do its work
+               //
+               Request oldRequest = super.generateRequest(file, group);
+               //
+               // Copy the request attributes
+               //
+               List<StdMutableRequestAttributes> attributes = new 
ArrayList<StdMutableRequestAttributes>();
+               for (RequestAttributes a : oldRequest.getRequestAttributes()) {
+                       attributes.add(new StdMutableRequestAttributes(a));
+               }
+               //
+               // We are supplying the private key as an attribute for the 
decryption function to use:
+               //
+               // (NOTE: Ideally this would be provided by a custom PIP 
provider, not the PEP)
+               //
+               // ID=com:att:research:xacml:test:custom:privatekey
+               // Issuer=com:att:research:xacml:test:custom
+               // 
Category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+               // Datatype=urn:com:att:research:xacml:custom:3.0:rsa:private
+               //
+               DataType<?> dtExtended = 
dataTypeFactory.getDataType(DataTypePrivateKey.DT_PRIVATEKEY);
+               if (dtExtended == null) {
+                       logger.error("Failed to get private key datatype.");
+                       return null;
+               }
+               //
+               // Create the attribute value
+               //
+               try {
+                       AttributeValue<?> attributeValue = 
dtExtended.createAttributeValue(this.privateKey);                               
     
+                       //
+                       // Create the attribute
+                       //
+                       StdMutableAttribute newAttribute = new 
StdMutableAttribute(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT,
+                                                                               
                                                                new 
IdentifierImpl("com:att:research:xacml:test:custom:privatekey"),
+                                                                               
                                                                attributeValue,
+                                                                               
                                                                
"com:att:research:xacml:test:custom",
+                                                                               
                                                                false);
+                       boolean added = false;
+                       for (StdMutableRequestAttributes a : attributes) {
+                               //
+                               // Does the category exist?
+                               //
+                               if 
(a.getCategory().equals(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT)) {
+                                       //
+                                       // Yes - add in the new attribute value
+                                       //
+                                       a.add(newAttribute);
+                                       added = true;
+                                       break;
+                               }
+                       }
+                       if (added == false) {
+                               //
+                               // New category - create it and add it in
+                               //
+                               StdMutableRequestAttributes a = new 
StdMutableRequestAttributes(); 
+                               a.setCategory(newAttribute.getCategory());
+                               a.add(newAttribute);
+                               attributes.add(a);
+                       }
+               } catch (DataTypeException e) {
+                       logger.error(e);
+                       return null;
+               }
+               //
+               // We are also supplying this attribute which is the secret 
text encrypted with
+               // the public key.
+               //
+               // ID=com:att:research:xacml:test:custom:encrypted-data
+               // Issuer=
+               // 
Category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+               // Datatype=http://www.w3.org/2001/XMLSchema#hexBinary
+               //
+               // Encrypt it
+               //
+               byte[] encryptedData = null;
+               try {
+                       Cipher cipher = Cipher.getInstance(ALGORITHM);
+                       cipher.init(Cipher.ENCRYPT_MODE, this.publicKey);
+                       //
+                       // This is just a hack to test a decryption of the 
wrong value.
+                       //
+                       if (group.equals("Permit")) {
+                               encryptedData = 
cipher.doFinal(DECRYPTION_INPUT_STRING.getBytes());
+                       } else {
+                               encryptedData = cipher.doFinal("This is NOT the 
secret".getBytes());
+                       }
+               } catch (NoSuchAlgorithmException | NoSuchPaddingException | 
InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
+                       logger.error(e);
+                       return null;
+               }
+               //
+               // Sanity check (for the Permit request)
+               //
+               try {
+                       if (group.equals("Permit")) {
+                               Cipher cipher = Cipher.getInstance(ALGORITHM);
+                               cipher.init(Cipher.DECRYPT_MODE, 
this.privateKey);
+                               byte[] decryptedData = 
cipher.doFinal(encryptedData);
+                               if (new 
String(decryptedData).equals(DECRYPTION_INPUT_STRING)) {
+                                       logger.info("Sanity check passed: 
decrypted the encrypted data.");
+                               } else {
+                                       logger.error("Sanity check failed to 
decrypt the encrypted data.");
+                                       return null;
+                               }
+                       }
+               } catch (NoSuchAlgorithmException | NoSuchPaddingException | 
InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
+                       logger.error(e);
+               }
+               //
+               // Get our datatype factory
+               //
+               dtExtended = 
dataTypeFactory.getDataType(XACML3.ID_DATATYPE_HEXBINARY);
+               if (dtExtended == null) {
+                       logger.error("Failed to get hex binary datatype.");
+                       return null;
+               }
+               //
+               // Create the attribute value
+               //
+               try {
+                       AttributeValue<?> attributeValue = 
dtExtended.createAttributeValue(encryptedData);                                 
     
+                       //
+                       // Create the attribute
+                       //
+                       StdMutableAttribute newAttribute = new 
StdMutableAttribute(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT,
+                                                                               
                                                                new 
IdentifierImpl("com:att:research:xacml:test:custom:encrypted-data"),
+                                                                               
                                                                attributeValue,
+                                                                               
                                                                null,
+                                                                               
                                                                false);
+                       boolean added = false;
+                       for (StdMutableRequestAttributes a : attributes) {
+                               //
+                               // Does the category exist?
+                               //
+                               if 
(a.getCategory().equals(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT)) {
+                                       //
+                                       // Yes - add in the new attribute value
+                                       //
+                                       a.add(newAttribute);
+                                       added = true;
+                                       break;
+                               }
+                       }
+                       if (added == false) {
+                               //
+                               // New category - create it and add it in
+                               //
+                               StdMutableRequestAttributes a = new 
StdMutableRequestAttributes(); 
+                               a.setCategory(newAttribute.getCategory());
+                               a.add(newAttribute);
+                               attributes.add(a);
+                       }
+               } catch (DataTypeException e) {
+                       logger.error(e);
+                       return null;
+               }
+               //
+               // Now form our final request
+               //
+               StdMutableRequest newRequest = new StdMutableRequest();
+               
newRequest.setCombinedDecision(oldRequest.getCombinedDecision());
+               newRequest.setRequestDefaults(oldRequest.getRequestDefaults());
+               
newRequest.setReturnPolicyIdList(oldRequest.getReturnPolicyIdList());
+               newRequest.setStatus(oldRequest.getStatus());
+               for (StdMutableRequestAttributes a : attributes) {
+                       newRequest.add(a);
+               }
+               return newRequest;
+       }
+
+       public static void main(String[] args) {
+               try {
+                       new TestCustom(args).run();
+               } catch (ParseException | IOException | FactoryException e) {
+                       logger.error(e);
+               } catch (HelpException e) {
+               }               
+       }
+
+}

Reply via email to