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