1 38 39 40 package com.sun.xml.fastinfoset.util; 41 42 import com.sun.xml.fastinfoset.EncodingConstants; 43 import com.sun.xml.fastinfoset.CommonResourceBundle; 44 import java.util.Iterator ; 45 import java.util.NoSuchElementException ; 46 import org.jvnet.fastinfoset.FastInfosetException; 47 48 public class PrefixArray extends ValueArray { 49 public static final int PREFIX_MAP_SIZE = 64; 50 51 private int _initialCapacity; 52 53 public String [] _array; 54 55 private PrefixArray _readOnlyArray; 56 57 private static class PrefixEntry { 58 private PrefixEntry next; 59 private int prefixId; 60 } 61 62 private PrefixEntry[] _prefixMap = new PrefixEntry[PREFIX_MAP_SIZE]; 63 64 private PrefixEntry _prefixPool; 65 66 private static class NamespaceEntry { 67 private NamespaceEntry next; 68 private int declarationId; 69 private int namespaceIndex; 70 71 private String prefix; 72 private String namespaceName; 73 private int prefixEntryIndex; 74 } 75 76 private NamespaceEntry _namespacePool; 77 78 private NamespaceEntry[] _inScopeNamespaces; 79 80 public int[] _currentInScope; 81 82 public int _declarationId; 83 84 public PrefixArray(int initialCapacity, int maximumCapacity) { 85 _initialCapacity = initialCapacity; 86 _maximumCapacity = maximumCapacity; 87 88 _array = new String [initialCapacity]; 89 _inScopeNamespaces = new NamespaceEntry[initialCapacity + 2]; 93 _currentInScope = new int[initialCapacity + 2]; 94 95 increaseNamespacePool(initialCapacity); 96 increasePrefixPool(initialCapacity); 97 98 initializeEntries(); 99 } 100 101 public PrefixArray() { 102 this(DEFAULT_CAPACITY, MAXIMUM_CAPACITY); 103 } 104 105 private final void initializeEntries() { 106 _inScopeNamespaces[0] = _namespacePool; 107 _namespacePool = _namespacePool.next; 108 _inScopeNamespaces[0].next = null; 109 _inScopeNamespaces[0].prefix = ""; 110 _inScopeNamespaces[0].namespaceName = ""; 111 _inScopeNamespaces[0].namespaceIndex = _currentInScope[0] = 0; 112 113 int index = KeyIntMap.indexFor(KeyIntMap.hashHash(_inScopeNamespaces[0].prefix.hashCode()), _prefixMap.length); 114 _prefixMap[index] = _prefixPool; 115 _prefixPool = _prefixPool.next; 116 _prefixMap[index].next = null; 117 _prefixMap[index].prefixId = 0; 118 119 120 _inScopeNamespaces[1] = _namespacePool; 121 _namespacePool = _namespacePool.next; 122 _inScopeNamespaces[1].next = null; 123 _inScopeNamespaces[1].prefix = EncodingConstants.XML_NAMESPACE_PREFIX; 124 _inScopeNamespaces[1].namespaceName = EncodingConstants.XML_NAMESPACE_NAME; 125 _inScopeNamespaces[1].namespaceIndex = _currentInScope[1] = 1; 126 127 index = KeyIntMap.indexFor(KeyIntMap.hashHash(_inScopeNamespaces[1].prefix.hashCode()), _prefixMap.length); 128 if (_prefixMap[index] == null) { 129 _prefixMap[index] = _prefixPool; 130 _prefixPool = _prefixPool.next; 131 _prefixMap[index].next = null; 132 } else { 133 final PrefixEntry e = _prefixMap[index]; 134 _prefixMap[index] = _prefixPool; 135 _prefixPool = _prefixPool.next; 136 _prefixMap[index].next = e; 137 } 138 _prefixMap[index].prefixId = 1; 139 } 140 141 private final void increaseNamespacePool(int capacity) { 142 if (_namespacePool == null) { 143 _namespacePool = new NamespaceEntry(); 144 } 145 146 for (int i = 0; i < capacity; i++) { 147 NamespaceEntry ne = new NamespaceEntry(); 148 ne.next = _namespacePool; 149 _namespacePool = ne; 150 } 151 } 152 153 private final void increasePrefixPool(int capacity) { 154 if (_prefixPool == null) { 155 _prefixPool = new PrefixEntry(); 156 } 157 158 for (int i = 0; i < capacity; i++) { 159 PrefixEntry pe = new PrefixEntry(); 160 pe.next = _prefixPool; 161 _prefixPool = pe; 162 } 163 } 164 165 public int countNamespacePool() { 166 int i = 0; 167 NamespaceEntry e = _namespacePool; 168 while (e != null) { 169 i++; 170 e = e.next; 171 } 172 return i; 173 } 174 175 public int countPrefixPool() { 176 int i = 0; 177 PrefixEntry e = _prefixPool; 178 while (e != null) { 179 i++; 180 e = e.next; 181 } 182 return i; 183 } 184 185 public final void clear() { 186 for (int i = _readOnlyArraySize; i < _size; i++) { 187 _array[i] = null; 188 } 189 _size = _readOnlyArraySize; 190 } 191 192 public final void clearCompletely() { 193 _prefixPool = null; 194 _namespacePool = null; 195 196 for (int i = 0; i < _size + 2; i++) { 197 _currentInScope[i] = 0; 198 _inScopeNamespaces[i] = null; 199 } 200 201 for (int i = 0; i < _prefixMap.length; i++) { 202 _prefixMap[i] = null; 203 } 204 205 increaseNamespacePool(_initialCapacity); 206 increasePrefixPool(_initialCapacity); 207 208 initializeEntries(); 209 210 _declarationId = 0; 211 212 clear(); 213 } 214 215 public final String [] getArray() { 216 return _array; 217 } 218 219 public final void setReadOnlyArray(ValueArray readOnlyArray, boolean clear) { 220 if (!(readOnlyArray instanceof PrefixArray)) { 221 throw new IllegalArgumentException (CommonResourceBundle.getInstance(). 222 getString("message.illegalClass", new Object []{readOnlyArray})); 223 } 224 225 setReadOnlyArray((PrefixArray)readOnlyArray, clear); 226 } 227 228 public final void setReadOnlyArray(PrefixArray readOnlyArray, boolean clear) { 229 if (readOnlyArray != null) { 230 _readOnlyArray = readOnlyArray; 231 _readOnlyArraySize = readOnlyArray.getSize(); 232 233 _inScopeNamespaces = new NamespaceEntry[_readOnlyArraySize + _inScopeNamespaces.length]; 235 _currentInScope = new int[_readOnlyArraySize + _currentInScope.length]; 236 initializeEntries(); 238 239 if (clear) { 240 clear(); 241 } 242 243 _array = getCompleteArray(); 244 _size = _readOnlyArraySize; 245 } 246 } 247 248 public final String [] getCompleteArray() { 249 if (_readOnlyArray == null) { 250 return _array; 251 } else { 252 final String [] ra = _readOnlyArray.getCompleteArray(); 253 final String [] a = new String [_readOnlyArraySize + _array.length]; 254 System.arraycopy(ra, 0, a, 0, _readOnlyArraySize); 255 return a; 256 } 257 } 258 259 public final String get(int i) { 260 return _array[i]; 261 } 262 263 public final int add(String s) { 264 if (_size == _array.length) { 265 resize(); 266 } 267 268 _array[_size++] = s; 269 return _size; 270 } 271 272 protected final void resize() { 273 if (_size == _maximumCapacity) { 274 throw new ValueArrayResourceException(CommonResourceBundle.getInstance().getString("message.arrayMaxCapacity")); 275 } 276 277 int newSize = _size * 3 / 2 + 1; 278 if (newSize > _maximumCapacity) { 279 newSize = _maximumCapacity; 280 } 281 282 final String [] newArray = new String [newSize]; 283 System.arraycopy(_array, 0, newArray, 0, _size); 284 _array = newArray; 285 286 newSize += _readOnlyArraySize; 287 final NamespaceEntry[] newInScopeNamespaces = new NamespaceEntry[newSize + 2]; 288 System.arraycopy(_inScopeNamespaces, 0, newInScopeNamespaces, 0, _readOnlyArraySize + _size + 2); 289 _inScopeNamespaces = newInScopeNamespaces; 290 291 final int[] newCurrentInScope = new int[newSize + 2]; 292 System.arraycopy(_currentInScope, 0, newCurrentInScope, 0, _readOnlyArraySize + _size + 2); 293 _currentInScope = newCurrentInScope; 294 } 295 296 public final void clearDeclarationIds() { 297 for (int i = 0; i < _size; i++) { 298 final NamespaceEntry e = _inScopeNamespaces[i]; 299 if (e != null) { 300 e.declarationId = 0; 301 } 302 } 303 304 _declarationId = 1; 305 } 306 307 public final void pushScope(int prefixIndex, int namespaceIndex) throws FastInfosetException { 308 if (_namespacePool == null) { 309 increaseNamespacePool(16); 310 } 311 312 final NamespaceEntry e = _namespacePool; 313 _namespacePool = e.next; 314 315 final NamespaceEntry current = _inScopeNamespaces[++prefixIndex]; 316 if (current == null) { 317 e.declarationId = _declarationId; 318 e.namespaceIndex = _currentInScope[prefixIndex] = ++namespaceIndex; 319 e.next = null; 320 321 _inScopeNamespaces[prefixIndex] = e; 322 } else if (current.declarationId < _declarationId) { 323 e.declarationId = _declarationId; 324 e.namespaceIndex = _currentInScope[prefixIndex] = ++namespaceIndex; 325 e.next = current; 326 327 current.declarationId = 0; 328 _inScopeNamespaces[prefixIndex] = e; 329 } else { 330 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.duplicateNamespaceAttribute")); 331 } 332 } 333 334 public final void pushScopeWithPrefixEntry(String prefix, String namespaceName, 335 int prefixIndex, int namespaceIndex) throws FastInfosetException { 336 if (_namespacePool == null) { 337 increaseNamespacePool(16); 338 } 339 if (_prefixPool == null) { 340 increasePrefixPool(16); 341 } 342 343 final NamespaceEntry e = _namespacePool; 344 _namespacePool = e.next; 345 346 final NamespaceEntry current = _inScopeNamespaces[++prefixIndex]; 347 if (current == null) { 348 e.declarationId = _declarationId; 349 e.namespaceIndex = _currentInScope[prefixIndex] = ++namespaceIndex; 350 e.next = null; 351 352 _inScopeNamespaces[prefixIndex] = e; 353 } else if (current.declarationId < _declarationId) { 354 e.declarationId = _declarationId; 355 e.namespaceIndex = _currentInScope[prefixIndex] = ++namespaceIndex; 356 e.next = current; 357 358 current.declarationId = 0; 359 _inScopeNamespaces[prefixIndex] = e; 360 } else { 361 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.duplicateNamespaceAttribute")); 362 } 363 364 final PrefixEntry p = _prefixPool; 365 _prefixPool = _prefixPool.next; 366 p.prefixId = prefixIndex; 367 368 e.prefix = prefix; 369 e.namespaceName = namespaceName; 370 e.prefixEntryIndex = KeyIntMap.indexFor(KeyIntMap.hashHash(prefix.hashCode()), _prefixMap.length); 371 372 final PrefixEntry pCurrent = _prefixMap[e.prefixEntryIndex]; 373 p.next = pCurrent; 374 _prefixMap[e.prefixEntryIndex] = p; 375 } 376 377 public final void popScope(int prefixIndex) { 378 final NamespaceEntry e = _inScopeNamespaces[++prefixIndex]; 379 _inScopeNamespaces[prefixIndex] = e.next; 380 _currentInScope[prefixIndex] = (e.next != null) ? e.next.namespaceIndex : 0; 381 382 e.next = _namespacePool; 383 _namespacePool = e; 384 } 385 386 public final void popScopeWithPrefixEntry(int prefixIndex) { 387 final NamespaceEntry e = _inScopeNamespaces[++prefixIndex]; 388 389 _inScopeNamespaces[prefixIndex] = e.next; 390 _currentInScope[prefixIndex] = (e.next != null) ? e.next.namespaceIndex : 0; 391 392 e.prefix = e.namespaceName = null; 393 e.next = _namespacePool; 394 _namespacePool = e; 395 396 PrefixEntry current = _prefixMap[e.prefixEntryIndex]; 397 if (current.prefixId == prefixIndex) { 398 _prefixMap[e.prefixEntryIndex] = current.next; 399 current.next = _prefixPool; 400 _prefixPool = current; 401 } else { 402 PrefixEntry prev = current; 403 current = current.next; 404 while (current != null) { 405 if (current.prefixId == prefixIndex) { 406 prev.next = current.next; 407 current.next = _prefixPool; 408 _prefixPool = current; 409 break; 410 } 411 prev = current; 412 current = current.next; 413 } 414 } 415 } 416 417 public final String getNamespaceFromPrefix(String prefix) { 418 final int index = KeyIntMap.indexFor(KeyIntMap.hashHash(prefix.hashCode()), _prefixMap.length); 419 PrefixEntry pe = _prefixMap[index]; 420 while (pe != null) { 421 final NamespaceEntry ne = _inScopeNamespaces[pe.prefixId]; 422 if (prefix == ne.prefix || prefix.equals(ne.prefix)) { 423 return ne.namespaceName; 424 } 425 pe = pe.next; 426 } 427 428 return null; 429 } 430 431 public final String getPrefixFromNamespace(String namespaceName) { 432 int position = 0; 433 while (++position < _size + 2) { 434 final NamespaceEntry ne = _inScopeNamespaces[position]; 435 if (ne != null && namespaceName.equals(ne.namespaceName)) { 436 return ne.prefix; 437 } 438 } 439 440 return null; 441 } 442 443 public final Iterator getPrefixes() { 444 return new Iterator () { 445 int _position = 1; 446 NamespaceEntry _ne = _inScopeNamespaces[_position]; 447 448 public boolean hasNext() { 449 return _ne != null; 450 } 451 452 public Object next() { 453 if (_position == _size + 2) { 454 throw new NoSuchElementException (); 455 } 456 457 final String prefix = _ne.prefix; 458 moveToNext(); 459 return prefix; 460 } 461 462 public void remove() { 463 throw new UnsupportedOperationException (); 464 } 465 466 private final void moveToNext() { 467 while (++_position < _size + 2) { 468 _ne = _inScopeNamespaces[_position]; 469 if (_ne != null) { 470 return; 471 } 472 } 473 _ne = null; 474 } 475 476 }; 477 } 478 479 public final Iterator getPrefixesFromNamespace(final String namespaceName) { 480 return new Iterator () { 481 String _namespaceName = namespaceName; 482 int _position = 0; 483 NamespaceEntry _ne; 484 485 { 486 moveToNext(); 487 } 488 489 public boolean hasNext() { 490 return _ne != null; 491 } 492 493 public Object next() { 494 if (_position == _size + 2) { 495 throw new NoSuchElementException (); 496 } 497 498 final String prefix = _ne.prefix; 499 moveToNext(); 500 return prefix; 501 } 502 503 public void remove() { 504 throw new UnsupportedOperationException (); 505 } 506 507 private final void moveToNext() { 508 while (++_position < _size + 2) { 509 _ne = _inScopeNamespaces[_position]; 510 if (_ne != null && _namespaceName.equals(_ne.namespaceName)) { 511 return; 512 } 513 } 514 _ne = null; 515 } 516 }; 517 } 518 } 519 | Popular Tags |