Coverage Report - org.openpermis.xacml.io.v2.BasicXacmlReader
 
Classes in this File Line Coverage Branch Coverage Complexity
BasicXacmlReader
79%
27/34
62%
5/8
6
 
 1  
 /*
 2  
  * Copyright (c) 2009, Ergon Informatik AG (http://www.ergon.ch)
 3  
  * All rights reserved.
 4  
  * 
 5  
  * Licensed under the Open Permis License which accompanies this distribution, 
 6  
  * and is available at http://www.openpermis.org/BSDlicenceKent.txt
 7  
  */
 8  
 package org.openpermis.xacml.io.v2;
 9  
 
 10  
 import java.io.Reader;
 11  
 import java.net.URI;
 12  
 import java.util.HashMap;
 13  
 import java.util.List;
 14  
 
 15  
 import org.dom4j.Document;
 16  
 import org.dom4j.DocumentException;
 17  
 import org.dom4j.Element;
 18  
 import org.dom4j.io.SAXReader;
 19  
 import org.jaxen.JaxenException;
 20  
 import org.jaxen.SimpleNamespaceContext;
 21  
 import org.jaxen.dom4j.Dom4jXPath;
 22  
 
 23  
 import org.openpermis.xacml.io.XacmlException;
 24  
 import org.openpermis.xacml.io.XacmlReader;
 25  
 import org.openpermis.xacml.io.XacmlRequest;
 26  
 
 27  
 
 28  
 
 29  
 /**
 30  
  * Basic implementation of a xacml reader.
 31  
  * @since 0.4.0
 32  
  */
 33  
 public class BasicXacmlReader implements XacmlReader {
 34  
 
 35  
         //---- Static
 36  
         
 37  
         /**
 38  
          * @since 0.4.0
 39  
          */
 40  
         public static final String XACML_CONTEXT_NAMESPACE = 
 41  
                 "urn:oasis:names:tc:xacml:2.0:context:schema:os";
 42  
         
 43  
         /**
 44  
          * @since 0.4.0
 45  
          */
 46  
         public static final String SUBJECT_ID = "urn:oasis:names:tc:xacml:1.0:subject:subject-id";
 47  
         
 48  
         /**
 49  
          * @since 0.4.0
 50  
          */
 51  
         public static final String ACTION_ID = "urn:oasis:names:tc:xacml:1.0:action:action-id";
 52  
         
 53  
         /**
 54  
          * @since 0.4.0
 55  
          */
 56  
         public static final String RESOURCE_ID = "urn:oasis:names:tc:xacml:1.0:resource:resource-id";
 57  
         
 58  
         /**
 59  
          * @since 0.4.0
 60  
          */
 61  
         public static final String STRING_TYPE = "http://www.w3.org/2001/XMLSchema#string";
 62  
         
 63  
         /**
 64  
          * @since 0.4.0
 65  
          */
 66  
         public static final String URI_TYPE = "http://www.w3.org/2001/XMLSchema#anyURI";
 67  
 
 68  
         //---- State
 69  
         
 70  
         private final Dom4jXPath subjectExpression;
 71  
         
 72  
         private final Dom4jXPath actionExpression;
 73  
         
 74  
         private final Dom4jXPath resourceExpression;
 75  
         
 76  
         //---- Constructors
 77  
         
 78  
         /**
 79  
          * @since 0.4.0
 80  
          */
 81  5
         public BasicXacmlReader () {
 82  
                 try {
 83  
                         // Namespace.
 84  5
                         final HashMap<String, String> map = new HashMap<String, String>();
 85  5
                         map.put( "ns", XACML_CONTEXT_NAMESPACE);
 86  5
                         final SimpleNamespaceContext namespace = new SimpleNamespaceContext(map);
 87  
                         
 88  
                         // Subject.
 89  5
                         this.subjectExpression = new Dom4jXPath(
 90  
                                 "/Request/ns:Subject/ns:Attribute[" +
 91  
                                         "@AttributeId='" + SUBJECT_ID + "' and " +
 92  
                                         "(@DataType='" + STRING_TYPE + "' or @DataType='" + URI_TYPE + "')" +
 93  
                                 "]/ns:AttributeValue");
 94  5
                         this.subjectExpression.setNamespaceContext(namespace);
 95  
                         
 96  
                         // Action.
 97  5
                         this.actionExpression = new Dom4jXPath(
 98  
                                 "/Request/ns:Action/ns:Attribute[@AttributeId='" + 
 99  
                                 ACTION_ID + "' and @DataType='" + STRING_TYPE + 
 100  
                                 "']/ns:AttributeValue");
 101  5
                         this.actionExpression.setNamespaceContext(namespace);
 102  
                         
 103  
                         // Resource.
 104  5
                         this.resourceExpression = new Dom4jXPath(
 105  
                                 "/Request/ns:Resource/ns:Attribute[" +
 106  
                                         "@AttributeId='" + RESOURCE_ID + "' and " +
 107  
                                         "(@DataType='" + STRING_TYPE + "' or @DataType='" + URI_TYPE + "')" +
 108  
                                 "]/ns:AttributeValue");
 109  5
                         this.resourceExpression.setNamespaceContext(namespace);
 110  
                         
 111  0
                 } catch (JaxenException e) {
 112  0
                         throw new IllegalStateException("Invalid xpath expressions.");
 113  5
                 }
 114  5
         }
 115  
         
 116  
         //---- Methods
 117  
         
 118  
         /**
 119  
          * Executes a xpath expression on the document and return the result.
 120  
          * @param document a {@link Document}.
 121  
          * @param expression a {@link Dom4jXPath}.
 122  
          * @throws XacmlException indicates that no result could be found. 
 123  
          * @since 0.4.0
 124  
          */
 125  
         @SuppressWarnings("unchecked")
 126  
         private String executeExpression (Document document, Dom4jXPath expression) 
 127  
                 throws XacmlException 
 128  
         {
 129  
                 List<Object> nodes;
 130  
                 try {
 131  6
                         nodes = expression.selectNodes(document);
 132  0
                 } catch (JaxenException e) {
 133  0
                         throw new XacmlException("Expression failure.", e);
 134  6
                 }
 135  
                 
 136  6
                 if (nodes == null) {
 137  0
                         throw new XacmlException("No expression found.");
 138  
                 } 
 139  
                 
 140  6
                 if (nodes.size() != 1) {
 141  0
                         throw new XacmlException("More than one expression found.");
 142  
                 } 
 143  6
                 final Element element = (Element) nodes.get(0);
 144  6
                 final String text = element.getText();
 145  
                 
 146  6
                 if (text == null) {
 147  0
                         throw new XacmlException("Expression text is null.");
 148  
                 }
 149  6
                 return text;
 150  
         }
 151  
         
 152  
         //---- RequestReader
 153  
 
 154  
         /**
 155  
          * @since 0.4.0
 156  
          */
 157  
         public XacmlRequest readRequest (Reader request) throws XacmlException {
 158  5
                 if (request == null) {
 159  1
                         throw new IllegalArgumentException("Request is null");
 160  
                 }
 161  
                 
 162  4
                 final SAXReader reader = new SAXReader();
 163  
                 
 164  
                 try {
 165  4
                         final Document document = reader.read(request);
 166  
                         
 167  2
                         return new XacmlRequest(
 168  
                                 URI.create(executeExpression(document, this.subjectExpression)),
 169  
                                 URI.create(executeExpression(document, this.resourceExpression)),
 170  
                                 executeExpression(document, this.actionExpression)
 171  
                         );
 172  
                         
 173  2
                 } catch (DocumentException e) {
 174  2
                         throw new XacmlException("Could not read document.", e);
 175  
                 }
 176  
         }
 177  
         
 178  
 }