2 * The Shibboleth License, Version 1.
4 * University Corporation for Advanced Internet Development, Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
11 * Redistributions of source code must retain the above copyright notice, this
12 * list of conditions and the following disclaimer.
14 * Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution, if any, must include
17 * the following acknowledgment: "This product includes software developed by
18 * the University Corporation for Advanced Internet Development
19 * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
20 * may appear in the software itself, if and wherever such third-party
21 * acknowledgments normally appear.
23 * Neither the name of Shibboleth nor the names of its contributors, nor
24 * Internet2, nor the University Corporation for Advanced Internet Development,
25 * Inc., nor UCAID may be used to endorse or promote products derived from this
26 * software without specific prior written permission. For written permission,
27 * please contact shibboleth@shibboleth.org
29 * Products derived from this software may not be called Shibboleth, Internet2,
30 * UCAID, or the University Corporation for Advanced Internet Development, nor
31 * may Shibboleth appear in their name, without prior written permission of the
32 * University Corporation for Advanced Internet Development.
35 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
36 * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
38 * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
39 * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
40 * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
41 * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
42 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 package edu.internet2.middleware.shibboleth.aa.arp;
53 import java.net.URISyntaxException;
55 import java.util.ArrayList;
56 import java.util.HashSet;
57 import java.util.Iterator;
60 import javax.xml.parsers.DocumentBuilderFactory;
61 import javax.xml.parsers.ParserConfigurationException;
63 import org.apache.log4j.Logger;
64 import org.w3c.dom.CharacterData;
65 import org.w3c.dom.Document;
66 import org.w3c.dom.Element;
67 import org.w3c.dom.Node;
68 import org.w3c.dom.NodeList;
69 import org.w3c.dom.Text;
72 * An Attribute Release Policy Rule.
74 * @author Walter Hoehn (wassa@columbia.edu)
79 private String description;
80 private Target target;
81 private static Logger log = Logger.getLogger(Rule.class.getName());
82 private ArrayList attributes = new ArrayList();
83 private NodeList attributeReferences;
85 private URI identifier;
88 * Returns the description for this <code>Rule</code>.
92 public String getDescription() {
97 * Sets the description for this <code>Rule</code>.
98 * @param description The description to set
101 public void setDescription(String description) {
102 this.description = description;
106 * Returns all of the attribute specifications associated with this Rule.
107 * @return the attributes
110 public Attribute[] getAttributes() {
111 return (Attribute[]) attributes.toArray(new Attribute[0]);
115 * Unmarshalls the <code>Rule</code> into an xml <code>Element</code>.
116 * @return the xml <code>Element</code>
119 public Element unmarshall() throws ArpMarshallingException {
122 Document placeHolder = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
123 Element ruleNode = placeHolder.createElementNS(Arp.arpNamespace, "Rule");
125 if (identifier != null) {
126 ruleNode.setAttributeNS(Arp.arpNamespace, "identifier", identifier.toString());
129 if (description != null) {
130 Element descriptionNode = placeHolder.createElementNS(Arp.arpNamespace, "Description");
131 descriptionNode.appendChild(placeHolder.createTextNode(description));
132 ruleNode.appendChild(descriptionNode);
134 ruleNode.appendChild(placeHolder.importNode(target.unmarshall(), true));
135 Iterator attrIterator = attributes.iterator();
136 while (attrIterator.hasNext()) {
137 ruleNode.appendChild(
138 placeHolder.importNode(((Attribute) attrIterator.next()).unmarshall(), true));
141 if (attributeReferences != null) {
142 for (int i = 0;i < attributeReferences.getLength();i++) {
143 ruleNode.appendChild(
144 placeHolder.importNode(attributeReferences.item(i), true));
148 } catch (ParserConfigurationException e) {
149 log.error("Encountered a problem unmarshalling an ARP Rule: " + e);
150 throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP Rule.");
155 * Creates an ARP Rule from an xml representation.
156 * @param element the xml <code>Element</code> containing the ARP Rule.
159 public void marshall(Element element) throws ArpMarshallingException {
161 //Make sure we are dealing with a Rule
162 if (!element.getTagName().equals("Rule")) {
163 log.error("Element data does not represent an ARP Rule.");
164 throw new ArpMarshallingException("Element data does not represent an ARP Rule.");
167 //Get the rule identifier
169 if (element.hasAttribute("identifier")) {
170 identifier = new URI(element.getAttribute("identifier"));
172 } catch (URISyntaxException e) {
173 log.error("Rule not identified by a proper URI: " + e);
174 throw new ArpMarshallingException("Rule not identified by a proper URI.");
177 //Grab the description
178 NodeList descriptionNodes = element.getElementsByTagNameNS(Arp.arpNamespace, "Description");
179 if (descriptionNodes.getLength() > 0) {
180 Element descriptionNode = (Element) descriptionNodes.item(0);
181 if (descriptionNode.hasChildNodes()
182 && descriptionNode.getFirstChild().getNodeType() == Node.TEXT_NODE) {
183 description = ((CharacterData) descriptionNode.getFirstChild()).getData();
188 NodeList targetNodes = element.getElementsByTagNameNS(Arp.arpNamespace, "Target");
189 if (targetNodes.getLength() != 1) {
191 "Element data does not represent an ARP Rule. An ARP Rule must contain 1 and "
192 + "only 1 Target definition.");
193 throw new ArpMarshallingException(
194 "Element data does not represent an ARP Rule. An"
195 + " ARP Rule must contain 1 and only 1 Target definition.");
197 target = new Target();
198 target.marshall((Element) targetNodes.item(0));
200 //Create the Attributes
201 NodeList attributeNodes = element.getElementsByTagNameNS(Arp.arpNamespace, "Attribute");
202 for (int i = 0; attributeNodes.getLength() > i; i++) {
203 Attribute attribute = new Attribute();
204 attribute.marshall((Element) attributeNodes.item(i));
205 attributes.add(attribute);
208 //Retain Attribute references
210 NodeList attributeReferenceNodes =
211 element.getElementsByTagNameNS(Arp.arpNamespace, "AttributeReference");
212 if (attributeReferenceNodes.getLength() > 0) {
214 "Encountered an Attribute Reference while marshalling an ARP. "
215 + "References are currently unsupported by the ARP Engine. Ignoring...");
216 attributeReferences = attributeReferenceNodes;
221 * Returns a boolean indication of whether this rule is applicable to a given attribute request.
222 * @param requester the SHAR making the request
223 * @param resource the resource on behalf of which the request is being made
226 public boolean matchesRequest(String requester, URL resource) {
227 if (target.matchesAny()) {
231 if (requester == null) {
236 MatchFunction requesterFunction =
237 ArpEngine.lookupMatchFunction(target.getRequester().getMatchFunctionIdentifier());
238 if (!requesterFunction.match(target.getRequester().getValue(), requester)) {
242 if (target.getResource().matchesAny()) {
246 if (resource == null) {
250 MatchFunction resourceFunction =
251 ArpEngine.lookupMatchFunction(target.getResource().getMatchFunctionIdentifier());
252 if (resourceFunction.match(target.getResource().getValue(), resource)) {
256 } catch (ArpException e) {
257 log.warn("Encountered a problem while trying to find matching ARP rules: " + e);
263 private Requester requester = null;
264 private Resource resource = null;
265 private boolean matchesAny = false;
268 * Unmarshalls the <code>Rule.Target</code> into an xml <code>Element</code>.
269 * @return the xml <code>Element</code>
272 Element unmarshall() throws ArpMarshallingException {
275 Document placeHolder =
276 DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
277 Element targetNode = placeHolder.createElementNS(Arp.arpNamespace, "Target");
280 Element anyTargetNode = placeHolder.createElementNS(Arp.arpNamespace, "AnyTarget");
281 targetNode.appendChild(anyTargetNode);
284 targetNode.appendChild(placeHolder.importNode(requester.unmarshall(), true));
285 if (target.resource.matchesAny()) {
286 Element anyResourceNode = placeHolder.createElementNS(Arp.arpNamespace, "AnyResource");
287 targetNode.appendChild(anyResourceNode);
290 targetNode.appendChild(placeHolder.importNode(resource.unmarshall(), true));
292 } catch (ParserConfigurationException e) {
293 log.error("Encountered a problem unmarshalling an ARP Rule: " + e);
294 throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP Rule.");
299 * Creates an ARP Rule Target from an xml representation.
300 * @param element the xml <code>Element</code> containing the ARP Rule.
302 void marshall(Element element) throws ArpMarshallingException {
304 //Make sure we are dealing with a Target
305 if (!element.getTagName().equals("Target")) {
306 log.error("Element data does not represent an ARP Rule Target.");
307 throw new ArpMarshallingException("Element data does not represent an ARP Rule target.");
310 //Handle <AnyTarget/> definitions
311 NodeList anyTargetNodeList = element.getElementsByTagNameNS(Arp.arpNamespace, "AnyTarget");
312 if (anyTargetNodeList.getLength() == 1) {
318 NodeList requesterNodeList = element.getElementsByTagNameNS(Arp.arpNamespace, "Requester");
319 if (requesterNodeList.getLength() == 1) {
320 requester = new Requester();
321 requester.marshall((Element) requesterNodeList.item(0));
323 log.error("ARP Rule Target contains invalid data: incorrectly specified <Requester>.");
324 throw new ArpMarshallingException("ARP Rule Target contains invalid data: incorrectly specified <Requester>.");
327 //Handle <AnyResource/>
328 NodeList anyResourceNodeList = element.getElementsByTagNameNS(Arp.arpNamespace, "AnyResource");
329 if (anyResourceNodeList.getLength() == 1) {
330 resource = new Resource();
335 NodeList resourceNodeList = element.getElementsByTagNameNS(Arp.arpNamespace, "Resource");
336 if (resourceNodeList.getLength() == 1) {
337 resource = new Resource();
338 resource.marshall((Element) resourceNodeList.item(0));
340 resource = new Resource();
344 boolean matchesAny() {
347 Requester getRequester() {
350 Resource getResource() {
356 private String value;
357 private URI matchFunctionIdentifier;
358 private boolean matchesAny;
362 boolean matchesAny() {
365 URI getMatchFunctionIdentifier() {
366 return matchFunctionIdentifier;
373 * Unmarshalls the <code>Rule.Resource</code> into an xml <code>Element</code>.
374 * @return the xml <code>Element</code>
377 Element unmarshall() throws ArpMarshallingException {
380 Document placeHolder =
381 DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
382 Element resourceNode = placeHolder.createElementNS(Arp.arpNamespace, "Resource");
383 if (!matchFunctionIdentifier
384 .equals(new URI("urn:mace:shibboleth:arp:matchFunction:resourceTree"))) {
385 resourceNode.setAttributeNS(Arp.arpNamespace, "matchFunction", matchFunctionIdentifier.toString());
387 Text valueNode = placeHolder.createTextNode(value);
388 resourceNode.appendChild(valueNode);
391 } catch (URISyntaxException e) {
392 log.error("Encountered a problem unmarshalling an ARP Rule Resource: " + e);
393 throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP Rule Resource.");
394 } catch (ParserConfigurationException e) {
395 log.error("Encountered a problem unmarshalling an ARP Rule Resource: " + e);
396 throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP Rule Resource.");
401 * Creates an ARP Rule Target Resource from an xml representation.
402 * @param element the xml <code>Element</code> containing the ARP Rule.
404 void marshall(Element element) throws ArpMarshallingException {
408 //Make sure we are deling with a Resource
409 if (!element.getTagName().equals("Resource")) {
410 log.error("Element data does not represent an ARP Rule Target.");
411 throw new ArpMarshallingException("Element data does not represent an ARP Rule target.");
415 if (element.hasChildNodes() && element.getFirstChild().getNodeType() == Node.TEXT_NODE) {
416 value = ((CharacterData) element.getFirstChild()).getData();
418 log.error("Element data does not represent an ARP Rule Target.");
419 throw new ArpMarshallingException("Element data does not represent an ARP Rule target.");
422 //Grab the match function
424 if (element.hasAttribute("matchFunction")) {
425 matchFunctionIdentifier = new URI(element.getAttribute("matchFunction"));
427 matchFunctionIdentifier = new URI("urn:mace:shibboleth:arp:matchFunction:resourceTree");
429 } catch (URISyntaxException e) {
430 log.error("ARP match function not identified by a proper URI.");
431 throw new ArpMarshallingException("ARP match function not identified by a proper URI.");
437 private String value;
438 private URI matchFunctionIdentifier;
439 URI getMatchFunctionIdentifier() {
440 return matchFunctionIdentifier;
447 * Unmarshalls the <code>Rule.Requester</code> into an xml <code>Element</code>.
448 * @return the xml <code>Element</code>
451 Element unmarshall() throws ArpMarshallingException {
454 Document placeHolder =
455 DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
456 Element requesterNode = placeHolder.createElementNS(Arp.arpNamespace, "Requester");
457 if (!matchFunctionIdentifier
458 .equals(new URI("urn:mace:shibboleth:arp:matchFunction:exactShar"))) {
459 requesterNode.setAttributeNS(Arp.arpNamespace, "matchFunction", matchFunctionIdentifier.toString());
461 Text valueNode = placeHolder.createTextNode(value);
462 requesterNode.appendChild(valueNode);
463 return requesterNode;
465 } catch (URISyntaxException e) {
466 log.error("Encountered a problem unmarshalling an ARP Rule Requester: " + e);
467 throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP Rule Requester.");
468 } catch (ParserConfigurationException e) {
469 log.error("Encountered a problem unmarshalling an ARP Rule Requester: " + e);
470 throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP Rule Requester.");
475 * Creates an ARP Rule Target Requester from an xml representation.
476 * @param element the xml <code>Element</code> containing the ARP Rule.
478 void marshall(Element element) throws ArpMarshallingException {
479 //Make sure we are deling with a Requester
480 if (!element.getTagName().equals("Requester")) {
481 log.error("Element data does not represent an ARP Rule Target.");
482 throw new ArpMarshallingException("Element data does not represent an ARP Rule target.");
486 if (element.hasChildNodes() && element.getFirstChild().getNodeType() == Node.TEXT_NODE) {
487 value = ((CharacterData) element.getFirstChild()).getData();
489 log.error("Element data does not represent an ARP Rule Target.");
490 throw new ArpMarshallingException("Element data does not represent an ARP Rule target.");
493 //Grab the match function
495 if (element.hasAttribute("matchFunction")) {
496 matchFunctionIdentifier = new URI(element.getAttribute("matchFunction"));
498 matchFunctionIdentifier = new URI("urn:mace:shibboleth:arp:matchFunction:exactShar");
500 } catch (URISyntaxException e) {
501 log.error("ARP match function not identified by a proper URI.");
502 throw new ArpMarshallingException("ARP match function not identified by a proper URI.");
510 private boolean anyValue = false;
511 private String anyValueRelease = "permit";
512 private Set values = new HashSet();
513 private URI identifier;
515 boolean releaseAnyValue() {
516 if (anyValueRelease.equals("permit")) {
522 boolean denyAnyValue() {
523 if (anyValueRelease.equals("deny")) {
529 void setAnyValueDeny(boolean b) {
532 anyValueRelease = "deny";
535 if (anyValueRelease.equals("deny") && anyValue) {
541 boolean isValuePermitted(Object value) {
543 if (denyAnyValue()) {
547 //Handle Permit All with no specific values
548 if (releaseAnyValue() && getValues().length == 0) {
552 //Handle Deny Specific
553 Iterator iterator = values.iterator();
554 while (iterator.hasNext()) {
555 AttributeValue valueSpec = (AttributeValue) iterator.next();
557 MatchFunction resourceFunction;
559 resourceFunction = ArpEngine.lookupMatchFunction(valueSpec.getMatchFunctionIdentifier());
560 // For safety, err on the side of caution
561 if (resourceFunction == null) {
563 "Could not locate matching function for ARP value. Function: "
564 + valueSpec.getMatchFunctionIdentifier().toString());
568 } catch (ArpException e) {
569 log.error("Error while attempting to find referenced matching function for ARP values: " + e);
574 if (valueSpec.getRelease().equals("deny") && resourceFunction.match(valueSpec.getValue(), value)) {
577 } catch (MatchingException e) {
578 log.error("Could not apply referenced matching function to ARP value: " + e);
583 //Handle Permit All with no relevant specific denies
584 if (releaseAnyValue()) {
588 //Handle Permit Specific
589 iterator = values.iterator();
590 while (iterator.hasNext()) {
591 AttributeValue valueSpec = (AttributeValue) iterator.next();
593 MatchFunction resourceFunction;
595 resourceFunction = ArpEngine.lookupMatchFunction(valueSpec.getMatchFunctionIdentifier());
596 // Ignore non-functional permits
597 if (resourceFunction == null) {
599 "Could not locate matching function for ARP value. Function: "
600 + valueSpec.getMatchFunctionIdentifier().toString());
604 } catch (ArpException e) {
605 log.error("Error while attempting to find referenced matching function for ARP values: " + e);
610 if (valueSpec.getRelease().equals("permit")
611 && resourceFunction.match(valueSpec.getValue(), value)) {
614 } catch (MatchingException e) {
615 log.error("Could not apply referenced matching function to ARP value: " + e);
622 void setAnyValuePermit(boolean b) {
625 anyValueRelease = "permit";
626 Iterator iterator = values.iterator();
627 HashSet permittedValues = new HashSet();
628 while (iterator.hasNext()) {
629 AttributeValue value = (AttributeValue) iterator.next();
630 if (value.getRelease().equals("permit")) {
631 permittedValues.add(value);
634 values.removeAll(permittedValues);
636 if (anyValueRelease.equals("permit") && anyValue) {
645 AttributeValue[] getValues() {
646 return (AttributeValue[]) values.toArray(new AttributeValue[0]);
649 void addValue(AttributeValue value) {
650 if (denyAnyValue()) {
653 if (releaseAnyValue() && value.getRelease().equals("permit")) {
660 * Unmarshalls an <code>Attribute</code> into an xml <code>Element</code>.
661 * @return the xml <code>Element</code>
664 Element unmarshall() throws ArpMarshallingException {
667 Document placeHolder = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
668 Element attributeNode = placeHolder.createElementNS(Arp.arpNamespace, "Attribute");
670 attributeNode.setAttributeNS(Arp.arpNamespace, "name", name.toString());
672 if (identifier != null) {
673 attributeNode.setAttributeNS(Arp.arpNamespace, "identifier", identifier.toString());
677 Element anyValueNode = placeHolder.createElementNS(Arp.arpNamespace, "AnyValue");
678 anyValueNode.setAttributeNS(Arp.arpNamespace, "release", anyValueRelease);
679 attributeNode.appendChild(anyValueNode);
681 Iterator valueIterator = values.iterator();
682 while (valueIterator.hasNext()) {
683 AttributeValue value = (AttributeValue) valueIterator.next();
684 Element valueNode = placeHolder.createElementNS(Arp.arpNamespace, "Value");
685 valueNode.setAttributeNS(Arp.arpNamespace, "release", value.getRelease());
687 .getMatchFunctionIdentifier()
688 .equals(new URI("urn:mace:shibboleth:arp:matchFunction:stringValue"))) {
689 valueNode.setAttributeNS(
692 value.getMatchFunctionIdentifier().toString());
694 Text valueTextNode = placeHolder.createTextNode(value.getValue());
695 valueNode.appendChild(valueTextNode);
696 attributeNode.appendChild(valueNode);
698 return attributeNode;
700 } catch (URISyntaxException e) {
701 log.error("Encountered a problem unmarshalling an ARP Rule Resource: " + e);
702 throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP Rule Resource.");
703 } catch (ParserConfigurationException e) {
704 log.error("Encountered a problem unmarshalling an ARP Rule: " + e);
705 throw new ArpMarshallingException("Encountered a problem unmarshalling an ARP Rule.");
710 * Creates an ARP Rule Attribute from an xml representation.
711 * @param element the xml <code>Element</code> containing the ARP Rule.
713 void marshall(Element element) throws ArpMarshallingException {
714 //Make sure we are dealing with an Attribute
715 if (!element.getTagName().equals("Attribute")) {
716 log.error("Element data does not represent an ARP Rule Target.");
717 throw new ArpMarshallingException("Element data does not represent an ARP Rule target.");
720 //Get the attribute identifier
722 if (element.hasAttribute("identifier")) {
723 identifier = new URI(element.getAttribute("identifier"));
725 } catch (URISyntaxException e) {
726 log.error("Attribute not identified by a proper URI: " + e);
727 throw new ArpMarshallingException("Attribute not identified by a proper URI.");
730 //Get the attribute name
732 if (element.hasAttribute("name")) {
733 name = new URI(element.getAttribute("name"));
735 log.error("Attribute name not specified.");
736 throw new ArpMarshallingException("Attribute name not specified.");
738 } catch (URISyntaxException e) {
739 log.error("Attribute name not identified by a proper URI: " + e);
740 throw new ArpMarshallingException("Attribute name not identified by a proper URI.");
743 //Handle <AnyValue/> definitions
744 NodeList anyValueNodeList = element.getElementsByTagNameNS(Arp.arpNamespace, "AnyValue");
745 if (anyValueNodeList.getLength() == 1) {
747 if (((Element) anyValueNodeList.item(0)).hasAttribute("release")) {
748 anyValueRelease = ((Element) anyValueNodeList.item(0)).getAttribute("release");
752 //Handle Value definitions
753 if (!denyAnyValue()) {
754 NodeList valueNodeList = element.getElementsByTagNameNS(Arp.arpNamespace, "Value");
755 for (int i = 0; valueNodeList.getLength() > i; i++) {
756 String release = null;
758 URI matchFunctionIdentifier = null;
759 if (((Element) valueNodeList.item(i)).hasAttribute("release")) {
760 release = ((Element) valueNodeList.item(i)).getAttribute("release");
763 //Grab the match function
765 if (((Element) valueNodeList.item(i)).hasAttribute("matchFunction")) {
766 matchFunctionIdentifier =
767 new URI(((Element) valueNodeList.item(i)).getAttribute("matchFunction"));
769 } catch (URISyntaxException e) {
771 "ARP match function not identified by a proper URI: "
772 + ((Element) valueNodeList.item(i)).getAttribute("matchFunction"));
773 throw new ArpMarshallingException("ARP match function not identified by a proper URI.");
776 if (((Element) valueNodeList.item(i)).hasChildNodes()
777 && ((Element) valueNodeList.item(i)).getFirstChild().getNodeType() == Node.TEXT_NODE) {
778 value = ((CharacterData) ((Element) valueNodeList.item(i)).getFirstChild()).getData();
780 if (releaseAnyValue() && release.equals("permit")) {
783 AttributeValue aValue = new AttributeValue(release, matchFunctionIdentifier, value);
790 class AttributeValue {
792 private String release = "permit";
793 private String value;
794 private URI matchFunctionIdentifier;
796 AttributeValue(String release, URI matchFunctionIdentifier, String value) throws ArpMarshallingException {
799 if (matchFunctionIdentifier != null) {
800 this.matchFunctionIdentifier = matchFunctionIdentifier;
803 matchFunctionIdentifier = new URI("urn:mace:shibboleth:arp:matchFunction:stringValue");
804 } catch (URISyntaxException e) {
805 throw new ArpMarshallingException("ARP Engine internal error: could not set default matching function for attribute value.");
810 String getRelease() {
818 URI getMatchFunctionIdentifier() {
819 return matchFunctionIdentifier;
822 void setRelease(String release) {
823 if (release == null) {
826 if (release.equals("permit") || release.equals("deny")) {
827 this.release = release;
831 void setValue(String value) {