KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > src > Element


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.openide.src;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.beans.PropertyChangeSupport JavaDoc;
25 import java.beans.PropertyVetoException JavaDoc;
26 import java.beans.VetoableChangeListener JavaDoc;
27 import java.beans.VetoableChangeSupport JavaDoc;
28 import java.io.PrintWriter JavaDoc;
29 import java.io.Serializable JavaDoc;
30 import java.io.StringWriter JavaDoc;
31 import javax.swing.JEditorPane JavaDoc;
32 import javax.swing.text.DefaultEditorKit JavaDoc;
33 import javax.swing.text.Document JavaDoc;
34 import javax.swing.text.EditorKit JavaDoc;
35 import javax.swing.text.StyledDocument JavaDoc;
36 import org.openide.ErrorManager;
37 import org.openide.nodes.Node;
38 import org.openide.text.FilterDocument;
39 import org.openide.text.IndentEngine;
40
41 /** Base class for representations of elements in the
42 * Java language.
43 * All elements are items which are structural features of a class (or the class itself),
44 * rather than corresponding to bytecode (i.e. statements are not represented).
45 * The same representation is suited to any language using the Java VM.
46 *
47 * @author Jaroslav Tulach, Petr Hamernik, Svatopluk Dedic
48 */

49 public abstract class Element extends Object JavaDoc
50     implements Serializable JavaDoc, ElementProperties, Node.Cookie {
51
52     /** Implementation */
53     protected Impl impl;
54     
55     /** Implementation extension #2 */
56     protected Impl2 impl2;
57
58     static final long serialVersionUID =967040188302141522L;
59     /** Create a new element with the provided implementation. The implementation is
60     * responsible for storing all properties of the object.
61     *
62     * @param impl the implementation to use
63     */

64     protected Element(Impl impl) {
65         this.impl = impl;
66         if (impl instanceof Impl2) {
67             this.impl2 = (Impl2)impl;
68         }
69         impl.attachedToElement (this);
70     }
71
72     /** Add a property change listener.
73     * @param l the listener to add
74     * @see ElementProperties
75     */

76     public final void addPropertyChangeListener (PropertyChangeListener JavaDoc l) {
77         impl.addPropertyChangeListener (l);
78     }
79
80     /** Remove a property change listener.
81     * @param l the listener to remove
82     * @see ElementProperties
83     */

84     public final void removePropertyChangeListener (PropertyChangeListener JavaDoc l) {
85         impl.removePropertyChangeListener (l);
86     }
87     
88     /**
89      * Attaches a VetoableChange listener to the element.
90      * The Listener will be notified about changes being done before the change is
91      * actually done.
92      * @param l instance of listener to attach.
93      */

94     public final void addVetoableChangeListener(VetoableChangeListener JavaDoc l) {
95         if (impl2 != null)
96             impl2.addVetoableChangeListener(l);
97     }
98
99     /**
100      * Removes the vetoable listener from the element.
101      * @param l listener to remove.
102      */

103     public final void removeVetoableChangeListener(VetoableChangeListener JavaDoc l) {
104         if (impl2 != null)
105             impl2.removeVetoableChangeListener(l);
106     }
107
108     /** Mark the current element in the context of this element.
109     * The current element means the position for inserting new elements.
110     * @param beforeAfter <CODE>true</CODE> means that new element is inserted before
111     * the specified element, <CODE>false</CODE> means after.
112     */

113     public void markCurrent(boolean beforeAfter) {
114         impl.markCurrent(beforeAfter);
115     }
116
117     /** Look for a cookie providing added behavior for this element.
118     * The request is {@link Impl#getCookie delegated} to the current implementation.
119     * Also note that <code>Element</code> implements <code>Node.Cookie</code>, and that
120     * if the implementation does not provide a cookie, but the requested cookie class is
121     * actually a superclass/interface of this element type, then the element itself may be
122     * returned as the cookie.
123     * @param type the cookie class to look for
124     * @return a cookie assignable to that class, or <code>null</code> if the cookie
125     * is not supported
126     */

127     public Node.Cookie getCookie(Class JavaDoc type) {
128         Node.Cookie c = impl.getCookie(type);
129         if ((c == null) && type.isAssignableFrom(getClass()))
130             c = this;
131
132         return c;
133     }
134
135     protected Object JavaDoc writeReplace() {
136         return impl;
137     }
138
139     /** Print this element (and all its subelements) into an element printer.
140     * @param printer the element printer
141     * @exception ElementPrinterInterruptException if the printer canceled the printing
142     */

143     public abstract void print(ElementPrinter printer) throws ElementPrinterInterruptException;
144
145     /** Prints array of elements.
146     * @param el the elements
147     * @param printer The printer where to write
148     * @return true if at least one element was printed
149     * @exception ElementPrinterInterruptException if printer cancel the printing
150     */

151     static boolean print(Element[] el, ElementPrinter printer) throws ElementPrinterInterruptException {
152         for (int i = 0; i < el.length; i++) {
153             if (i > 0) {
154                 printer.println(""); // NOI18N
155
printer.println(""); // NOI18N
156
}
157             el[i].print(printer);
158         }
159         return (el.length > 0);
160     }
161
162     /** Prints the javadoc to the printer.
163     * It calls doc.getRawText() and inserts the '*' symbols to the begins
164     * of lines.
165     * @param doc The printed javadoc
166     * @param printer The printer where to write
167     * @exception ElementPrinterInterruptException if printer cancel the printing
168     */

169     static void printJavaDoc(JavaDoc doc, ElementPrinter printer) throws ElementPrinterInterruptException {
170         if (doc.isEmpty())
171             return;
172
173         //PENDING: should be more customizable
174
String JavaDoc javaText = doc.getRawText();
175         String JavaDoc lines[]=javaText.split("\\n"); // NOI18N
176
int i;
177         
178         printer.print("/**\n");
179         for (i=0;i<lines.length;i++) {
180             String JavaDoc line=lines[i];
181
182             printer.print("*");
183             if (line.length() > 0 && line.charAt(0) != ' ')
184                 printer.print(" ");
185             printer.println(line);
186         }
187         printer.print(" */"); // NOI18N
188
}
189
190     /** Helper method. User for creating document that perform better formatting if there's an
191      * EditorKit registered for the Java MIME type and supports indentation engine.
192      * @return document that can be used for Java code generation
193      */

194     StyledDocument JavaDoc createDocument() {
195     EditorKit JavaDoc kit = JEditorPane.createEditorKitForContentType("text/x-java"); // NOI18N
196
if (kit == null) {
197         kit = new DefaultEditorKit JavaDoc();
198     }
199     Document JavaDoc doc = kit.createDefaultDocument();
200     if (doc instanceof StyledDocument JavaDoc) {
201         return (StyledDocument JavaDoc)doc;
202     }
203     return new FilterDocument(doc);
204     }
205     
206     /** Helper method that properly annotates an exception.
207      * @param message used for human-readable explanation of the exception.
208      */

209     void throwSourceException(String JavaDoc message) throws SourceException {
210     SourceException ex = new SourceException(message);
211         ErrorManager.getDefault().annotate(ex, ErrorManager.USER, null, message, null, null);
212     throw ex;
213     }
214     
215     void throwSourceException(Throwable JavaDoc nested) throws SourceException {
216     SourceException ex = new SourceException(nested.getMessage());
217     ErrorManager.getDefault().annotate(ex, nested);
218     throw ex;
219     }
220
221     /** Get a string representation of the element.
222     * @return the string
223     * @see #print
224     * @see DefaultElementPrinter
225     */

226     public String JavaDoc toString() {
227         StringWriter JavaDoc sw = new StringWriter JavaDoc();
228     StyledDocument JavaDoc doc = createDocument();
229         IndentEngine indentator = IndentEngine.find(doc);
230         PrintWriter JavaDoc pw = new PrintWriter JavaDoc(indentator.createWriter(doc, 0, sw));
231         // PrintWriter pw = new PrintWriter(sw);
232
try {
233             print(new DefaultElementPrinter(pw));
234         }
235         catch (ElementPrinterInterruptException e) {
236             // could not happen.
237
}
238         pw.close();
239         return sw.toString();
240     }
241
242     /** Pluggable implementation of the storage of element properties.
243     * @see Element#Element
244     */

245     public interface Impl extends Serializable JavaDoc {
246         /** @deprecated Only public by accident. */
247         /* public static final */ long serialVersionUID = -3246061193296761293L;
248         /** Called to attach the implementation to a specific
249         * element. Will be called in the element's constructor.
250         * Allows implementors
251         * of this interface to store a reference to the holder class,
252         * useful for implementing the property change listeners.
253         *
254         * @param el the element to attach to
255         */

256         public void attachedToElement (Element el);
257
258         /** Add a property change listener.
259         * @param l the listener to add
260         */

261         public void addPropertyChangeListener (PropertyChangeListener JavaDoc l);
262
263         /** Remove a property change listener.
264         * @param l the listener to remove
265         */

266         public void removePropertyChangeListener (PropertyChangeListener JavaDoc l);
267         
268         /** Implementations must be resolvable.
269         * I.e., upon deserialization they must be able to recreate the
270         * holder class.
271         * @return an instance of the proper subclass of {@link Element}
272         * @see Serializable
273         */

274         public Object JavaDoc readResolve();
275
276         /** Get the support for a cookie, if any.
277         * Changes of supported cookies are <em>not</em> fired.
278         *
279         * @param type the cookie class to look for
280         * @return an instance assignable to that class, or <code>null</code> if the cookie
281         * is not supported
282         */

283         public Node.Cookie getCookie(Class JavaDoc type);
284
285         /** Mark the current element in the context of this element.
286         * The current element means the position for inserting new elements.
287         * @param beforeAfter <CODE>true</CODE> means that new element is inserted before
288         * the specified element, <CODE>false</CODE> means after.
289         */

290         public void markCurrent(boolean beforeAfter);
291     }
292
293     /**
294      * Extended version of the implementation interface. The new version contains
295      * support for vetoable listeners for all Elements and some more for specialized
296      * ones.
297      * @author Svatopluk Dedic
298      * @since 24/11/2000
299      */

300     public interface Impl2 extends Impl {
301         /** Adds a vetoable listener.
302          * @param l instener instance to add.
303          */

304         public void addVetoableChangeListener(VetoableChangeListener JavaDoc l);
305         
306         /** Removes a vetoable listener.
307          * @param l instener instance to remove.
308          */

309         public void removeVetoableChangeListener(VetoableChangeListener JavaDoc l);
310
311         /**
312          * Determines whether the element is still valid - if it is a part of its original model.
313          * The Element should be invalidated during its removal from the model so further
314          * operations may notice that and fail in appropriate cases.
315          * @return true, if the element is still valid and a part of a model.
316          */

317         public boolean isValid();
318     }
319
320     /** Default implementation of the Impl interface.
321     * It just holds the property values.
322     */

323     static abstract class Memory implements Element.Impl2, Node.Cookie {
324         /** the element for this implementation */
325         protected Element element;
326
327         /** Property change support */
328         private PropertyChangeSupport JavaDoc support;
329         
330         /**
331          * VetoableChange Support.
332          */

333         private VetoableChangeSupport JavaDoc vetoSupport;
334
335         static final long serialVersionUID =7734412320645883859L;
336         /** Attaches to element */
337         public void attachedToElement (Element element) {
338             this.element = element;
339         }
340
341         /** Fires property change event.
342         * @param name property name
343         * @param o old value
344         * @param n new value
345         */

346         protected final void firePropertyChange (String JavaDoc name, Object JavaDoc o, Object JavaDoc n) {
347             if (support != null) {
348                 support.firePropertyChange (name, o, n);
349             }
350         }
351         
352         protected final void firePropertyChange(PropertyChangeEvent JavaDoc evt) {
353             if (support != null)
354                 support.firePropertyChange(evt);
355         }
356
357         /** Adds property listener */
358         public synchronized void addPropertyChangeListener (PropertyChangeListener JavaDoc l) {
359             if (support == null) {
360                 synchronized (this) {
361                     // new test under synchronized block
362
if (support == null) {
363                         support = new PropertyChangeSupport JavaDoc (element);
364                     }
365                 }
366             }
367             support.addPropertyChangeListener (l);
368         }
369
370         /** Removes property listener */
371         public void removePropertyChangeListener (PropertyChangeListener JavaDoc l) {
372             if (support != null) {
373                 support.removePropertyChangeListener (l);
374             }
375         }
376
377         public void addVetoableChangeListener(VetoableChangeListener JavaDoc l) {
378             if (vetoSupport == null) {
379                 synchronized (this) {
380                     if (vetoSupport == null)
381                         vetoSupport = new VetoableChangeSupport JavaDoc(this);
382                 }
383             }
384             vetoSupport.addVetoableChangeListener(l);
385         }
386
387         public void removeVetoableChangeListener(VetoableChangeListener JavaDoc l) {
388             if (vetoSupport != null)
389                 vetoSupport.removeVetoableChangeListener(l);
390         }
391         
392         protected void fireVetoableChange(String JavaDoc name, Object JavaDoc o, Object JavaDoc v) throws PropertyVetoException JavaDoc {
393             if (vetoSupport != null)
394                 vetoSupport.fireVetoableChange(name, o, v);
395         }
396         
397         protected void fireVetoableChange(PropertyChangeEvent JavaDoc evt) throws PropertyVetoException JavaDoc {
398             if (vetoSupport != null)
399                 vetoSupport.fireVetoableChange(evt);
400         }
401
402         /** This implementation returns always null.
403         * @param type the class to look for
404         * @return null.
405         */

406         public Node.Cookie getCookie(Class JavaDoc type) {
407             if (type.isAssignableFrom(getClass())) {
408               return this;
409             } else {
410               return null;
411             }
412         }
413
414         /** Mark the current element in the context of this element.
415         * The current element means the position for inserting new elements.
416         * @param beforeAfter <CODE>true</CODE> means that new element is inserted before
417         * the specified element, <CODE>false</CODE> means after.
418         */

419         public void markCurrent(boolean beforeAfter) {
420             //PENDING
421
}
422         
423         public boolean isValid() {
424             return true;
425         }
426     }
427 }
428
Popular Tags