KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > spi > editor > completion > support > AsyncCompletionTask


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.spi.editor.completion.support;
21
22 import javax.swing.SwingUtilities JavaDoc;
23 import javax.swing.text.Document JavaDoc;
24 import javax.swing.text.JTextComponent JavaDoc;
25 import org.netbeans.spi.editor.completion.CompletionResultSet;
26 import org.netbeans.spi.editor.completion.CompletionTask;
27 import org.openide.util.RequestProcessor;
28
29 /**
30  * Asynchronous completion task allowing asynchronous query execution
31  * through {@link AsyncCompletionQuery}.
32  * <br>
33  * This is a final class and all the logic must be defined
34  * in an implementation of {@link AsyncCompletionQuery} that must
35  * be passed to constructor of this task.
36  *
37  * @see AsyncCompletionQuery
38  * @author Miloslav Metelka, Dusan Balek
39  * @version 1.00
40  */

41
42 public final class AsyncCompletionTask implements CompletionTask, Runnable JavaDoc {
43     
44     private final AsyncCompletionQuery query;
45     
46     private final JTextComponent JavaDoc component;
47     
48     private Document JavaDoc doc;
49     
50     private int queryCaretOffset;
51     
52     private CompletionResultSet queryResultSet;
53     
54     private CompletionResultSet refreshResultSet;
55
56     private RequestProcessor.Task rpTask;
57     
58     /** Whether this task is cancelled. */
59     private boolean cancelled;
60
61     /** Whether query was already invoked on this task. */
62     private boolean queryInvoked;
63     
64     /**
65      * Construct asynchronous task for the given component.
66      *
67      * @param query non-null query implementation.
68      * @param component text component to operate with. The completion infrastructure
69      * will cancel the task if the component or its associated document would change.
70      * <br>
71      * It may be null to indicate that no component was provided.
72      */

73     public AsyncCompletionTask(AsyncCompletionQuery query, JTextComponent JavaDoc component) {
74         assert (query != null) : "Query must be non-null";
75         this.query = query;
76         this.component = component;
77     }
78     
79     /**
80      * Constructor for the case when there is no valid component
81      * which can happen when creating task for documentation or tooltip computation.
82      *
83      * @param query non-null query implementation.
84      */

85     public AsyncCompletionTask(AsyncCompletionQuery query) {
86         this(query, null);
87     }
88
89     /**
90      * Called by completion infrastructure in AWT thread to populate
91      * the given result set with data.
92      */

93     public void query(CompletionResultSet resultSet) {
94         assert (resultSet != null);
95         assert (SwingUtilities.isEventDispatchThread());
96         if (component != null) {
97             doc = component.getDocument();
98         } else {
99             doc = null;
100         }
101         queryInvoked = true;
102
103         synchronized (this) {
104             performQuery(resultSet);
105         }
106     }
107
108     /**
109      * Called by completion infrastructure in AWT thread once there
110      * is a change in the component (caret position changes or document
111      * gets modified).
112      * <br>
113      * The results should be fired into the newly provided completion listener.
114      */

115     public void refresh(CompletionResultSet resultSet) {
116         assert (SwingUtilities.isEventDispatchThread());
117         assert !cancelled : "refresh() called on canceled task"; // NOI18N
118
if (queryInvoked) {
119             assert (resultSet != null);
120             refreshResultSet = resultSet;
121             refreshImpl();
122         } else {
123             query.preQueryUpdate(component);
124         }
125     }
126
127     /**
128      * Called by completion infrastructure to cancel the running task.
129      */

130     public void cancel() {
131         cancelled = true;
132         synchronized (this) {
133             if (rpTask != null) {
134                 rpTask.cancel();
135                 rpTask = null;
136             }
137         }
138     }
139
140     private void performQuery(CompletionResultSet resultSet) {
141         // Runs in AWT thread only
142
if (component != null) {
143             queryCaretOffset = component.getSelectionStart();
144         } else {
145             queryCaretOffset = -1;
146         }
147
148         query.prepareQuery(component);
149         synchronized (this) {
150             queryResultSet = resultSet;
151             rpTask = RequestProcessor.getDefault().post(this);
152         }
153     }
154     
155     void refreshImpl() {
156         // Always called in AWT thread only
157
CompletionResultSet resultSet;
158         boolean rpTaskFinished;
159         synchronized (this) {
160             rpTaskFinished = (rpTask == null);
161             resultSet = refreshResultSet; // refreshResultSet checked in run()
162
}
163         if (resultSet != null) {
164             if (rpTaskFinished) { // query finished already
165
synchronized (this) {
166                     refreshResultSet = null;
167                 }
168                 // Synchronously call the refresh()
169
if (query.canFilter(component)) {
170                     query.filter(resultSet);
171                     assert resultSet.isFinished()
172                         : toString() + ": query.filter(): Result set not finished by resultSet.finish()"; // NOI18N
173
} else { // cannot filter and query stopped => another full query
174
performQuery(resultSet);
175                 }
176
177             } else { // pending query not finished yet
178
if (!query.canFilter(component)) { // query should attempted to be stopped by canFilter()
179
// Leave the ongoing query to be finished and once that happens
180
// ask for another canFilter()
181
} // Let the query finish and schedule refreshing by (refreshResultSet != null)
182
}
183         }
184     }
185
186     /**
187      * This method will be run() from the RequestProcessor during
188      * performing of the query.
189      */

190     public void run() {
191         // First check whether there was not request yet to stop the query: (queryResultSet == null)
192
CompletionResultSet resultSet = queryResultSet;
193         if (resultSet != null) {
194             // Perform the querying (outside of synchronized section)
195
query.query(resultSet, doc, queryCaretOffset);
196             assert resultSet.isFinished()
197             : toString() + ": query.query(): Result set not finished by resultSet.finish()"; // NOI18N
198
}
199
200         synchronized (this) {
201             rpTask = null;
202             queryResultSet = null;
203             // Check for pending refresh
204
if (refreshResultSet != null) {
205                 // Post refresh computation into AWT thread
206
SwingUtilities.invokeLater(new Runnable JavaDoc() {
207                     public void run() {
208                         refreshImpl();
209                     }
210                 });
211             }
212         }
213     }
214
215     synchronized boolean isCancelled() {
216         return cancelled;
217     }
218
219     public String JavaDoc toString() {
220         return "AsyncCompletionTask: query=" + query; // NOI18N
221
}
222 }
223
Popular Tags