View Javadoc
1   /*
2    * Redistribution and use of this software and associated documentation ("Software"), with or
3    * without modification, are permitted provided that the following conditions are met:
4    *
5    * 1. Redistributions of source code must retain copyright statements and notices. Redistributions
6    * must also contain a copy of this document.
7    *
8    * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
9    * conditions and the following disclaimer in the documentation and/or other materials provided with
10   * the distribution.
11   *
12   * 3. The name "Exolab" must not be used to endorse or promote products derived from this Software
13   * without prior written permission of Intalio, Inc. For written permission, please contact
14   * info@exolab.org.
15   *
16   * 4. Products derived from this Software may not be called "Exolab" nor may "Exolab" appear in
17   * their names without prior written permission of Intalio, Inc. Exolab is a registered trademark of
18   * Intalio, Inc.
19   *
20   * 5. Due credit should be given to the Exolab Project (http://www.exolab.org/).
21   *
22   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR
23   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTALIO, INC. OR ITS
25   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
29   * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30   *
31   * Copyright 2001-2002 (C) Intalio, Inc. All Rights Reserved.
32   *
33   * $Id$
34   */
35  package org.exolab.castor.xml.util;
36  
37  import java.util.ArrayList;
38  import java.util.List;
39  
40  import org.exolab.castor.xml.AttributeSet;
41  
42  /**
43   * The default implementation of AttributeSet used by the Marshalling Framework.
44   *
45   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
46   * @version $Revision$ $Date: 2006-04-13 06:47:36 -0600 (Thu, 13 Apr 2006) $
47   */
48  public class AttributeSetImpl implements AttributeSet {
49  
50    /**
51     * The XML namespace declaration prefix. It is an error for an attribute name to be equal to this
52     * value.
53     */
54    public static final String XMLNS = "xmlns";
55  
56    private static final String EMPTY_STRING = "";
57  
58    /**
59     * The list of attributes in this AttributeSet.
60     */
61    private List<Attribute> _attributes = new ArrayList<Attribute>();
62  
63  
64    /**
65     * Creates a new AttributeSetImpl.
66     */
67    public AttributeSetImpl() {
68      super();
69    }
70  
71    /**
72     * Creates a new AttributeSetImpl.
73     *
74     * @param size the default size for this AttributeSetImpl
75     */
76    public AttributeSetImpl(int size) {
77      if (size < 0) {
78        String err = "size cannot be less than zero";
79        throw new IllegalArgumentException(err);
80      }
81    }
82  
83    /**
84     * Removes all Attributes in this AttributeSetImpl
85     */
86    public void clear() {
87      _attributes.clear();
88    }
89  
90    /**
91     * Returns the index of the attribute associated with the given name and namespace.
92     *
93     * @param name the name of the attribute whose value should be returned.
94     * @param namespace the namespace of the attribute
95     * @return the index of the attribute, or -1 if not found.
96     */
97    public int getIndex(String name, String namespace) {
98      if (namespace == null) {
99        namespace = EMPTY_STRING;
100     }
101 
102     for (int i = 0; i < _attributes.size(); i++) {
103       Attribute attr = _attributes.get(i);
104       if (namespace.equals(attr.namespace)) {
105         if (attr.name.equals(name)) {
106           return i;
107         }
108       }
109     }
110     return -1;
111   }
112 
113   /**
114    * Returns the name of the attribute located at the given index.
115    *
116    * @param index the index of the attribute whose name should be returned.
117    * @return the name of the attribute located at the given index.
118    */
119   public String getName(final int index) {
120     Attribute attr = _attributes.get(index);
121     return attr.name;
122   }
123 
124   /**
125    * Returns the namespace of the attribute located at the given index.
126    *
127    * @return the namespace of the attribute located at the given index.
128    */
129   public String getNamespace(final int index) {
130     Attribute attr = _attributes.get(index);
131     return attr.namespace;
132   }
133 
134   /**
135    * Returns the number of Attributes within this AttributeSet.
136    *
137    * @return the number of Attributes within this AttributeSet.
138    */
139   public int getSize() {
140     return _attributes.size();
141   }
142 
143   /**
144    * Returns the value of the attribute located at the given index within this AttributeSet.
145    *
146    * @param index the index of the attribute whose value should be returned.
147    */
148   public String getValue(int index) {
149     Attribute attr = _attributes.get(index);
150     return attr.value;
151   }
152 
153   /**
154    * Returns the value of the attribute associated with the given name. This method is equivalent to
155    * call #getValue(name, null);
156    *
157    * @param name the name of the attribute whose value should be returned.
158    */
159   public String getValue(String name) {
160     if (name == null) {
161       return null;
162     }
163     Attribute attr = getAttribute(name, "");
164     if (attr != null) {
165       return attr.value;
166     }
167     return null;
168   }
169 
170   /**
171    * Returns the value of the attribute associated with the given name. This method is equivalent to
172    * call #getValue(name, null);
173    *
174    * @param name the name of the attribute whose value should be returned.
175    * @param namespace the namespace of the attribute
176    */
177   public String getValue(String name, String namespace) {
178     if (name == null) {
179       return null;
180     }
181     Attribute attr = getAttribute(name, namespace);
182     if (attr != null) {
183       return attr.value;
184     }
185     return null;
186   }
187 
188   /**
189    * Adds or replaces the attribute with the given name. No namespace is associated with the
190    * attribute.
191    *
192    * @param name the name of the attribute
193    * @param value the attribute value.
194    */
195   public void setAttribute(String name, String value) {
196     setAttribute(name, value, EMPTY_STRING);
197   }
198 
199   /**
200    * Adds or replaces the attribute with the given name. No namespace is associated with the
201    * attribute.
202    *
203    * @param name the name of the attribute
204    * @param value the attribute value.
205    */
206   public void setAttribute(String name, String value, String namespace) {
207     if ((name == null) || (name.length() == 0))
208       throw new IllegalArgumentException("name must not be null");
209 
210     if (XMLNS.equals(name)) {
211       String err = "'xmlns' is a reserved word for use with XML "
212           + "namespace declarations. It may not be used as an " + "attribute name.";
213       throw new IllegalArgumentException(err);
214     }
215 
216     if (namespace == null)
217       namespace = EMPTY_STRING;
218 
219     Attribute attr = getAttribute(name, namespace);
220     if (attr == null) {
221       _attributes.add(new Attribute(name, value, namespace));
222     } else {
223       attr.value = value;
224     }
225 
226   }
227 
228   private Attribute getAttribute(String name, String namespace) {
229     if (namespace == null) {
230       namespace = EMPTY_STRING;
231     }
232     for (int i = 0; i < _attributes.size(); i++) {
233       Attribute attr = _attributes.get(i);
234       if (namespace.equals(attr.namespace)) {
235         if (attr.name.equals(name)) {
236           return attr;
237         }
238       }
239     }
240     return null;
241   }
242 
243   /**
244    * A representation of an Attribute
245    */
246   class Attribute {
247 
248     String name = null;
249     String value = null;
250     String namespace = null;
251 
252     public Attribute() {
253       super();
254     }
255 
256     public Attribute(String name, String value, String namespace) {
257       this.name = name;
258       this.value = value;
259       this.namespace = namespace;
260     }
261 
262   }
263 
264 }