ced4da01ef7e870c7b5d391364debd150812225e
[java-idp.git] / src / edu / internet2 / middleware / eduPerson / ScopedAttribute.java
1 package edu.internet2.middleware.eduPerson;
2
3 import java.util.Iterator;
4 import java.util.Vector;
5 import org.opensaml.*;
6 import org.w3c.dom.*;
7
8 /**
9  *  Basic implementation of a scoped, eduPerson SAML attribute
10  *
11  * @author     Scott Cantor
12  * @created    May 9, 2002
13  */
14 public class ScopedAttribute extends SAMLAttribute
15 {
16     /**  Default attribute scope */
17     protected String defaultScope = null;
18
19     /**  Scopes of the attribute values */
20     protected Vector scopes = new Vector();
21
22     /**
23      *  Constructor for the ScopedAttribute object
24      *
25      * @param  name               Name of attribute
26      * @param  namespace          Namespace/qualifier of attribute
27      * @param  type               The schema type of attribute value(s)
28      * @param  lifetime           Effective lifetime of attribute's value(s) in
29      *      seconds (0 means infinite)
30      * @param  values             An array of attribute values
31      * @param  defaultScope       The default scope to apply for values
32      * @param  scopes             Scopes of the attribute values
33      * @exception  SAMLException  Thrown if attribute cannot be built from the
34      *      supplied information
35      */
36     public ScopedAttribute(String name, String namespace, QName type, long lifetime, Object[] values,
37                            String defaultScope, String[] scopes)
38         throws SAMLException
39     {
40         super(name, namespace, type, lifetime, values);
41         this.defaultScope = defaultScope;
42
43         for (int i = 0; scopes != null && i < scopes.length; i++)
44             this.scopes.add(scopes[i]);
45     }
46
47     /**
48      *  Reconstructs and validates an attribute from a DOM tree<P>
49      *
50      *  Overrides the basic implementation to handle the same simple types, but
51      *  also picks up scope.
52      *
53      * @param  e                  A DOM Attribute element
54      * @exception  SAMLException  Thrown if the attribute cannot be constructed
55      */
56     public ScopedAttribute(Element e)
57         throws SAMLException
58     {
59         super(e);
60
61         // Default scope comes from subject.
62         NodeList nlist = ((Element)e.getParentNode()).getElementsByTagNameNS(org.opensaml.XML.SAML_NS, "NameIdentifier");
63         if (nlist.getLength() != 1)
64             throw new InvalidAssertionException(SAMLException.RESPONDER, "ScopedAttribute() can't find saml:NameIdentifier in enclosing statement");
65         defaultScope = ((Element)nlist.item(0)).getAttributeNS(null, "NameQualifier");
66     }
67
68     /**
69      *  Gets the values of the SAML Attribute, serialized as strings with the
70      *  effective scope appended
71      *
72      * @return    The array of values
73      */
74     public Object[] getValues()
75     {
76         if (values == null)
77             return null;
78
79         Object[] bufs = new Object[values.size()];
80         for (int i = 0; i < values.size(); i++)
81         {
82             if (values.get(i) != null)
83             {
84                 if (scopes != null && i < scopes.size() && scopes.get(i) != null)
85                     bufs[i] = values.get(i).toString() + "@" + scopes.get(i);
86                 else
87                     bufs[i] = values.get(i).toString() + "@" + defaultScope;
88             }
89         }
90         return bufs;
91     }
92
93     /**
94      *  Attribute acceptance hook used while consuming attributes from an
95      *  assertion. Base class simply accepts anything. Override for desired
96      *  behavior.
97      *
98      * @param  e  An AttributeValue element to check
99      * @return    true iff the value is deemed acceptable
100      */
101     public boolean accept(Element e)
102     {
103         return true;
104     }
105
106     /**
107      *  Adds a value to the state of the SAML Attribute<P>
108      *
109      *  This class supports a simple text node content model with a Scope
110      *  attribute
111      *
112      * @param  e  The AttributeValue element containing the value to add
113      * @return    true iff the value was understood
114      */
115     public boolean addValue(Element e)
116     {
117         if (super.addValue(e))
118         {
119             scopes.add(e.getAttributeNS(null,"Scope"));
120             return true;
121         }
122         return false;
123     }
124
125     /**
126      *  Overridden method to return a DOM tree representing the attribute<P>
127      *
128      *  Because attributes are generalized, this base method only handles simple
129      *  attributes whose values are of uniform simple type and expressed in the
130      *  DOM as a single text node within the AttributeValue element(s). The
131      *  values are serialized using the toString() method.<P>
132      *
133      *  SAML applications should override this class and reimplement or
134      *  supplement this method to handle other requirements.
135      *
136      * @param  doc  A Document object to use in manufacturing the tree
137      * @return      Root "Attribute" element of a DOM tree
138      */
139     public Node toDOM(Document doc)
140     {
141         super.toDOM(doc);
142
143         NodeList nlist = ((Element)root).getElementsByTagNameNS(org.opensaml.XML.SAML_NS, "AttributeValue");
144         for (int i = 0; i < nlist.getLength(); i++)
145         {
146             ((Element)nlist.item(i)).removeAttributeNS(null, "Scope");
147             String scope=(i<scopes.size() ? scopes.get(i).toString() : null);
148             if (scope != null && scope.length()>0 && !scope.equals(defaultScope))
149                 ((Element)nlist.item(i)).setAttributeNS(null, "Scope", scope);
150         }
151
152         return root;
153     }
154 }
155