Implement equals() in default ValueHandler to fix a testcase.
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / aa / AAAttribute.java
1 /* 
2  * The Shibboleth License, Version 1. 
3  * Copyright (c) 2002 
4  * University Corporation for Advanced Internet Development, Inc. 
5  * All rights reserved
6  * 
7  * 
8  * Redistribution and use in source and binary forms, with or without 
9  * modification, are permitted provided that the following conditions are met:
10  * 
11  * Redistributions of source code must retain the above copyright notice, this 
12  * list of conditions and the following disclaimer.
13  * 
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.
22  * 
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
28  * 
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.
33  * 
34  * 
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.
48  */
49  
50 package edu.internet2.middleware.shibboleth.aa;
51
52
53 import java.util.Arrays;
54 import java.util.Collection;
55 import java.util.Iterator;
56
57 import org.apache.log4j.Logger;
58 import org.opensaml.QName;
59 import org.opensaml.SAMLAttribute;
60 import org.opensaml.SAMLException;
61 import org.opensaml.XML;
62 import org.w3c.dom.Document;
63 import org.w3c.dom.Element;
64 import org.w3c.dom.Node;
65
66 import edu.internet2.middleware.shibboleth.aa.arp.ArpAttribute;
67 import edu.internet2.middleware.shibboleth.aa.attrresolv.ResolverAttribute;
68 import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.ValueHandler;
69 import edu.internet2.middleware.shibboleth.aa.attrresolv.provider.ValueHandlerException;
70 import edu.internet2.middleware.shibboleth.common.Constants;
71
72 /**
73  * An attribute for which the Shibboleth Attribute Authority has been asked
74  * to provide an assertion.
75  * 
76  * @author Walter Hoehn (wassa@columbia.edu)
77  */
78 public class AAAttribute extends SAMLAttribute implements ResolverAttribute, ArpAttribute {
79
80         private static Logger log = Logger.getLogger(AAAttribute.class.getName());
81         private boolean resolved = false;
82         private static long defaultLifetime = 1800000;
83         private ValueHandler valueHandler = new StringValueHandler();
84
85         public AAAttribute(String name) throws SAMLException {
86                 super(
87                         name,
88                         Constants.SHIB_ATTRIBUTE_NAMESPACE_URI,
89                         new QName("urn:mace:shibboleth:1.0", "AttributeValueType"),
90                         defaultLifetime,
91                         null);
92         }
93
94         public AAAttribute(String name, Object[] values) throws SAMLException {
95                 this(name);
96                 setValues(values);
97         }
98         
99         public AAAttribute(String name, Object[] values, ValueHandler handler) throws SAMLException {
100                         this(name);
101                         setValues(values);
102                         registerValueHandler(handler);
103                 }
104
105         public boolean hasValues() {
106                 if (values.isEmpty()) {
107                         return false;
108                 }
109                 return true;
110         }
111
112         public Iterator getValues() {
113                 return valueHandler.getValues(values);
114         }
115
116         public void setValues(Object[] values) {
117                 if (!this.values.isEmpty()) {
118                         this.values.clear();
119                 }
120                 this.values.addAll(Arrays.asList(values));
121         }
122
123         /**
124         * @see java.lang.Object#hashCode()
125         */
126         public int hashCode() {
127                 int code = 0;
128                 if (values != null) {
129                         Iterator iterator = values.iterator();
130                         while (iterator.hasNext()) {
131                                 code += iterator.next().hashCode();
132                         }
133                 }
134                 return name.hashCode() + code;
135         }
136
137         /**
138          * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ArpAttribute#resolved()
139          */
140         public boolean resolved() {
141                 return resolved;
142         }
143
144         /**
145          * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ArpAttribute#setResolved()
146          */
147         public void setResolved() {
148                 resolved = true;
149         }
150
151         /**
152          * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ArpAttribute#resolveFromCached(edu.internet2.middleware.shibboleth.aa.attrresolv.ArpAttribute)
153          */
154         public void resolveFromCached(ResolverAttribute attribute) {
155                 resolved = true;
156                 setLifetime(attribute.getLifetime());
157
158                 if (!this.values.isEmpty()) {
159                         this.values.clear();
160                 }
161                 for (Iterator iterator = attribute.getValues(); iterator.hasNext();) {
162                         values.add(iterator.next());
163                 }
164
165                 registerValueHandler(attribute.getRegisteredValueHandler());
166         }
167
168         public void setLifetime(long lifetime) {
169                 this.lifetime = lifetime;
170
171         }
172
173         public void addValue(Object value) {
174                 values.add(value);
175         }
176
177         /**
178          * @see org.opensaml.SAMLObject#toDOM(org.w3c.dom.Document)
179          */
180         public Node toDOM(Document doc) {
181
182                 Element attributeElement = doc.createElementNS(XML.SAML_NS, "Attribute");
183                 attributeElement.setAttributeNS(null, "AttributeName", name);
184                 attributeElement.setAttributeNS(null, "AttributeNamespace", namespace);
185
186                 for (int i = 0; i < values.size(); i++) {
187
188                         attributeElement.setAttributeNS(XML.XMLNS_NS, "xmlns:typens", type.getNamespaceURI());
189
190                         Element valueElement = doc.createElementNS(XML.SAML_NS, "AttributeValue");
191                         valueElement.setAttributeNS(XML.XSI_NS, "xsi:type", "typens:" + type.getLocalName());
192
193                         try {
194                                 valueHandler.toDOM(valueElement, values.get(i), doc);
195                                 attributeElement.appendChild(valueElement);
196
197                         } catch (ValueHandlerException e) {
198                                 log.error("Value Handler unable to convert value to DOM Node: " + e);
199                         }
200                 }
201                 return attributeElement;
202         }
203
204         /**
205          * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ArpAttribute#registerValueHandler(edu.internet2.middleware.shibboleth.aa.attrresolv.provider.ValueHandler)
206          */
207         public void registerValueHandler(ValueHandler handler) {
208                 valueHandler = handler;
209         }
210
211         /**
212          * @see edu.internet2.middleware.shibboleth.aa.attrresolv.ArpAttribute#getRegisteredValueHandler()
213          */
214         public ValueHandler getRegisteredValueHandler() {
215                 return valueHandler;
216         }
217
218         /**
219          * @see java.lang.Object#equals(java.lang.Object)
220          */
221         public boolean equals(Object object) {
222
223                 if (!(object instanceof AAAttribute)) {System.err.println("hey hey hey");
224                         return false;
225                 }
226                 if (lifetime != ((AAAttribute) object).lifetime) {System.err.println("hey hey hey");
227                         return false;
228                 }
229                 if (name != ((AAAttribute) object).name) {System.err.println("hey hey hey");
230                         return false;
231                 }
232                 if (!valueHandler.equals(((AAAttribute) object).valueHandler)) {System.err.println("hey hey yo");
233                         return false;
234                 }
235                 return values.equals(((AAAttribute) object).values);
236         }
237
238 }
239
240 /**
241  *  Default <code>ValueHandler</code> implementation.  Expects all values to be String objects.
242  *
243  * @author Walter Hoehn (wassa@columbia.edu)
244  */
245 class StringValueHandler implements ValueHandler {
246
247         public void toDOM(Element valueElement, Object value, Document document) {
248                 valueElement.appendChild(document.createTextNode(value.toString()));
249         }
250
251         public Iterator getValues(Collection internalValues) {
252                 return internalValues.iterator();
253         }
254
255         /**
256          * @see java.lang.Object#equals(java.lang.Object)
257          */
258         public boolean equals(Object object) {
259                 if (object instanceof StringValueHandler) {
260                         return true;
261                 }
262                 return false;
263         }
264
265 }
266
267