KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > codegen > SourceText


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.modules.java.codegen;
21
22 import java.lang.ref.*;
23 import java.io.IOException JavaDoc;
24 import java.util.*;
25
26 import javax.swing.text.BadLocationException JavaDoc;
27 import javax.swing.text.Position JavaDoc;
28 import javax.swing.text.StyledDocument JavaDoc;
29 import javax.swing.undo.UndoableEdit JavaDoc;
30
31 import org.openide.awt.UndoRedo;
32 import org.openide.src.*;
33 import org.openide.text.CloneableEditorSupport;
34 import org.openide.text.NbDocument;
35 import org.openide.text.PositionBounds;
36 import org.openide.text.PositionRef;
37 import org.openide.ErrorManager;
38
39 import org.netbeans.modules.java.bridge.Binding;
40 import org.netbeans.modules.java.bridge.BindingFactory;
41 import org.netbeans.modules.java.bridge.ImportElement;
42
43 /**
44  * Source is not, in fact, a Binding, but provides context to the editing operations.
45  * It should manage locking, interactions with the outside environment and protection
46  * management.<P>
47  *
48  * @author Svatopluk Dedic <mailto:sdedic@netbeans.org>
49  * @version 0.1
50  */

51 public class SourceText implements DocumentBinding {
52     /** True, if runAtomics should be, in fact, runAtomicAsUser.
53      */

54     int isAtomicAsUser;
55
56     /** Support for editing documents.
57      */

58     CloneableEditorSupport editSupport;
59     
60     /**
61      * Undo manager to register undo events with.
62      */

63     Env environment;
64     
65     /**
66      * Yes/no flag whether the whole generator is enabled. Parser updater, for example,
67      * disables the code generator while it updates the source model, so the discovered
68      * changes are not reflected back to the text.
69      */

70     boolean generatorEnabled;
71     
72     /**
73      * An object used to lock tree of javax.swing.text.Elements or Bindings during
74      * updates & reads.
75      */

76     Object JavaDoc treeLock;
77     
78     /**
79      * Binding of the SourceElement, held by a WeakReference. Since the binding
80      * is held exclusively by SourceElement.Impl implementation, it may be freed along
81      * with the implementation (or according to the implementation memory policy).
82      */

83     Reference refSourceRoot;
84
85     Map bindingMap;
86     
87     
88     public SourceText(Env sourceEnvironment) {
89         this.environment = sourceEnvironment;
90         treeLock = new Object JavaDoc();
91     }
92     
93     public Element getElement() {
94         return null;
95     }
96     
97     protected SourceB getRoot() {
98         synchronized (this) {
99             if (refSourceRoot == null)
100                 return null;
101             Object JavaDoc r = refSourceRoot.get();
102             if (r == null)
103                 refSourceRoot = null;
104             return (SourceB)r;
105         }
106     }
107     
108     public CloneableEditorSupport getEditorSupport() {
109         if (editSupport == null)
110             editSupport = environment.findEditorSupport();
111         return editSupport;
112     }
113     
114     protected synchronized void registerBinding(Element el, ElementBinding b) {
115         if (bindingMap == null) {
116             bindingMap = new WeakHashMap(37);
117         }
118         bindingMap.put(el, new WeakReference(b));
119     }
120
121     /**
122      * Enters or leaves user-mode of document editing. If the document contains
123      * some user-protected text, all changes to the text will be disallowed in
124      * the user mode.
125      */

126     public void enableAtomicAsUser(boolean enable) {
127         if (enable)
128             isAtomicAsUser++;
129         else
130             isAtomicAsUser--;
131     }
132     
133     public void enableGenerator(boolean enable) {
134         generatorEnabled = enable;
135     }
136     
137     public boolean isGeneratorEnabled() {
138         return generatorEnabled;
139     }
140     
141     
142     /**
143      * Retrieves a document for the I/O operations. The method can throw
144      * IOException wrapped into a SourceException, if the operation fails.
145      */

146     public StyledDocument JavaDoc getDocument() throws SourceException {
147         try {
148             return getEditorSupport().openDocument();
149         } catch (IOException JavaDoc ex) {
150             rethrowException(ex);
151         }
152         return null;
153     }
154     
155     public Element findElement(int position) {
156         SourceB sb = getRoot();
157         if (sb == null)
158             return null;
159         synchronized (getTreeLock()) {
160             ElementBinding b = sb.findBindingAt(position);
161             if (b == null)
162                 return null;
163             return b.getElement();
164         }
165     }
166     
167     public boolean isAtomicAsUser() {
168         return this.isAtomicAsUser > 0;
169     }
170     
171     public void runAtomic(final Runnable JavaDoc r) throws SourceException {
172         runAtomic(null, r);
173     }
174     
175     private void checkWritable(Element el) throws IOException JavaDoc {
176         environment.takeLock();
177     }
178
179     private void runAtomic(Element el, final Runnable JavaDoc r) throws SourceException {
180        final Exception JavaDoc[] exc = new Exception JavaDoc[1];
181        try {
182            checkWritable(el);
183            if (isAtomicAsUser()) {
184                NbDocument.runAtomicAsUser(getDocument(), r);
185            } else {
186                NbDocument.runAtomic(getDocument(), r);
187            }
188        } catch (RuntimeException JavaDoc ex) {
189            throw ex;
190        } catch (Exception JavaDoc ex) {
191            exc[0] = ex;
192        }
193        rethrowException(el, exc[0]);
194     }
195     
196     public void updateBindings(Runnable JavaDoc r) {
197         synchronized (getTreeLock()) {
198             r.run();
199         }
200     }
201     
202     protected Object JavaDoc getTreeLock() {
203         return treeLock;
204     }
205
206     protected static void rethrowException(Exception JavaDoc ex) throws SourceException {
207         rethrowException(null, ex);
208     }
209     
210     protected static void rethrowException(Element el, Exception JavaDoc ex) throws SourceException {
211         if (ex == null)
212             return;
213
214         ErrorManager man = ErrorManager.getDefault();
215         SourceException x;
216         
217         if (ex instanceof BadLocationException JavaDoc) {
218            x = new SourceException.Protection(el);
219            man.annotate(x, ErrorManager.USER, null, ex.getLocalizedMessage(),
220             ex, null);
221         } else if (ex instanceof IOException JavaDoc) {
222            x = new SourceException.IO((IOException JavaDoc)ex);
223            man.annotate(x, ErrorManager.USER, null, ex.getLocalizedMessage(), ex, null);
224         } else if (ex instanceof SourceException) {
225            x = (SourceException)ex;
226         } else {
227            // PENDING: annotate the exception with the old one!
228
x = new SourceException();
229            man.annotate(x, ex);
230         }
231         throw x;
232     }
233     
234     public void runAtomic(final Element el, final ExceptionRunnable r) throws SourceException {
235         final Exception JavaDoc[] exc = new Exception JavaDoc[1];
236         try {
237             checkWritable(el);
238         } catch (IOException JavaDoc ex) {
239             rethrowException(el, ex);
240         }
241         Runnable JavaDoc r2 = new Runnable JavaDoc() {
242             public void run() {
243                 //environment.notifyBeginEdit();
244
try {
245                     r.run();
246                 } catch (Exception JavaDoc ex) {
247                     exc[0] = ex;
248                     throw new IllegalStateException JavaDoc();
249                 } finally {
250                     //environment.notifyEndEdit();
251
}
252             }
253        };
254        StyledDocument JavaDoc doc = getDocument();
255        if (isAtomicAsUser()) {
256            try {
257                 NbDocument.runAtomicAsUser(doc, r2);
258            } catch (BadLocationException JavaDoc ex) {
259                exc[0] = ex;
260            } catch (IllegalStateException JavaDoc ex) {
261            }
262        } else {
263            try {
264                 NbDocument.runAtomic(doc, r2);
265            } catch (IllegalStateException JavaDoc ex) {
266                // swallow - rethrow the runnable's exception instead.
267
}
268        }
269        rethrowException(el, exc[0]);
270     }
271     
272     protected PositionRef createPos(int offset, Position.Bias JavaDoc bias) {
273         return getEditorSupport().createPositionRef(offset, bias);
274     }
275     
276     protected synchronized ElementBinding findBinding(Element e) {
277         if (bindingMap == null)
278             return null;
279         Reference r = (Reference)bindingMap.get(e);
280         if (r == null)
281             return null;
282         return (ElementBinding)r.get();
283     }
284     
285     protected boolean canWriteInside(PositionBounds bounds) {
286         return environment.findFreePosition(bounds) != null;
287     }
288     
289     protected PositionRef findFreePosition(PositionBounds bounds) {
290         return environment.findFreePosition(bounds);
291     }
292     
293     public Binding.Field bindField(FieldElement impl) {
294         return new FieldB(impl, this);
295     }
296     
297     public Binding.Method bindMethod(MethodElement impl) {
298         return new Method(impl, this);
299     }
300     
301     public Binding.Method bindConstructor(ConstructorElement impl) {
302         return new Method(impl, this);
303     }
304     
305     public Binding.Class bindClass(ClassElement impl) {
306         return new Clazz(impl, this);
307     }
308     
309     public Binding.Initializer bindInitializer(InitializerElement impl) {
310         return new Initializer(impl, this);
311     }
312     
313     public Binding.Import bindImport(ImportElement impl) {
314         return new ImportB(impl, this);
315     }
316     
317     public Binding.Source bindSource(SourceElement impl) {
318         SourceB sb = new SourceB(impl, this);
319         this.refSourceRoot = new WeakReference(sb);
320         return sb;
321     }
322     
323     public void dumpDocument() {
324         System.err.println("Document dump:"); // NOI18N
325
final StyledDocument JavaDoc doc = getEditorSupport().getDocument();
326         doc.render(new Runnable JavaDoc() {
327             public void run() {
328                 try {
329                     String JavaDoc s = doc.getText(0, doc.getLength());
330                     System.err.println(s);
331                 } catch (Exception JavaDoc ex) {
332                 }
333             }
334         });
335     }
336 }
337
Popular Tags