1 /* 2 * Copyright (c) 1997, 2012, 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 // AttributesImpl.java - default implementation of Attributes. 27 // Written by David Megginson, sax@megginson.com 28 // NO WARRANTY! This class is in the public domain. 29 30 // $Id: AttributesImpl.java,v 1.4 2002/09/29 02:55:48 okajima Exp $ 31 32 //fixed bug at removeAttribute!! by Daisuke OKAJIMA 2002.4.21 33 34 package com.sun.tools.internal.jxc.gen.config; 35 36 import org.xml.sax.Attributes; 37 38 39 /** 40 * Default implementation of the Attributes interface. 41 * 42 * <blockquote> 43 * <em>This module, both source code and documentation, is in the 44 * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> 45 * </blockquote> 46 * 47 * <p>This class provides a default implementation of the SAX2 48 * {@link org.xml.sax.Attributes Attributes} interface, with the 49 * addition of manipulators so that the list can be modified or 50 * reused.</p> 51 * 52 * <p>There are two typical uses of this class:</p> 53 * 54 * <ol> 55 * <li>to take a persistent snapshot of an Attributes object 56 * in a {@link org.xml.sax.ContentHandler#startElement startElement} event; or</li> 57 * <li>to construct or modify an Attributes object in a SAX2 driver or filter.</li> 58 * </ol> 59 * 60 * <p>This class replaces the now-deprecated SAX1 {@link 61 * org.xml.sax.helpers.AttributeListImpl AttributeListImpl} 62 * class; in addition to supporting the updated Attributes 63 * interface rather than the deprecated {@link org.xml.sax.AttributeList 64 * AttributeList} interface, it also includes a much more efficient 65 * implementation using a single array rather than a set of Vectors.</p> 66 * 67 * <p><b> 68 * Auto-generated, do not edit. 69 * </b></p> 70 * @since SAX 2.0 71 * @author David Megginson, 72 * <a href="mailto:sax@megginson.com">sax@megginson.com</a> 73 * @version 2.0 74 */ 75 public class AttributesImpl implements Attributes 76 { 77 78 79 //////////////////////////////////////////////////////////////////// 80 // Constructors. 81 //////////////////////////////////////////////////////////////////// 82 83 84 /** 85 * Construct a new, empty AttributesImpl object. 86 */ 87 public AttributesImpl () 88 { 89 length = 0; 90 data = null; 91 } 92 93 94 /** 95 * Copy an existing Attributes object. 96 * 97 * <p>This constructor is especially useful inside a 98 * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p> 99 * 100 * @param atts The existing Attributes object. 101 */ 102 public AttributesImpl (Attributes atts) 103 { 104 setAttributes(atts); 105 } 106 107 108 109 //////////////////////////////////////////////////////////////////// 110 // Implementation of org.xml.sax.Attributes. 111 //////////////////////////////////////////////////////////////////// 112 113 114 /** 115 * Return the number of attributes in the list. 116 * 117 * @return The number of attributes in the list. 118 * @see org.xml.sax.Attributes#getLength 119 */ 120 public int getLength () 121 { 122 return length; 123 } 124 125 126 /** 127 * Return an attribute's Namespace URI. 128 * 129 * @param index The attribute's index (zero-based). 130 * @return The Namespace URI, the empty string if none is 131 * available, or null if the index is out of range. 132 * @see org.xml.sax.Attributes#getURI 133 */ 134 public String getURI (int index) 135 { 136 if (index >= 0 && index < length) { 137 return data[index*5]; 138 } else { 139 return null; 140 } 141 } 142 143 144 /** 145 * Return an attribute's local name. 146 * 147 * @param index The attribute's index (zero-based). 148 * @return The attribute's local name, the empty string if 149 * none is available, or null if the index if out of range. 150 * @see org.xml.sax.Attributes#getLocalName 151 */ 152 public String getLocalName (int index) 153 { 154 if (index >= 0 && index < length) { 155 return data[index*5+1]; 156 } else { 157 return null; 158 } 159 } 160 161 162 /** 163 * Return an attribute's qualified (prefixed) name. 164 * 165 * @param index The attribute's index (zero-based). 166 * @return The attribute's qualified name, the empty string if 167 * none is available, or null if the index is out of bounds. 168 * @see org.xml.sax.Attributes#getQName 169 */ 170 public String getQName (int index) 171 { 172 if (index >= 0 && index < length) { 173 return data[index*5+2]; 174 } else { 175 return null; 176 } 177 } 178 179 180 /** 181 * Return an attribute's type by index. 182 * 183 * @param index The attribute's index (zero-based). 184 * @return The attribute's type, "CDATA" if the type is unknown, or null 185 * if the index is out of bounds. 186 * @see org.xml.sax.Attributes#getType(int) 187 */ 188 public String getType (int index) 189 { 190 if (index >= 0 && index < length) { 191 return data[index*5+3]; 192 } else { 193 return null; 194 } 195 } 196 197 198 /** 199 * Return an attribute's value by index. 200 * 201 * @param index The attribute's index (zero-based). 202 * @return The attribute's value or null if the index is out of bounds. 203 * @see org.xml.sax.Attributes#getValue(int) 204 */ 205 public String getValue (int index) 206 { 207 if (index >= 0 && index < length) { 208 return data[index*5+4]; 209 } else { 210 return null; 211 } 212 } 213 214 215 /** 216 * Look up an attribute's index by Namespace name. 217 * 218 * <p>In many cases, it will be more efficient to look up the name once and 219 * use the index query methods rather than using the name query methods 220 * repeatedly.</p> 221 * 222 * @param uri The attribute's Namespace URI, or the empty 223 * string if none is available. 224 * @param localName The attribute's local name. 225 * @return The attribute's index, or -1 if none matches. 226 * @see org.xml.sax.Attributes#getIndex(java.lang.String,java.lang.String) 227 */ 228 public int getIndex (String uri, String localName) 229 { 230 int max = length * 5; 231 for (int i = 0; i < max; i += 5) { 232 if (data[i].equals(uri) && data[i+1].equals(localName)) { 233 return i / 5; 234 } 235 } 236 return -1; 237 } 238 239 240 /** 241 * Look up an attribute's index by qualified (prefixed) name. 242 * 243 * @param qName The qualified name. 244 * @return The attribute's index, or -1 if none matches. 245 * @see org.xml.sax.Attributes#getIndex(java.lang.String) 246 */ 247 public int getIndex (String qName) 248 { 249 int max = length * 5; 250 for (int i = 0; i < max; i += 5) { 251 if (data[i+2].equals(qName)) { 252 return i / 5; 253 } 254 } 255 return -1; 256 } 257 258 259 /** 260 * Look up an attribute's type by Namespace-qualified name. 261 * 262 * @param uri The Namespace URI, or the empty string for a name 263 * with no explicit Namespace URI. 264 * @param localName The local name. 265 * @return The attribute's type, or null if there is no 266 * matching attribute. 267 * @see org.xml.sax.Attributes#getType(java.lang.String,java.lang.String) 268 */ 269 public String getType (String uri, String localName) 270 { 271 int max = length * 5; 272 for (int i = 0; i < max; i += 5) { 273 if (data[i].equals(uri) && data[i+1].equals(localName)) { 274 return data[i+3]; 275 } 276 } 277 return null; 278 } 279 280 281 /** 282 * Look up an attribute's type by qualified (prefixed) name. 283 * 284 * @param qName The qualified name. 285 * @return The attribute's type, or null if there is no 286 * matching attribute. 287 * @see org.xml.sax.Attributes#getType(java.lang.String) 288 */ 289 public String getType (String qName) 290 { 291 int max = length * 5; 292 for (int i = 0; i < max; i += 5) { 293 if (data[i+2].equals(qName)) { 294 return data[i+3]; 295 } 296 } 297 return null; 298 } 299 300 301 /** 302 * Look up an attribute's value by Namespace-qualified name. 303 * 304 * @param uri The Namespace URI, or the empty string for a name 305 * with no explicit Namespace URI. 306 * @param localName The local name. 307 * @return The attribute's value, or null if there is no 308 * matching attribute. 309 * @see org.xml.sax.Attributes#getValue(java.lang.String,java.lang.String) 310 */ 311 public String getValue (String uri, String localName) 312 { 313 int max = length * 5; 314 for (int i = 0; i < max; i += 5) { 315 if (data[i].equals(uri) && data[i+1].equals(localName)) { 316 return data[i+4]; 317 } 318 } 319 return null; 320 } 321 322 323 /** 324 * Look up an attribute's value by qualified (prefixed) name. 325 * 326 * @param qName The qualified name. 327 * @return The attribute's value, or null if there is no 328 * matching attribute. 329 * @see org.xml.sax.Attributes#getValue(java.lang.String) 330 */ 331 public String getValue (String qName) 332 { 333 int max = length * 5; 334 for (int i = 0; i < max; i += 5) { 335 if (data[i+2].equals(qName)) { 336 return data[i+4]; 337 } 338 } 339 return null; 340 } 341 342 343 344 //////////////////////////////////////////////////////////////////// 345 // Manipulators. 346 //////////////////////////////////////////////////////////////////// 347 348 349 /** 350 * Clear the attribute list for reuse. 351 * 352 * <p>Note that no memory is actually freed by this call: 353 * the current arrays are kept so that they can be 354 * reused.</p> 355 */ 356 public void clear () 357 { 358 length = 0; 359 } 360 361 362 /** 363 * Copy an entire Attributes object. 364 * 365 * <p>It may be more efficient to reuse an existing object 366 * rather than constantly allocating new ones.</p> 367 * 368 * @param atts The attributes to copy. 369 */ 370 public void setAttributes (Attributes atts) 371 { 372 clear(); 373 length = atts.getLength(); 374 data = new String[length*5]; 375 for (int i = 0; i < length; i++) { 376 data[i*5] = atts.getURI(i); 377 data[i*5+1] = atts.getLocalName(i); 378 data[i*5+2] = atts.getQName(i); 379 data[i*5+3] = atts.getType(i); 380 data[i*5+4] = atts.getValue(i); 381 } 382 } 383 384 385 /** 386 * Add an attribute to the end of the list. 387 * 388 * <p>For the sake of speed, this method does no checking 389 * to see if the attribute is already in the list: that is 390 * the responsibility of the application.</p> 391 * 392 * @param uri The Namespace URI, or the empty string if 393 * none is available or Namespace processing is not 394 * being performed. 395 * @param localName The local name, or the empty string if 396 * Namespace processing is not being performed. 397 * @param qName The qualified (prefixed) name, or the empty string 398 * if qualified names are not available. 399 * @param type The attribute type as a string. 400 * @param value The attribute value. 401 */ 402 public void addAttribute (String uri, String localName, String qName, 403 String type, String value) 404 { 405 ensureCapacity(length+1); 406 data[length*5] = uri; 407 data[length*5+1] = localName; 408 data[length*5+2] = qName; 409 data[length*5+3] = type; 410 data[length*5+4] = value; 411 length++; 412 } 413 414 415 /** 416 * Set an attribute in the list. 417 * 418 * <p>For the sake of speed, this method does no checking 419 * for name conflicts or well-formedness: such checks are the 420 * responsibility of the application.</p> 421 * 422 * @param index The index of the attribute (zero-based). 423 * @param uri The Namespace URI, or the empty string if 424 * none is available or Namespace processing is not 425 * being performed. 426 * @param localName The local name, or the empty string if 427 * Namespace processing is not being performed. 428 * @param qName The qualified name, or the empty string 429 * if qualified names are not available. 430 * @param type The attribute type as a string. 431 * @param value The attribute value. 432 * @exception java.lang.ArrayIndexOutOfBoundsException When the 433 * supplied index does not point to an attribute 434 * in the list. 435 */ 436 public void setAttribute (int index, String uri, String localName, 437 String qName, String type, String value) 438 { 439 if (index >= 0 && index < length) { 440 data[index*5] = uri; 441 data[index*5+1] = localName; 442 data[index*5+2] = qName; 443 data[index*5+3] = type; 444 data[index*5+4] = value; 445 } else { 446 badIndex(index); 447 } 448 } 449 450 451 /** 452 * Remove an attribute from the list. 453 * 454 * @param index The index of the attribute (zero-based). 455 * @exception java.lang.ArrayIndexOutOfBoundsException When the 456 * supplied index does not point to an attribute 457 * in the list. 458 */ 459 public void removeAttribute (int index) 460 { 461 if (index >= 0 && index < length) { 462 if (index < length - 1) { 463 System.arraycopy(data, (index+1)*5, data, index*5, 464 (length-index-1)*5); 465 } 466 length--; 467 } else { 468 badIndex(index); 469 } 470 } 471 472 473 /** 474 * Set the Namespace URI of a specific attribute. 475 * 476 * @param index The index of the attribute (zero-based). 477 * @param uri The attribute's Namespace URI, or the empty 478 * string for none. 479 * @exception java.lang.ArrayIndexOutOfBoundsException When the 480 * supplied index does not point to an attribute 481 * in the list. 482 */ 483 public void setURI (int index, String uri) 484 { 485 if (index >= 0 && index < length) { 486 data[index*5] = uri; 487 } else { 488 badIndex(index); 489 } 490 } 491 492 493 /** 494 * Set the local name of a specific attribute. 495 * 496 * @param index The index of the attribute (zero-based). 497 * @param localName The attribute's local name, or the empty 498 * string for none. 499 * @exception java.lang.ArrayIndexOutOfBoundsException When the 500 * supplied index does not point to an attribute 501 * in the list. 502 */ 503 public void setLocalName (int index, String localName) 504 { 505 if (index >= 0 && index < length) { 506 data[index*5+1] = localName; 507 } else { 508 badIndex(index); 509 } 510 } 511 512 513 /** 514 * Set the qualified name of a specific attribute. 515 * 516 * @param index The index of the attribute (zero-based). 517 * @param qName The attribute's qualified name, or the empty 518 * string for none. 519 * @exception java.lang.ArrayIndexOutOfBoundsException When the 520 * supplied index does not point to an attribute 521 * in the list. 522 */ 523 public void setQName (int index, String qName) 524 { 525 if (index >= 0 && index < length) { 526 data[index*5+2] = qName; 527 } else { 528 badIndex(index); 529 } 530 } 531 532 533 /** 534 * Set the type of a specific attribute. 535 * 536 * @param index The index of the attribute (zero-based). 537 * @param type The attribute's type. 538 * @exception java.lang.ArrayIndexOutOfBoundsException When the 539 * supplied index does not point to an attribute 540 * in the list. 541 */ 542 public void setType (int index, String type) 543 { 544 if (index >= 0 && index < length) { 545 data[index*5+3] = type; 546 } else { 547 badIndex(index); 548 } 549 } 550 551 552 /** 553 * Set the value of a specific attribute. 554 * 555 * @param index The index of the attribute (zero-based). 556 * @param value The attribute's value. 557 * @exception java.lang.ArrayIndexOutOfBoundsException When the 558 * supplied index does not point to an attribute 559 * in the list. 560 */ 561 public void setValue (int index, String value) 562 { 563 if (index >= 0 && index < length) { 564 data[index*5+4] = value; 565 } else { 566 badIndex(index); 567 } 568 } 569 570 571 572 //////////////////////////////////////////////////////////////////// 573 // Internal methods. 574 //////////////////////////////////////////////////////////////////// 575 576 577 /** 578 * Ensure the internal array's capacity. 579 * 580 * @param n The minimum number of attributes that the array must 581 * be able to hold. 582 */ 583 private void ensureCapacity (int n) 584 { 585 if (n > 0 && (data == null || data.length==0)) { 586 data = new String[25]; 587 } 588 589 int max = data.length; 590 if (max >= n * 5) { 591 return; 592 } 593 594 595 while (max < n * 5) { 596 max *= 2; 597 } 598 String newData[] = new String[max]; 599 System.arraycopy(data, 0, newData, 0, length*5); 600 data = newData; 601 } 602 603 604 /** 605 * Report a bad array index in a manipulator. 606 * 607 * @param index The index to report. 608 * @exception java.lang.ArrayIndexOutOfBoundsException Always. 609 */ 610 private void badIndex (int index) 611 throws ArrayIndexOutOfBoundsException 612 { 613 String msg = 614 "Attempt to modify attribute at illegal index: " + index; 615 throw new ArrayIndexOutOfBoundsException(msg); 616 } 617 618 619 620 //////////////////////////////////////////////////////////////////// 621 // Internal state. 622 //////////////////////////////////////////////////////////////////// 623 624 int length; 625 String data []; 626 627 } 628 629 // end of AttributesImpl.java