1 package net.sf.saxon.om; 2 3 import net.sf.saxon.event.LocationProvider; 4 import net.sf.saxon.style.StandardNames; 5 import org.xml.sax.Attributes ; 6 7 8 19 20 public final class AttributeCollectionImpl implements Attributes , AttributeCollection { 21 22 25 private NamePool namePool; 26 private LocationProvider locationProvider; 27 private String [] values = null; 28 private int[] codes = null; 29 private int used = 0; 30 31 33 public static final AttributeCollection EMPTY_ATTRIBUTE_COLLECTION = 34 new AttributeCollectionImpl(null); 35 36 38 private static final int RECSIZE = 4; 39 40 private static final int NAMECODE = 0; 41 private static final int TYPECODE = 1; 42 private static final int LOCATIONID = 2; 43 private static final int PROPERTIES = 3; 44 45 48 49 public AttributeCollectionImpl(NamePool pool) { 50 namePool = pool; 51 used = 0; 52 } 53 54 58 59 public void setLocationProvider(LocationProvider provider) { 60 this.locationProvider = provider; 61 } 62 63 75 76 public void addAttribute(int nameCode, int typeCode, String value, int locationId, int properties) { 77 if (values == null) { 78 values = new String [5]; 79 codes = new int[5 * RECSIZE]; 80 used = 0; 81 } 82 if (values.length == used) { 83 int newsize = (used == 0 ? 5 : used * 2); 84 String [] v2 = new String [newsize]; 85 int[] c2 = new int[newsize * RECSIZE]; 86 System.arraycopy(values, 0, v2, 0, used); 87 System.arraycopy(codes, 0, c2, 0, used*RECSIZE); 88 values = v2; 89 codes = c2; 90 } 91 int n = used*RECSIZE; 92 codes[n+NAMECODE] = nameCode; 93 codes[n+TYPECODE] = typeCode; 94 codes[n+LOCATIONID] = locationId; 95 codes[n+PROPERTIES] = properties; 96 values[used++] = value; 97 } 98 99 110 111 public void setAttribute(int index, int nameCode, int typeCode, String value, int locationId, int properties) { 112 int n = index*RECSIZE; 113 codes[n+NAMECODE] = nameCode; 114 codes[n+TYPECODE] = typeCode; 115 codes[n+LOCATIONID] = locationId; 116 codes[n+PROPERTIES] = properties; 117 values[index] = value; 118 } 119 120 121 125 126 public void clear() { 127 used = 0; 128 } 129 130 133 134 public void compact() { 135 if (used == 0) { 136 codes = null; 137 values = null; 138 } else if (values.length > used) { 139 String [] v2 = new String [used]; 140 int[] c2 = new int[used * RECSIZE]; 141 System.arraycopy(values, 0, v2, 0, used); 142 System.arraycopy(codes, 0, c2, 0, used*RECSIZE); 143 values = v2; 144 codes = c2; 145 } 146 } 147 148 153 154 public int getLength() { 155 return (values == null ? 0 : used); 156 } 157 158 165 166 public int getNameCode(int index) { 167 if (codes == null) { 168 return -1; 169 } 170 if (index < 0 || index >= used) { 171 return -1; 172 } 173 174 return codes[index * RECSIZE + NAMECODE]; 175 } 176 177 184 185 public int getTypeAnnotation(int index) { 186 if (codes == null) { 187 return StandardNames.XDT_UNTYPED_ATOMIC; 188 } 189 if (index < 0 || index >= used) { 190 return StandardNames.XDT_UNTYPED_ATOMIC; 191 } 192 193 return codes[index * RECSIZE + TYPECODE]; 194 } 195 196 203 204 public int getLocationId(int index) { 205 if (codes == null) { 206 return -1; 207 } 208 if (index < 0 || index >= used) { 209 return -1; 210 } 211 212 return codes[index * RECSIZE + LOCATIONID]; 213 } 214 215 226 227 public String getSystemId(int index) { 228 return locationProvider.getSystemId(getLocationId(index)); 229 } 230 231 242 243 public int getLineNumber(int index) { 244 return locationProvider.getLineNumber(getLocationId(index)); 245 } 246 247 255 256 public int getProperties(int index) { 257 if (codes == null) { 258 return -1; 259 } 260 if (index < 0 || index >= used) { 261 return -1; 262 } 263 264 return codes[index * RECSIZE + PROPERTIES]; 265 } 266 267 275 276 public String getPrefix(int index) { 277 if (codes == null) { 278 return null; 279 } 280 if (index < 0 || index >= used) { 281 return null; 282 } 283 return namePool.getPrefix(getNameCode(index)); 284 } 285 286 293 294 public String getQName(int index) { 295 if (codes == null) { 296 return null; 297 } 298 if (index < 0 || index >= used) { 299 return null; 300 } 301 return namePool.getDisplayName(getNameCode(index)); 302 } 303 304 311 312 public String getLocalName(int index) { 313 if (codes == null) { 314 return null; 315 } 316 if (index < 0 || index >= used) { 317 return null; 318 } 319 return namePool.getLocalName(getNameCode(index)); 320 } 321 322 329 330 public String getURI(int index) { 331 if (codes == null) { 332 return null; 333 } 334 if (index < 0 || index >= used) { 335 return null; 336 } 337 return namePool.getURI(getNameCode(index)); 338 } 339 340 341 352 353 public String getType(int index) { 354 int typeCode = getTypeAnnotation(index) & NamePool.FP_MASK; 355 switch (typeCode) { 356 case StandardNames.XS_ID: return "ID"; 357 case StandardNames.XS_IDREF: return "IDREF"; 358 case StandardNames.XS_NMTOKEN: return "NMTOKEN"; 359 case StandardNames.XS_ENTITY: return "ENTITY"; 360 case StandardNames.XS_IDREFS: return "IDREFS"; 361 case StandardNames.XS_NMTOKENS: return "NMTOKENS"; 362 case StandardNames.XS_ENTITIES: return "ENTITIES"; 363 default: return "CDATA"; 364 } 365 } 366 367 374 375 public String getType(String uri, String localname) { 376 int index = findByName(uri, localname); 377 return (index < 0 ? null : getType(index)); 378 } 379 380 387 388 public String getValue(int index) { 389 if (values == null) { 390 return null; 391 } 392 if (index < 0 || index >= used) { 393 return null; 394 } 395 return values[index]; 396 } 397 398 405 406 public String getValue(String uri, String localname) { 407 int index = findByName(uri, localname); 408 return (index < 0 ? null : getValue(index)); 409 } 410 411 414 415 public String getValueByFingerprint(int fingerprint) { 416 int index = findByFingerprint(fingerprint); 417 return (index < 0 ? null : getValue(index)); 418 } 419 420 426 427 public int getIndex(String qname) { 428 if (codes == null) { 429 return -1; 430 } 431 if (qname.indexOf(':') < 0) { 432 return findByName("", qname); 433 } 434 String [] parts; 436 try { 437 parts = Name.getQNameParts(qname); 438 } catch (QNameException err) { 439 return -1; 440 } 441 String prefix = parts[0]; 442 if (prefix.equals("")) { 443 return findByName("", qname); 444 } else { 445 String localName = parts[1]; 446 for (int i = 0; i < used; i++) { 447 String lname = namePool.getLocalName(getNameCode(i)); 448 String ppref = namePool.getPrefix(getNameCode(i)); 449 if (localName.equals(lname) && prefix.equals(ppref)) { 450 return i; 451 } 452 } 453 return -1; 454 } 455 } 456 457 464 465 public int getIndex(String uri, String localname) { 466 return findByName(uri, localname); 467 } 468 469 473 474 public int getIndexByFingerprint(int fingerprint) { 475 return findByFingerprint(fingerprint); 476 } 477 478 485 486 public String getType(String name) { 487 int index = getIndex(name); 488 return getType(index); 489 } 490 491 492 499 500 public String getValue(String name) { 501 int index = getIndex(name); 502 return getValue(index); 503 } 504 505 511 512 private int findByName(String uri, String localName) { 513 if (namePool == null) { 514 return -1; } 516 int f = namePool.getFingerprint(uri, localName); 517 if (f == -1) { 518 return -1; 519 } 520 return findByFingerprint(f); 521 } 522 523 528 529 private int findByFingerprint(int fingerprint) { 530 if (codes == null) { 531 return -1; 532 } 533 for (int i = 0; i < used; i++) { 534 if (fingerprint == (codes[i*RECSIZE + NAMECODE] & NamePool.FP_MASK)) { 535 return i; 536 } 537 } 538 return -1; 539 } 540 541 544 545 public boolean isId(int index) { 546 return getType(index).equals("ID") || 547 ((getNameCode(index) & NamePool.FP_MASK) == StandardNames.XML_ID); 548 } 549 550 } 551 552 | Popular Tags |