1 /* 2 * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 // Attributes2Impl.java - extended AttributesImpl 27 // http://www.saxproject.org 28 // Public Domain: no warranty. 29 // $Id: Attributes2Impl.java,v 1.3 2005/02/24 11:20:18 gg156739 Exp $ 30 31 package org.xml.sax.ext; 32 33 import org.xml.sax.Attributes; 34 import org.xml.sax.helpers.AttributesImpl; 35 36 37 /** 38 * SAX2 extension helper for additional Attributes information, 39 * implementing the {@link Attributes2} interface. 40 * 41 * <blockquote> 42 * <em>This module, both source code and documentation, is in the 43 * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> 44 * </blockquote> 45 * 46 * <p>This is not part of core-only SAX2 distributions.</p> 47 * 48 * <p>The <em>specified</em> flag for each attribute will always 49 * be true, unless it has been set to false in the copy constructor 50 * or using {@link #setSpecified}. 51 * Similarly, the <em>declared</em> flag for each attribute will 52 * always be false, except for defaulted attributes (<em>specified</em> 53 * is false), non-CDATA attributes, or when it is set to true using 54 * {@link #setDeclared}. 55 * If you change an attribute's type by hand, you may need to modify 56 * its <em>declared</em> flag to match. 57 * </p> 58 * 59 * @since 1.5, SAX 2.0 (extensions 1.1 alpha) 60 * @author David Brownell 61 */ 62 public class Attributes2Impl extends AttributesImpl implements Attributes2 63 { 64 private boolean declared []; 65 private boolean specified []; 66 67 68 /** 69 * Construct a new, empty Attributes2Impl object. 70 */ 71 public Attributes2Impl () { 72 specified = null; 73 declared = null; 74 } 75 76 77 /** 78 * Copy an existing Attributes or Attributes2 object. 79 * If the object implements Attributes2, values of the 80 * <em>specified</em> and <em>declared</em> flags for each 81 * attribute are copied. 82 * Otherwise the flag values are defaulted to assume no DTD was used, 83 * unless there is evidence to the contrary (such as attributes with 84 * type other than CDATA, which must have been <em>declared</em>). 85 * 86 * <p>This constructor is especially useful inside a 87 * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p> 88 * 89 * @param atts The existing Attributes object. 90 */ 91 public Attributes2Impl (Attributes atts) 92 { 93 super (atts); 94 } 95 96 97 //////////////////////////////////////////////////////////////////// 98 // Implementation of Attributes2 99 //////////////////////////////////////////////////////////////////// 100 101 102 /** 103 * Returns the current value of the attribute's "declared" flag. 104 */ 105 // javadoc mostly from interface 106 public boolean isDeclared (int index) 107 { 108 if (index < 0 || index >= getLength ()) 109 throw new ArrayIndexOutOfBoundsException ( 110 "No attribute at index: " + index); 111 return declared [index]; 112 } 113 114 115 /** 116 * Returns the current value of the attribute's "declared" flag. 117 */ 118 // javadoc mostly from interface 119 public boolean isDeclared (String uri, String localName) 120 { 121 int index = getIndex (uri, localName); 122 123 if (index < 0) 124 throw new IllegalArgumentException ( 125 "No such attribute: local=" + localName 126 + ", namespace=" + uri); 127 return declared [index]; 128 } 129 130 131 /** 132 * Returns the current value of the attribute's "declared" flag. 133 */ 134 // javadoc mostly from interface 135 public boolean isDeclared (String qName) 136 { 137 int index = getIndex (qName); 138 139 if (index < 0) 140 throw new IllegalArgumentException ( 141 "No such attribute: " + qName); 142 return declared [index]; 143 } 144 145 146 /** 147 * Returns the current value of an attribute's "specified" flag. 148 * 149 * @param index The attribute index (zero-based). 150 * @return current flag value 151 * @exception java.lang.ArrayIndexOutOfBoundsException When the 152 * supplied index does not identify an attribute. 153 */ 154 public boolean isSpecified (int index) 155 { 156 if (index < 0 || index >= getLength ()) 157 throw new ArrayIndexOutOfBoundsException ( 158 "No attribute at index: " + index); 159 return specified [index]; 160 } 161 162 163 /** 164 * Returns the current value of an attribute's "specified" flag. 165 * 166 * @param uri The Namespace URI, or the empty string if 167 * the name has no Namespace URI. 168 * @param localName The attribute's local name. 169 * @return current flag value 170 * @exception java.lang.IllegalArgumentException When the 171 * supplied names do not identify an attribute. 172 */ 173 public boolean isSpecified (String uri, String localName) 174 { 175 int index = getIndex (uri, localName); 176 177 if (index < 0) 178 throw new IllegalArgumentException ( 179 "No such attribute: local=" + localName 180 + ", namespace=" + uri); 181 return specified [index]; 182 } 183 184 185 /** 186 * Returns the current value of an attribute's "specified" flag. 187 * 188 * @param qName The XML qualified (prefixed) name. 189 * @return current flag value 190 * @exception java.lang.IllegalArgumentException When the 191 * supplied name does not identify an attribute. 192 */ 193 public boolean isSpecified (String qName) 194 { 195 int index = getIndex (qName); 196 197 if (index < 0) 198 throw new IllegalArgumentException ( 199 "No such attribute: " + qName); 200 return specified [index]; 201 } 202 203 204 //////////////////////////////////////////////////////////////////// 205 // Manipulators 206 //////////////////////////////////////////////////////////////////// 207 208 209 /** 210 * Copy an entire Attributes object. The "specified" flags are 211 * assigned as true, and "declared" flags as false (except when 212 * an attribute's type is not CDATA), 213 * unless the object is an Attributes2 object. 214 * In that case those flag values are all copied. 215 * 216 * @see AttributesImpl#setAttributes 217 */ 218 public void setAttributes (Attributes atts) 219 { 220 int length = atts.getLength (); 221 222 super.setAttributes (atts); 223 declared = new boolean [length]; 224 specified = new boolean [length]; 225 226 if (atts instanceof Attributes2) { 227 Attributes2 a2 = (Attributes2) atts; 228 for (int i = 0; i < length; i++) { 229 declared [i] = a2.isDeclared (i); 230 specified [i] = a2.isSpecified (i); 231 } 232 } else { 233 for (int i = 0; i < length; i++) { 234 declared [i] = !"CDATA".equals (atts.getType (i)); 235 specified [i] = true; 236 } 237 } 238 } 239 240 241 /** 242 * Add an attribute to the end of the list, setting its 243 * "specified" flag to true. To set that flag's value 244 * to false, use {@link #setSpecified}. 245 * 246 * <p>Unless the attribute <em>type</em> is CDATA, this attribute 247 * is marked as being declared in the DTD. To set that flag's value 248 * to true for CDATA attributes, use {@link #setDeclared}. 249 * 250 * @see AttributesImpl#addAttribute 251 */ 252 public void addAttribute (String uri, String localName, String qName, 253 String type, String value) 254 { 255 super.addAttribute (uri, localName, qName, type, value); 256 257 258 int length = getLength (); 259 if(specified==null) 260 { 261 specified = new boolean[length]; 262 declared = new boolean[length]; 263 } else if (length > specified.length) { 264 boolean newFlags []; 265 266 newFlags = new boolean [length]; 267 System.arraycopy (declared, 0, newFlags, 0, declared.length); 268 declared = newFlags; 269 270 newFlags = new boolean [length]; 271 System.arraycopy (specified, 0, newFlags, 0, specified.length); 272 specified = newFlags; 273 } 274 275 specified [length - 1] = true; 276 declared [length - 1] = !"CDATA".equals (type); 277 } 278 279 280 // javadoc entirely from superclass 281 public void removeAttribute (int index) 282 { 283 int origMax = getLength () - 1; 284 285 super.removeAttribute (index); 286 if (index != origMax) { 287 System.arraycopy (declared, index + 1, declared, index, 288 origMax - index); 289 System.arraycopy (specified, index + 1, specified, index, 290 origMax - index); 291 } 292 } 293 294 295 /** 296 * Assign a value to the "declared" flag of a specific attribute. 297 * This is normally needed only for attributes of type CDATA, 298 * including attributes whose type is changed to or from CDATA. 299 * 300 * @param index The index of the attribute (zero-based). 301 * @param value The desired flag value. 302 * @exception java.lang.ArrayIndexOutOfBoundsException When the 303 * supplied index does not identify an attribute. 304 * @see #setType 305 */ 306 public void setDeclared (int index, boolean value) 307 { 308 if (index < 0 || index >= getLength ()) 309 throw new ArrayIndexOutOfBoundsException ( 310 "No attribute at index: " + index); 311 declared [index] = value; 312 } 313 314 315 /** 316 * Assign a value to the "specified" flag of a specific attribute. 317 * This is the only way this flag can be cleared, except clearing 318 * by initialization with the copy constructor. 319 * 320 * @param index The index of the attribute (zero-based). 321 * @param value The desired flag value. 322 * @exception java.lang.ArrayIndexOutOfBoundsException When the 323 * supplied index does not identify an attribute. 324 */ 325 public void setSpecified (int index, boolean value) 326 { 327 if (index < 0 || index >= getLength ()) 328 throw new ArrayIndexOutOfBoundsException ( 329 "No attribute at index: " + index); 330 specified [index] = value; 331 } 332 }