KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > rice > cs > drjava > model > DefaultLightWeightParsingControl


1 /*BEGIN_COPYRIGHT_BLOCK
2  *
3  * This file is part of DrJava. Download the current version of this project from http://www.drjava.org/
4  * or http://sourceforge.net/projects/drjava/
5  *
6  * DrJava Open Source License
7  *
8  * Copyright (C) 2001-2005 JavaPLT group at Rice University (javaplt@rice.edu). All rights reserved.
9  *
10  * Developed by: Java Programming Languages Team, Rice University, http://www.cs.rice.edu/~javaplt/
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13  * documentation files (the "Software"), to deal with the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
15  * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16  *
17  * - Redistributions of source code must retain the above copyright notice, this list of conditions and the
18  * following disclaimers.
19  * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
20  * following disclaimers in the documentation and/or other materials provided with the distribution.
21  * - Neither the names of DrJava, the JavaPLT, Rice University, nor the names of its contributors may be used to
22  * endorse or promote products derived from this Software without specific prior written permission.
23  * - Products derived from this software may not be called "DrJava" nor use the term "DrJava" as part of their
24  * names without prior written permission from the JavaPLT group. For permission, write to javaplt@rice.edu.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
27  * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28  * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
29  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30  * WITH THE SOFTWARE.
31  *
32 END_COPYRIGHT_BLOCK*/

33
34 package edu.rice.cs.drjava.model;
35
36 import java.util.List JavaDoc;
37 import java.util.LinkedList JavaDoc;
38 import java.util.Hashtable JavaDoc;
39 import javax.swing.text.*;
40
41 import edu.rice.cs.drjava.DrJava;
42 import edu.rice.cs.drjava.config.OptionConstants;
43 import edu.rice.cs.drjava.model.definitions.*;
44 import edu.rice.cs.util.Log;
45 import edu.rice.cs.util.swing.Utilities;
46
47 /** Default light-weight parsing control.
48  * @version $Id$
49  */

50 public class DefaultLightWeightParsingControl implements LightWeightParsingControl {
51   /** The model. */
52   private AbstractGlobalModel _model;
53   
54   /** The time at which updates may be performed. */
55   private long _beginUpdates;
56   
57   /** The time at which the last delay operation was performed. */
58   private long _lastDelay = System.currentTimeMillis();
59   
60   /** Last updates for the documents. */
61   private Hashtable JavaDoc<OpenDefinitionsDocument, Long JavaDoc> _lastUpdates = new Hashtable JavaDoc<OpenDefinitionsDocument, Long JavaDoc>();
62   
63   /** Enclosing class names for the documents. */
64   private Hashtable JavaDoc<OpenDefinitionsDocument, String JavaDoc> _enclosingClassNames = new Hashtable JavaDoc<OpenDefinitionsDocument, String JavaDoc>();
65   
66   /** Flag to stop automatic updates. */
67   private volatile boolean _running = false;
68   
69   /** Monitor to restart automatic updates. */
70   private Object JavaDoc _restart = new Object JavaDoc();
71   
72   /** List of listeners. */
73   private LinkedList JavaDoc<LightWeightParsingListener> _listeners = new LinkedList JavaDoc<LightWeightParsingListener>();
74   
75   /** Log file. */
76   private static final Log _log = new Log("LightWeightParsing", false);
77   
78   /** Thread group for the updater. */
79   private ThreadGroup JavaDoc _updaterThreadGroup = new ThreadGroup JavaDoc("Light-weight parsing updater thread group") {
80     public void uncaughtException(Thread JavaDoc t, Throwable JavaDoc e) {
81       _log.log("Uncaught exception in updater; disabled for rest of session", e);
82       new edu.rice.cs.drjava.ui.DrJavaErrorHandler().handle(e);
83     }
84   };
85   
86   /** Thread to perform automatic updates. */
87   private Thread JavaDoc _updater = new Thread JavaDoc(_updaterThreadGroup, new Runnable JavaDoc() {
88     public void run() {
89       while(true) { // this is ok, it's a daemon thread and will die when all other threads have died
90
while (!_running) {
91           _log.log("Waiting...");
92           try {
93             synchronized(_restart) {
94               if (!_running) {
95                 _restart.wait();
96               }
97             }
98           }
99           catch(InterruptedException JavaDoc e) { }
100         }
101         long current = System.currentTimeMillis();
102         long delta = (_beginUpdates-current);
103         // _log.logTime("Begin updates at "+_beginUpdates+" (delta="+delta+")");
104
if (current>=_beginUpdates) {
105           OpenDefinitionsDocument doc = _model.getActiveDocument();
106           Long JavaDoc last = _lastUpdates.get(doc);
107           if ((last==null) || (last<_lastDelay)) {
108             update(doc);
109             // _log.logTime("Update done.");
110
}
111           else {
112             // _log.logTime("Not updating, last update was at "+last);
113
}
114           delta = DrJava.getConfig().getSetting(OptionConstants.DIALOG_LIGHTWEIGHT_PARSING_DELAY).intValue();
115         }
116         // _log.logTime("Not updating, sleeping for "+delta);
117
try {
118           Thread.sleep(delta);
119         }
120         catch (InterruptedException JavaDoc e) { /* ignore, just wake up earlier and retry */ }
121       }
122     }
123   });
124   
125   /** Create the default light-weight parsing control.
126    * @param model the model */

127   public DefaultLightWeightParsingControl(AbstractGlobalModel model) {
128     _model = model;
129     _updater.setDaemon(true);
130     _updater.start();
131   }
132   
133   /** Perform light-weight parsing. */
134   public synchronized void update(final OpenDefinitionsDocument doc) {
135     _log.log("Update for "+doc);
136     try {
137       _lastUpdates.put(doc, System.currentTimeMillis());
138       final String JavaDoc old = _enclosingClassNames.get(doc);
139       final String JavaDoc updated = doc.getEnclosingClassName(doc.getCaretPosition(), true);
140       if ((old==null) || (!old.equals(updated))) {
141         _enclosingClassNames.put(doc, updated);
142         Utilities.invokeLater(new Runnable JavaDoc() {
143           public void run() {
144             List JavaDoc<LightWeightParsingListener> listeners = getListeners();
145             for (LightWeightParsingListener l: listeners) { l.enclosingClassNameUpdated(doc, old, updated); }
146           }
147         });
148       }
149     }
150     catch(BadLocationException e) { /* ignore */ }
151     catch(ClassNameNotFoundException e) { /* ignore */ }
152   }
153   
154   /** Start or stop automatic updates.
155    * @param b {@code true} to start or {@code false} to stop automatic updates
156    */

157   public void setAutomaticUpdates(boolean b) {
158     _log.log("setAutomaticUpdates("+b+")");
159     _running = b;
160     if (b) {
161       delay();
162       synchronized(_restart) {
163         _restart.notify();
164       }
165     }
166   }
167   
168   /** Delay the next update. */
169   public void delay() {
170     _lastDelay = System.currentTimeMillis();
171     _beginUpdates = _lastDelay + (DrJava.getConfig().getSetting(OptionConstants.DIALOG_LIGHTWEIGHT_PARSING_DELAY).intValue());
172   }
173   
174   /** Reset light-weight parsing. Forget everything. */
175   public synchronized void reset() {
176     for(final OpenDefinitionsDocument doc: _enclosingClassNames.keySet()) {
177       final String JavaDoc old = _enclosingClassNames.get(doc);
178       Utilities.invokeLater(new Runnable JavaDoc() {
179         public void run() {
180           List JavaDoc<LightWeightParsingListener> listeners = getListeners();
181           for (LightWeightParsingListener l: listeners) { l.enclosingClassNameUpdated(doc, old, null); }
182         }
183       });
184     }
185     _enclosingClassNames.clear();
186     _lastUpdates.clear();
187   }
188   
189   /** Return the last enclosing class name for the specified document, "" if not inside a class, or
190    * null if unknown.
191    * WARNING: In long source files and when contained in anonymous inner classes, this function might take a LONG time.
192    * @param doc the document for which we want the information
193    * @return the enclosing class name
194    */

195   public synchronized String JavaDoc getEnclosingClassName(OpenDefinitionsDocument doc) { return _enclosingClassNames.get(doc); }
196   
197   /** Add the listener to this controller.
198    * @param l listener to add */

199   public synchronized void addListener(LightWeightParsingListener l) {
200     _listeners.add(l);
201   }
202   
203   /** Remove the listener from this controller. */
204   public synchronized void removeListener(LightWeightParsingListener l) {
205     _listeners.remove(l);
206   }
207   
208   /** Remove all listeners from this controller. */
209   public synchronized void removeAllListeners() {
210     _listeners.clear();
211   }
212   
213   /** @return a copy of the list of listeners. */
214   public synchronized List JavaDoc<LightWeightParsingListener> getListeners() {
215     return new LinkedList JavaDoc<LightWeightParsingListener>(_listeners);
216   }
217 }
Popular Tags