1 // Attributes2Impl.java - extended AttributesImpl
2 // http://www.saxproject.org
3 // Public Domain: no warranty.
4 // $Id: Attributes2Impl.java,v 1.5 2004/03/08 13:01:01 dmegginson Exp $
6 package org.xml.sax.ext;
8 import org.xml.sax.Attributes;
9 import org.xml.sax.helpers.AttributesImpl;
13 * SAX2 extension helper for additional Attributes information,
14 * implementing the {@link Attributes2} interface.
17 * <em>This module, both source code and documentation, is in the
18 * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
21 * <p>This is not part of core-only SAX2 distributions.</p>
23 * <p>The <em>specified</em> flag for each attribute will always
24 * be true, unless it has been set to false in the copy constructor
25 * or using {@link #setSpecified}.
26 * Similarly, the <em>declared</em> flag for each attribute will
27 * always be false, except for defaulted attributes (<em>specified</em>
28 * is false), non-CDATA attributes, or when it is set to true using
29 * {@link #setDeclared}.
30 * If you change an attribute's type by hand, you may need to modify
31 * its <em>declared</em> flag to match.
34 * @since SAX 2.0 (extensions 1.1 alpha)
35 * @author David Brownell
38 public class Attributes2Impl extends AttributesImpl implements Attributes2
40 private boolean declared [];
41 private boolean specified [];
45 * Construct a new, empty Attributes2Impl object.
47 public Attributes2Impl () { }
51 * Copy an existing Attributes or Attributes2 object.
52 * If the object implements Attributes2, values of the
53 * <em>specified</em> and <em>declared</em> flags for each
54 * attribute are copied.
55 * Otherwise the flag values are defaulted to assume no DTD was used,
56 * unless there is evidence to the contrary (such as attributes with
57 * type other than CDATA, which must have been <em>declared</em>).
59 * <p>This constructor is especially useful inside a
60 * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p>
62 * @param atts The existing Attributes object.
64 public Attributes2Impl (Attributes atts)
70 ////////////////////////////////////////////////////////////////////
71 // Implementation of Attributes2
72 ////////////////////////////////////////////////////////////////////
76 * Returns the current value of the attribute's "declared" flag.
78 // javadoc mostly from interface
80 public boolean isDeclared (int index)
82 if (index < 0 || index >= getLength ())
83 throw new ArrayIndexOutOfBoundsException (
84 "No attribute at index: " + index);
85 return declared [index];
90 * Returns the current value of the attribute's "declared" flag.
92 // javadoc mostly from interface
94 public boolean isDeclared (String uri, String localName)
96 int index = getIndex (uri, localName);
99 throw new IllegalArgumentException (
100 "No such attribute: local=" + localName
101 + ", namespace=" + uri);
102 return declared [index];
107 * Returns the current value of the attribute's "declared" flag.
109 // javadoc mostly from interface
111 public boolean isDeclared (String qName)
113 int index = getIndex (qName);
116 throw new IllegalArgumentException (
117 "No such attribute: " + qName);
118 return declared [index];
123 * Returns the current value of an attribute's "specified" flag.
125 * @param index The attribute index (zero-based).
126 * @return current flag value
127 * @exception java.lang.ArrayIndexOutOfBoundsException When the
128 * supplied index does not identify an attribute.
131 public boolean isSpecified (int index)
133 if (index < 0 || index >= getLength ())
134 throw new ArrayIndexOutOfBoundsException (
135 "No attribute at index: " + index);
136 return specified [index];
141 * Returns the current value of an attribute's "specified" flag.
143 * @param uri The Namespace URI, or the empty string if
144 * the name has no Namespace URI.
145 * @param localName The attribute's local name.
146 * @return current flag value
147 * @exception java.lang.IllegalArgumentException When the
148 * supplied names do not identify an attribute.
151 public boolean isSpecified (String uri, String localName)
153 int index = getIndex (uri, localName);
156 throw new IllegalArgumentException (
157 "No such attribute: local=" + localName
158 + ", namespace=" + uri);
159 return specified [index];
164 * Returns the current value of an attribute's "specified" flag.
166 * @param qName The XML qualified (prefixed) name.
167 * @return current flag value
168 * @exception java.lang.IllegalArgumentException When the
169 * supplied name does not identify an attribute.
172 public boolean isSpecified (String qName)
174 int index = getIndex (qName);
177 throw new IllegalArgumentException (
178 "No such attribute: " + qName);
179 return specified [index];
183 ////////////////////////////////////////////////////////////////////
185 ////////////////////////////////////////////////////////////////////
189 * Copy an entire Attributes object. The "specified" flags are
190 * assigned as true, and "declared" flags as false (except when
191 * an attribute's type is not CDATA),
192 * unless the object is an Attributes2 object.
193 * In that case those flag values are all copied.
195 * @see AttributesImpl#setAttributes
198 public void setAttributes (Attributes atts)
200 int length = atts.getLength ();
202 super.setAttributes (atts);
203 declared = new boolean [length];
204 specified = new boolean [length];
206 if (atts instanceof Attributes2) {
207 Attributes2 a2 = (Attributes2) atts;
208 for (int i = 0; i < length; i++) {
209 declared [i] = a2.isDeclared (i);
210 specified [i] = a2.isSpecified (i);
213 for (int i = 0; i < length; i++) {
214 declared [i] = !"CDATA".equals (atts.getType (i));
215 specified [i] = true;
222 * Add an attribute to the end of the list, setting its
223 * "specified" flag to true. To set that flag's value
224 * to false, use {@link #setSpecified}.
226 * <p>Unless the attribute <em>type</em> is CDATA, this attribute
227 * is marked as being declared in the DTD. To set that flag's value
228 * to true for CDATA attributes, use {@link #setDeclared}.
230 * @see AttributesImpl#addAttribute
233 public void addAttribute (String uri, String localName, String qName,
234 String type, String value)
236 super.addAttribute (uri, localName, qName, type, value);
238 int length = getLength ();
240 if (length < specified.length) {
243 newFlags = new boolean [length];
244 System.arraycopy (declared, 0, newFlags, 0, declared.length);
247 newFlags = new boolean [length];
248 System.arraycopy (specified, 0, newFlags, 0, specified.length);
249 specified = newFlags;
252 specified [length - 1] = true;
253 declared [length - 1] = !"CDATA".equals (type);
257 // javadoc entirely from superclass
259 public void removeAttribute (int index)
261 int origMax = getLength () - 1;
263 super.removeAttribute (index);
264 if (index != origMax) {
265 System.arraycopy (declared, index + 1, declared, index,
267 System.arraycopy (specified, index + 1, specified, index,
274 * Assign a value to the "declared" flag of a specific attribute.
275 * This is normally needed only for attributes of type CDATA,
276 * including attributes whose type is changed to or from CDATA.
278 * @param index The index of the attribute (zero-based).
279 * @param value The desired flag value.
280 * @exception java.lang.ArrayIndexOutOfBoundsException When the
281 * supplied index does not identify an attribute.
284 public void setDeclared (int index, boolean value)
286 if (index < 0 || index >= getLength ())
287 throw new ArrayIndexOutOfBoundsException (
288 "No attribute at index: " + index);
289 declared [index] = value;
294 * Assign a value to the "specified" flag of a specific attribute.
295 * This is the only way this flag can be cleared, except clearing
296 * by initialization with the copy constructor.
298 * @param index The index of the attribute (zero-based).
299 * @param value The desired flag value.
300 * @exception java.lang.ArrayIndexOutOfBoundsException When the
301 * supplied index does not identify an attribute.
303 public void setSpecified (int index, boolean value)
305 if (index < 0 || index >= getLength ())
306 throw new ArrayIndexOutOfBoundsException (
307 "No attribute at index: " + index);
308 specified [index] = value;