KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > tax > TreeElement


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.tax;
21
22 import java.util.List JavaDoc;
23 import java.util.LinkedList JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.Collections JavaDoc;
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 /**
36  * It represents startTag, endTag and emptyTag markup and holds element content.
37  *
38  * @author Libor Kramolis
39  * @version 0.1
40  */

41 public class TreeElement extends TreeParentNode implements Document.Child, DocumentFragment.Child, Element.Child, GeneralEntityReference.Child {
42     
43     /** */
44     public static final String JavaDoc PROP_TAG_NAME = "tagName"; // NOI18N
45
/** */
46     public static final String JavaDoc PROP_ATTRIBUTES = "attributes"; // NOI18N
47

48     /** */
49     private TreeName tagName; //QName as arrears in output
50

51     /** */
52     // private String baseURI; //??? => xml:base="baseURI" // NOI18N
53

54     /** */
55     private TreeNamespaceContext namespaceContext;
56     
57     /** */
58     private TreeNamedObjectMap attributes;
59     
60     /** */
61     private boolean empty; //signals that it represents empty element <empty/>
62
//as opposite to <nonempty></nonempty>
63
//it is a sticky flag
64

65     /** */
66     private boolean containsCharacterData;
67     
68     
69     //
70
// init
71
//
72

73     /** Creates new TreeElement.
74      * @throws InvalidArgumentException
75      */

76     public TreeElement (String JavaDoc 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() ) /* then */ Util.THIS.debug ("TreeElement:: : name = " + tagName + " : empty = " + empty); // NOI18N
89
}
90     
91     
92     /** Creates new TreeElement.
93      * @throws InvalidArgumentException
94      */

95     public TreeElement (String JavaDoc qName) throws InvalidArgumentException {
96         this (qName, false);
97     }
98     
99     /**
100      * Creates new TreeElement -- copy constructor.
101      */

102     protected TreeElement (TreeElement element, boolean deep) {
103         super (element, deep);
104         
105         this.tagName = element.tagName;
106         this.empty = element.empty;
107         // this.baseURI = element.baseURI;
108
this.namespaceContext = new TreeNamespaceContext (this);
109         this.attributes = new TreeNamedObjectMap (createAttributesContentManager ());
110         this.attributes.addAll ((TreeNamedObjectMap)element.attributes.clone ());
111     }
112     
113     
114     //
115
// from TreeObject
116
//
117

118     /**
119      */

120     public Object JavaDoc clone (boolean deep) {
121         return new TreeElement (this, deep);
122     }
123     
124     /**
125      */

126     public boolean equals (Object JavaDoc 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     /*
142      * Merge name and empty (sticky) properties and delagte merging attributes.
143      * Ignore peer's Namespace context.
144      */

145     public void merge (TreeObject treeObject) throws CannotMergeException {
146         super.merge (treeObject);
147         
148         TreeElement peer = (TreeElement) treeObject;
149         this.empty = empty || peer.empty; //sticky tag
150

151         try {
152             setTreeName (peer.getTreeName ());
153         } catch (Exception JavaDoc exc) {
154             throw new CannotMergeException (treeObject, exc);
155         }
156         
157         attributes.merge (peer.getAttributes ());
158         // attributes.setContentManager (this);
159
}
160     
161     
162     //
163
// read only
164
//
165

166     
167     /**
168      */

169     protected void setReadOnly (boolean newReadOnly) {
170         super.setReadOnly (newReadOnly);
171         
172         attributes.setReadOnly (newReadOnly);
173     }
174     
175     
176     //
177
// itself
178
//
179

180     /**
181      */

182     public final String JavaDoc getQName () {
183         return tagName.getQualifiedName ();
184     }
185     
186     /**
187      * @throws ReadOnlyException
188      * @throws InvalidArgumentException
189      */

190     public final void setQName (String JavaDoc newTagName) throws ReadOnlyException, InvalidArgumentException {
191         setTreeName (new TreeName (newTagName));
192     }
193     
194     /**
195      */

196     public final TreeName getTreeName () {
197         return tagName;
198     }
199     
200     /**
201      */

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     /**
211      * @throws ReadOnlyException
212      * @throws InvalidArgumentException
213      */

214     public final void setTreeName (TreeName newTagName) throws ReadOnlyException, InvalidArgumentException {
215         //
216
// check new value
217
//
218
if ( Util.equals (this.tagName, newTagName) )
219             return;
220         checkReadOnly ();
221         checkTagName (newTagName);
222         
223         //
224
// set new value
225
//
226
setTreeNameImpl (newTagName);
227     }
228     
229     /**
230      * Treat the empty flag as "sticky" is means that is someone
231      * adds some conetent and then remove it this flag will survive
232      * @return true it this element represents empty one
233      */

234     public boolean isEmpty () {
235         if (empty == false)
236             return false;
237         return getChildNodes ().size () == 0;
238     }
239     
240     /**
241      */

242     protected final void checkTagName (TreeName tagName) throws InvalidArgumentException {
243         TreeUtilities.checkElementTagName (tagName);
244     }
245     
246     
247     //
248
// Namespaces
249
//
250

251     
252     /**
253      */

254     protected final TreeNamespaceContext getNamespaceContext () {
255         return namespaceContext;
256     }
257     
258     /**
259      * @return element namespce or TreeNamespace.NO_NAMESPACE
260      */

261     public final TreeNamespace getNamespace () {
262         String JavaDoc prefix = getNamespacePrefix ();
263         String JavaDoc 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     /**
273      */

274     public final String JavaDoc getNamespacePrefix () {
275         return tagName.getPrefix ();
276     }
277     
278     
279     /**
280      */

281     public final String JavaDoc getNamespaceURI () {
282         return getNamespace ().getURI ();
283     }
284     
285     
286     /**
287      */

288     public final String JavaDoc getLocalName () {
289         return tagName.getName ();
290     }
291     
292     
293     
294     //
295
// Attributes
296
//
297

298     
299     /**
300      */

301     public final int getAttributesNumber () {
302         return (attributes.size ());
303     }
304     
305     /**
306      */

307     public final boolean hasAttributes () {
308         return ( attributes.size () != 0 );
309     }
310     
311     /**
312      */

313     public final boolean hasAttribute (String JavaDoc name) {
314         return ( getAttribute (name) != null );
315     }
316     
317     
318     /**
319      */

320     public final TreeNamedObjectMap getAttributes () {
321         return attributes;
322     }
323     
324     /**
325      */

326     public final TreeAttribute getAttribute (String JavaDoc 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     /**
336      * @throws InvalidArgumentException
337      * @throws ReadOnlyException
338      */

339     public final TreeAttribute addAttribute (String JavaDoc name, String JavaDoc value) throws ReadOnlyException, InvalidArgumentException {
340 //// Will be uncommented after NB 3.3.1 (http://www.netbeans.org/issues/show_bug.cgi?id=17699)
341
// TreeAttribute attr = getAttribute (name);
342
// if ( attr != null ) {
343
// throw new InvalidArgumentException
344
// (attr, Util.THIS.getString ("EXC_attribute_exists", name));
345
// }
346

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     /**
356      * @throws InvalidArgumentException
357      * @throws ReadOnlyException
358      */

359     public final void addAttribute (TreeAttribute newAttr) throws ReadOnlyException, InvalidArgumentException {
360         String JavaDoc qName = newAttr.getQName ();
361
362 //// Will be uncommented after NB 3.3.1 (http://www.netbeans.org/issues/show_bug.cgi?id=17699)
363
// TreeAttribute attr = getAttribute (qName);
364
// if ( attr != null ) {
365
// throw new InvalidArgumentException
366
// (attr, Util.THIS.getString ("EXC_attribute_exists", qName));
367
// }
368

369         checkReadOnly ();
370         TreeAttribute oldAttr = removeAttribute (qName);
371         attributes.add (newAttr);
372         // return oldAttr;
373
}
374     
375     
376     /**
377      * @throws ReadOnlyException
378      */

379     public final TreeAttribute removeAttribute (String JavaDoc name) throws ReadOnlyException {
380         return removeAttribute (getAttribute (name));
381     }
382     
383     
384     /**
385      * @throws ReadOnlyException
386      */

387     public final TreeAttribute removeAttribute (TreeAttribute oldAttr) throws ReadOnlyException {
388         checkReadOnly ();
389         attributes.remove (oldAttr);
390         return oldAttr;
391     }
392     
393     /**
394      * @throws ReadOnlyException
395      */

396     public final void removeAttributes () throws ReadOnlyException {
397         checkReadOnly ();
398         attributes.clear ();
399     }
400     
401     
402     //
403
// Utilities
404
//
405

406     /**
407      * @throws ReadOnlyException
408      */

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) { // from TreeText.appendChild : impossible because TreeText.getData
426
break; // get out from 'while (true)'
427
}
428                         } else {
429                             break; // get out from 'while (true)'
430
}
431                     }
432                 }
433             }
434         } catch (IndexOutOfBoundsException JavaDoc e) {
435             /* OK */
436         } finally {
437             getChildNodes ().getEventManager ().setFirePolicy (TreeEventManager.FIRE_NOW);
438         }
439     }
440     
441     
442     /**
443      */

444     public final boolean containsCharacterData () {
445         return containsCharacterData;
446     }
447     
448     /**
449      */

450     private void updateContainsCharacterData () {
451         Iterator JavaDoc it = getChildNodes ().iterator ();
452         while (it.hasNext ()) {
453             Object JavaDoc 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     //
473
// TreeObjectList.ContentManager
474
//
475

476     /**
477      */

478     protected TreeObjectList.ContentManager createChildListContentManager () {
479         return new ChildListContentManager ();
480     }
481     
482     
483     /**
484      */

485     protected TreeNamedObjectMap.ContentManager createAttributesContentManager () {
486         return new AttributesContentManager ();
487     }
488     
489     
490     /**
491      *
492      */

493     protected class ChildListContentManager extends TreeParentNode.ChildListContentManager {
494         
495         /**
496          */

497         public TreeNode getOwnerNode () {
498             return TreeElement.this;
499         }
500         
501         /**
502          */

503         public void checkAssignableObject (Object JavaDoc obj) {
504             super.checkAssignableObject (obj);
505             checkAssignableClass (Element.Child.class, obj);
506         }
507         
508     } // end: class ChildListContentManager
509

510     
511     /**
512      *
513      */

514     protected class AttributesContentManager extends TreeNamedObjectMap.ContentManager {
515         
516         /**
517          */

518         public TreeNode getOwnerNode () {
519             return TreeElement.this;
520         }
521         
522         /**
523          */

524         public void checkAssignableObject (Object JavaDoc obj) {
525             checkAssignableClass (Element.Attribute.class, obj);
526         }
527         
528         /**
529          */

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         /**
536          */

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         /**
543          */

544         public void orderChanged (int[] permutation) {
545             TreeElement.this.firePropertyChange (TreeElement.PROP_ATTRIBUTES, TreeElement.this.attributes, null);
546         }
547         
548     } // end: class AttributesContentManager
549

550 }
551
Popular Tags