KickJava   Java API By Example, From Geeks To Geeks.

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


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 org.openide.util.Task;
23 import org.openide.util.NbBundle;
24
25 /** Describes an entire Java source file.
26 * Note that there is no standard in-memory implementation of this element;
27 * every user of the class is expected to have a reasonable
28 * implementation according to where the source file resides.
29 * <p>The source element should be parsed in the background using
30 * {@link #prepare} before any attempts are made to access its properties
31 * to read or to write, or to call {@link #print};
32 * otherwise such accesses will block until the parse is finished.
33 * @author Petr Hamernik, Jaroslav Tulach
34 */

35 public final class SourceElement extends Element {
36     /** Status when the source element is not yet prepared.
37     */

38     public static final int STATUS_NOT = 0;
39     /** Status when the source element contains unrecoverable errors.
40     */

41     public static final int STATUS_ERROR = 1;
42     /** Status when the source element contains minor errors.
43     */

44     public static final int STATUS_PARTIAL = 2;
45     /** Status when the source element has been parsed and is error-free.
46     */

47     public static final int STATUS_OK = 3;
48
49     static final long serialVersionUID =-1439690719608070114L;
50
51     /** Create a new source element.
52     * @param impl the pluggable implementation
53     */

54     public SourceElement(Impl impl) {
55         super (impl);
56     }
57
58     /** @return implementation for the source
59     */

60     final Impl getSourceImpl () {
61         return (Impl)impl;
62     }
63
64     /** Get the parsing status of the element.
65     * This is a non-blocking operation.
66     * @return one of {@link #STATUS_NOT}, {@link #STATUS_ERROR}, {@link #STATUS_PARTIAL}, or {@link #STATUS_OK}
67     */

68     public int getStatus () {
69         return getSourceImpl ().getStatus ();
70     }
71
72     /** Begin parsing this source element.
73     * This method is non-blocking; it only returns
74     * a task that can be used to control the ongoing parse.
75     * Initially the {@link #getStatus} should be {@link #STATUS_NOT}, and change
76     * to one of the other three when parsing is complete, according to whether
77     * or not errors were encountered, and their severity.
78     *
79     * @return a task to control the preparation of the element
80     */

81     public Task prepare () {
82         return getSourceImpl ().prepare ();
83     }
84
85
86     // =========================== package section ============================
87

88     /** Set the package of this source file.
89     * @param id the package name, or <code>null</code> to use the default package
90     * @exception SourceException if the operation cannot proceed
91     */

92     public void setPackage (Identifier id) throws SourceException {
93         getSourceImpl ().setPackage (id);
94     }
95
96     /** Get the package of this source file.
97     * @return the package name, or <code>null</code> if this source file is in the default package
98     */

99     public Identifier getPackage () {
100         return getSourceImpl ().getPackage ();
101     }
102
103     // =========================== imports section ============================
104

105     /** Get all imports.
106     *
107     * @return the imports
108     */

109     public Import[] getImports() {
110         return getSourceImpl ().getImports ();
111     }
112
113     /** Set all imports.
114     * The old imports will be replaced.
115     * @param imprt the new imports
116     * @exception SourceException if the operation cannot proceed
117     */

118     public void setImports(Import[] imprt) throws SourceException {
119         getSourceImpl ().changeImports (imprt, Impl.SET);
120     }
121
122     /** Add an import.
123     * @param el the import to add
124     * @exception SourceException if the operation cannot proceed
125     */

126     public void addImport (Import el) throws SourceException {
127         getSourceImpl ().changeImports (
128             new Import[] { el }, Impl.ADD
129         );
130     }
131
132     /** Add some imports.
133     * @param els the imports to add
134     * @exception SourceException if the operation cannot proceed
135     */

136     public void addImports (final Import[] els) throws SourceException {
137         getSourceImpl ().changeImports (els, Impl.ADD);
138     }
139
140     /** Remove an import.
141     * @param el the import to remove
142     * @exception SourceException if the operation cannot proceed
143     */

144     public void removeImport (Import el) throws SourceException {
145         getSourceImpl ().changeImports (
146             new Import[] { el }, Impl.REMOVE
147         );
148     }
149
150     /** Remove some imports.
151     * @param els the imports to remove
152     * @exception SourceException if the operation cannot proceed
153     */

154     public void removeImports (final Import[] els) throws SourceException {
155         getSourceImpl ().changeImports (els, Impl.REMOVE);
156     }
157
158     //================== Top-level classes ==========================
159

160     /** Add a new top-level class.
161     * @param el the top-level class to add
162     * @throws SourceException if impossible
163     */

164     public void addClass (ClassElement el) throws SourceException {
165         Identifier id = Identifier.create(el.getName().getName());
166         if (getClass(id) != null)
167             throwAddException("FMT_EXC_AddClassToSource", el); // NOI18N
168
getSourceImpl ().changeClasses (new ClassElement[] { el }, Impl.ADD);
169     }
170
171     /** Add some new top-level classes.
172     * @param els the top-level classes to add
173     * @throws SourceException if impossible
174     */

175     public void addClasses (final ClassElement[] els) throws SourceException {
176         Identifier id;
177         
178         for (int i = 0; i < els.length; i++) {
179             id = Identifier.create(els[i].getName().getName());
180             if (getClass(id) != null)
181                 throwAddException("FMT_EXC_AddClassToSource", els[i]); // NOI18N
182
}
183         getSourceImpl ().changeClasses (els, Impl.ADD);
184     }
185
186     /** This method just throws localized exception. It is used during
187     * adding class element, which already exists in source.
188     * @param formatKey The message format key to localized bundle.
189     * @param element The element which can't be added
190     * @exception SourceException is alway thrown from this method.
191     */

192     private void throwAddException(String JavaDoc formatKey, ClassElement element) throws SourceException {
193     String JavaDoc msg = NbBundle.getMessage(ElementFormat.class, formatKey,
194         element.getName().getName());
195         throwSourceException(msg);
196     }
197
198     /** Remove an top-level class.
199     * @param el the top-level class to remove
200     * @throws SourceException if impossible
201     */

202     public void removeClass (ClassElement el) throws SourceException {
203         getSourceImpl ().changeClasses (new ClassElement[] { el }, Impl.REMOVE);
204     }
205
206     /** Remove some top-level classes.
207     * @param els the top-level classes to remove
208     * @throws SourceException if impossible
209     */

210     public void removeClasses (final ClassElement[] els) throws SourceException {
211         getSourceImpl ().changeClasses (els, Impl.REMOVE);
212     }
213
214     /** Set the top-level classes.
215     * The old ones will be replaced.
216     * @param els the new top-level classes
217     * @throws SourceException if impossible
218     */

219     public void setClasses (ClassElement[] els) throws SourceException {
220         getSourceImpl ().changeClasses (els, Impl.SET);
221     }
222
223     /** Get the top-level classes.
224     * @return all top-level classes
225     */

226     public ClassElement[] getClasses () {
227         return getSourceImpl ().getClasses ();
228     }
229
230     /** Find a top-level class by name.
231     * @param name the name to look for
232     * @return the class, or <code>null</code> if it does not exist
233     */

234     public ClassElement getClass (Identifier name) {
235         return getSourceImpl ().getClass (name);
236     }
237
238     /** Get all classes recursively, both top-level and inner.
239     * @return all classes
240     */

241     public ClassElement[] getAllClasses () {
242         return getSourceImpl ().getAllClasses ();
243     }
244
245     /* Prints the element into the element printer.
246     * @param printer The element printer where to print to
247     * @exception ElementPrinterInterruptException if printer cancel the printing
248     */

249     public void print(ElementPrinter printer) throws ElementPrinterInterruptException {
250         Identifier pack = getPackage();
251         if (pack != null) {
252             printer.print("package "); // NOI18N
253
printer.print(pack.getFullName());
254             printer.println(";"); // NOI18N
255
printer.println(""); // NOI18N
256
}
257
258         Import[] imp = getImports();
259         for(int i = 0; i < imp.length; i++) {
260             printer.print(imp[i].toString());
261             printer.println(";"); // NOI18N
262
}
263         if (imp.length > 0)
264             printer.println(""); // NOI18N
265

266         print(getClasses(), printer);
267     }
268
269     /** Lock the underlaing document to have exclusive access to it and could make changes
270     * on this SourceElement.
271     *
272     * @param run the action to run
273     */

274     public void runAtomic (Runnable JavaDoc run) {
275         getSourceImpl ().runAtomic(run);
276     }
277
278     /** Executes given runnable in "user mode" does not allowing any modifications
279     * to parts of text marked as guarded. The actions should be run as "atomic" so
280     * either happen all at once or none at all (if a guarded block should be modified).
281     *
282     * @param run the action to run
283     * @exception SourceException if a modification of guarded text occured
284     * and that is why no changes to the document has been done.
285     */

286     public void runAtomicAsUser (Runnable JavaDoc run) throws SourceException {
287         getSourceImpl ().runAtomicAsUser(run);
288     }
289
290     /** Pluggable behaviour for source elements.
291     * @see SourceElement
292     */

293     public static interface Impl extends Element.Impl {
294         /** Add some top-level classes. */
295         public static final int ADD = ClassElement.Impl.ADD;
296         /** Remove some top-level classes. */
297         public static final int REMOVE = ClassElement.Impl.REMOVE;
298         /** Set the top-classes. */
299         public static final int SET = ClassElement.Impl.SET;
300
301         /** @deprecated Only public by accident. */
302         /* public static final */ long serialVersionUID = -2181228658756563166L;
303
304         /** Get the parsing status of the element.
305          * This is a non-blocking operation.
306          * @return one of {@link #STATUS_NOT}, {@link #STATUS_ERROR}, {@link #STATUS_PARTIAL}, or {@link #STATUS_OK}
307          */

308         public int getStatus ();
309
310
311         /** Begin parsing this source element.
312          * This method is non-blocking; it only returns
313          * a task that can be used to control the ongoing parse.
314          * Initially the {@link #getStatus} should be {@link #STATUS_NOT}, and change
315          * to one of the other three when parsing is complete, according to whether
316          * or not errors were encountered, and their severity.
317          *
318          * @return a task to control the preparation of the element
319          */

320         public Task prepare ();
321
322         /** Set the package of this source file.
323          * @param id the package name, or <code>null</code> to use the default package
324          * @exception SourceException if the operation cannot proceed
325          */

326         public void setPackage (Identifier id) throws SourceException;
327
328         /** Get the package of this source file.
329          * @return the package name, or <code>null</code> if this source file is in the default package
330          */

331         public Identifier getPackage ();
332
333         // =========================== imports section ============================
334

335         /** Get all imports.
336          *
337          * @return the imports
338          */

339         public Import[] getImports();
340
341
342         /** Change the set of imports.
343         * @param elems the imports to change
344         * @param action one of {@link #ADD}, {@link #REMOVE}, or {@link #SET}
345         * @exception SourceException if the action cannot be handled
346         */

347         public void changeImports (Import[] elems, int action) throws SourceException;
348
349
350         /** Change the set of top-level classes.
351         * @param elems the classes to change
352         * @param action one of {@link #ADD}, {@link #REMOVE}, or {@link #SET}
353         * @exception SourceException if the action cannot be handled
354         */

355         public void changeClasses (ClassElement[] elems, int action) throws SourceException;
356
357         /** Get all top-level classes.
358         * @return the classes
359         */

360         public ClassElement[] getClasses ();
361
362         /** Find a top-level class by name.
363         * @param name the name to look for
364         * @return the class, or <code>null</code> if it does not exist
365         */

366         public ClassElement getClass (Identifier name);
367
368         /** Get all classes recursively, both top-level and inner.
369          * @return all classes
370          */

371         public ClassElement[] getAllClasses ();
372
373         /** Lock the underlaing document to have exclusive access to it and could make changes
374         * on this SourceElement.
375         *
376         * @param run the action to run
377         */

378         public void runAtomic (Runnable JavaDoc run);
379
380         /** Executes given runnable in "user mode" does not allowing any modifications
381         * to parts of text marked as guarded. The actions should be run as "atomic" so
382         * either happen all at once or none at all (if a guarded block should be modified).
383         *
384         * @param run the action to run
385         * @exception SourceException if a modification of guarded text occured
386         * and that is why no changes to the document has been done.
387         */

388         public void runAtomicAsUser (Runnable JavaDoc run) throws SourceException;
389     }
390
391 }
392
Popular Tags