1 19 20 package org.netbeans.tax; 21 22 import java.util.List ; 23 import java.util.LinkedList ; 24 import java.util.Iterator ; 25 import java.util.Collections ; 26 27 import org.netbeans.tax.spec.Document; 28 import org.netbeans.tax.spec.DocumentFragment; 29 import org.netbeans.tax.spec.Element; 30 import org.netbeans.tax.spec.GeneralEntityReference; 31 import org.netbeans.tax.spec.Attribute; 32 33 import org.netbeans.tax.event.TreeEventManager; 34 35 41 public class TreeElement extends TreeParentNode implements Document.Child, DocumentFragment.Child, Element.Child, GeneralEntityReference.Child { 42 43 44 public static final String PROP_TAG_NAME = "tagName"; 46 public static final String PROP_ATTRIBUTES = "attributes"; 48 49 private TreeName tagName; 51 52 54 55 private TreeNamespaceContext namespaceContext; 56 57 58 private TreeNamedObjectMap attributes; 59 60 61 private boolean empty; 65 66 private boolean containsCharacterData; 67 68 69 73 76 public TreeElement (String tagName, boolean empty) throws InvalidArgumentException { 77 super (); 78 79 TreeName treeName = new TreeName (tagName); 80 checkTagName (treeName); 81 this.tagName = treeName; 82 this.empty = empty; 83 this.containsCharacterData = false; 84 85 this.namespaceContext = new TreeNamespaceContext (this); 86 this.attributes = new TreeNamedObjectMap (createAttributesContentManager ()); 87 88 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("TreeElement:: : name = " + tagName + " : empty = " + empty); } 90 91 92 95 public TreeElement (String qName) throws InvalidArgumentException { 96 this (qName, false); 97 } 98 99 102 protected TreeElement (TreeElement element, boolean deep) { 103 super (element, deep); 104 105 this.tagName = element.tagName; 106 this.empty = element.empty; 107 this.namespaceContext = new TreeNamespaceContext (this); 109 this.attributes = new TreeNamedObjectMap (createAttributesContentManager ()); 110 this.attributes.addAll ((TreeNamedObjectMap)element.attributes.clone ()); 111 } 112 113 114 118 120 public Object clone (boolean deep) { 121 return new TreeElement (this, deep); 122 } 123 124 126 public boolean equals (Object object, boolean deep) { 127 if (!!! super.equals (object, deep)) 128 return false; 129 130 TreeElement peer = (TreeElement) object; 131 if (this.empty != peer.empty) 132 return false; 133 if (!!! Util.equals (this.getTreeName (), peer.getTreeName ())) 134 return false; 135 if (!!! Util.equals (this.getAttributes (), peer.getAttributes ())) 136 return false; 137 138 return true; 139 } 140 141 145 public void merge (TreeObject treeObject) throws CannotMergeException { 146 super.merge (treeObject); 147 148 TreeElement peer = (TreeElement) treeObject; 149 this.empty = empty || peer.empty; 151 try { 152 setTreeName (peer.getTreeName ()); 153 } catch (Exception exc) { 154 throw new CannotMergeException (treeObject, exc); 155 } 156 157 attributes.merge (peer.getAttributes ()); 158 } 160 161 162 166 167 169 protected void setReadOnly (boolean newReadOnly) { 170 super.setReadOnly (newReadOnly); 171 172 attributes.setReadOnly (newReadOnly); 173 } 174 175 176 180 182 public final String getQName () { 183 return tagName.getQualifiedName (); 184 } 185 186 190 public final void setQName (String newTagName) throws ReadOnlyException, InvalidArgumentException { 191 setTreeName (new TreeName (newTagName)); 192 } 193 194 196 public final TreeName getTreeName () { 197 return tagName; 198 } 199 200 202 private final void setTreeNameImpl (TreeName newTagName) { 203 TreeName oldTagName = this.tagName; 204 205 this.tagName = newTagName; 206 207 firePropertyChange (PROP_TAG_NAME, oldTagName, newTagName); 208 } 209 210 214 public final void setTreeName (TreeName newTagName) throws ReadOnlyException, InvalidArgumentException { 215 if ( Util.equals (this.tagName, newTagName) ) 219 return; 220 checkReadOnly (); 221 checkTagName (newTagName); 222 223 setTreeNameImpl (newTagName); 227 } 228 229 234 public boolean isEmpty () { 235 if (empty == false) 236 return false; 237 return getChildNodes ().size () == 0; 238 } 239 240 242 protected final void checkTagName (TreeName tagName) throws InvalidArgumentException { 243 TreeUtilities.checkElementTagName (tagName); 244 } 245 246 247 251 252 254 protected final TreeNamespaceContext getNamespaceContext () { 255 return namespaceContext; 256 } 257 258 261 public final TreeNamespace getNamespace () { 262 String prefix = getNamespacePrefix (); 263 String uri = namespaceContext.getURI (prefix); 264 265 if (uri == null) { 266 return TreeNamespace.NO_NAMESPACE; 267 } else { 268 return new TreeNamespace (prefix, uri); 269 } 270 } 271 272 274 public final String getNamespacePrefix () { 275 return tagName.getPrefix (); 276 } 277 278 279 281 public final String getNamespaceURI () { 282 return getNamespace ().getURI (); 283 } 284 285 286 288 public final String getLocalName () { 289 return tagName.getName (); 290 } 291 292 293 294 298 299 301 public final int getAttributesNumber () { 302 return (attributes.size ()); 303 } 304 305 307 public final boolean hasAttributes () { 308 return ( attributes.size () != 0 ); 309 } 310 311 313 public final boolean hasAttribute (String name) { 314 return ( getAttribute (name) != null ); 315 } 316 317 318 320 public final TreeNamedObjectMap getAttributes () { 321 return attributes; 322 } 323 324 326 public final TreeAttribute getAttribute (String name) { 327 try { 328 TreeName treeName = new TreeName (name); 329 return (TreeAttribute)attributes.get (treeName); 330 } catch (InvalidArgumentException exc) { 331 return null; 332 } 333 } 334 335 339 public final TreeAttribute addAttribute (String name, String value) throws ReadOnlyException, InvalidArgumentException { 340 347 checkReadOnly (); 348 TreeAttribute newAttr = new TreeAttribute (name, value); 349 TreeAttribute oldAttr = removeAttribute (name); 350 attributes.add (newAttr); 351 return oldAttr; 352 } 353 354 355 359 public final void addAttribute (TreeAttribute newAttr) throws ReadOnlyException, InvalidArgumentException { 360 String qName = newAttr.getQName (); 361 362 369 checkReadOnly (); 370 TreeAttribute oldAttr = removeAttribute (qName); 371 attributes.add (newAttr); 372 } 374 375 376 379 public final TreeAttribute removeAttribute (String name) throws ReadOnlyException { 380 return removeAttribute (getAttribute (name)); 381 } 382 383 384 387 public final TreeAttribute removeAttribute (TreeAttribute oldAttr) throws ReadOnlyException { 388 checkReadOnly (); 389 attributes.remove (oldAttr); 390 return oldAttr; 391 } 392 393 396 public final void removeAttributes () throws ReadOnlyException { 397 checkReadOnly (); 398 attributes.clear (); 399 } 400 401 402 406 409 public final void normalize () throws ReadOnlyException { 410 checkReadOnly (); 411 try { 412 getChildNodes ().getEventManager ().setFirePolicy (TreeEventManager.FIRE_LATER); 413 for (int i = 0; true; i++) { 414 TreeChild child = item (i); 415 416 if (child instanceof TreeElement) { 417 ((TreeElement)child).normalize (); 418 } else if (child instanceof TreeText) { 419 while (true) { 420 TreeChild child2 = item (i + 1); 421 if (child2 instanceof TreeText) { 422 try { 423 ((TreeText)child).appendData (((TreeText)child2).getData ()); 424 removeChild (child2); 425 } catch (InvalidArgumentException exc) { break; } 428 } else { 429 break; } 431 } 432 } 433 } 434 } catch (IndexOutOfBoundsException e) { 435 436 } finally { 437 getChildNodes ().getEventManager ().setFirePolicy (TreeEventManager.FIRE_NOW); 438 } 439 } 440 441 442 444 public final boolean containsCharacterData () { 445 return containsCharacterData; 446 } 447 448 450 private void updateContainsCharacterData () { 451 Iterator it = getChildNodes ().iterator (); 452 while (it.hasNext ()) { 453 Object obj = it.next (); 454 if ( obj instanceof TreeCharacterData ) { 455 TreeCharacterData charData = (TreeCharacterData)obj; 456 if ( charData instanceof TreeData ) { 457 if ( ((TreeData)charData).onlyWhiteSpaces () == false ) { 458 containsCharacterData = true; 459 } 460 } else { 461 containsCharacterData = true; 462 } 463 if ( containsCharacterData ) { 464 return; 465 } 466 } 467 } 468 containsCharacterData = false; 469 } 470 471 472 476 478 protected TreeObjectList.ContentManager createChildListContentManager () { 479 return new ChildListContentManager (); 480 } 481 482 483 485 protected TreeNamedObjectMap.ContentManager createAttributesContentManager () { 486 return new AttributesContentManager (); 487 } 488 489 490 493 protected class ChildListContentManager extends TreeParentNode.ChildListContentManager { 494 495 497 public TreeNode getOwnerNode () { 498 return TreeElement.this; 499 } 500 501 503 public void checkAssignableObject (Object obj) { 504 super.checkAssignableObject (obj); 505 checkAssignableClass (Element.Child.class, obj); 506 } 507 508 } 510 511 514 protected class AttributesContentManager extends TreeNamedObjectMap.ContentManager { 515 516 518 public TreeNode getOwnerNode () { 519 return TreeElement.this; 520 } 521 522 524 public void checkAssignableObject (Object obj) { 525 checkAssignableClass (Element.Attribute.class, obj); 526 } 527 528 530 public void objectInserted (TreeObject obj) { 531 ((TreeAttribute)obj).setOwnerElement (TreeElement.this); 532 TreeElement.this.firePropertyChange (TreeElement.PROP_ATTRIBUTES, TreeElement.this.attributes, null); 533 } 534 535 537 public void objectRemoved (TreeObject obj) { 538 ((TreeAttribute)obj).setOwnerElement (null); 539 TreeElement.this.firePropertyChange (TreeElement.PROP_ATTRIBUTES, TreeElement.this.attributes, null); 540 } 541 542 544 public void orderChanged (int[] permutation) { 545 TreeElement.this.firePropertyChange (TreeElement.PROP_ATTRIBUTES, TreeElement.this.attributes, null); 546 } 547 548 } 550 } 551 | Popular Tags |