KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > java > source > JavaSourceTaskFactory


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 package org.netbeans.api.java.source;
20
21 import java.io.IOException JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.Map.Entry;
28 import java.util.logging.Level JavaDoc;
29 import java.util.logging.Logger JavaDoc;
30 import org.netbeans.api.java.source.JavaSource.Phase;
31 import org.netbeans.api.java.source.JavaSource.Priority;
32 import org.netbeans.modules.java.source.parsing.FileObjects;
33 import org.openide.filesystems.FileObject;
34 import org.netbeans.api.java.source.support.EditorAwareJavaSourceTaskFactory;
35 import org.netbeans.api.java.source.support.CaretAwareJavaSourceTaskFactory;
36 import org.netbeans.api.java.source.support.LookupBasedJavaSourceTaskFactory;
37 import org.netbeans.modules.java.source.JavaSourceTaskFactoryManager;
38 import org.openide.ErrorManager;
39 import org.openide.util.RequestProcessor;
40
41 /**
42  * A factory for tasks that will be run in the {@link JavaSource} Java parsing harness.
43  *
44  * Please note that there is usually no need to implement this class directly,
45  * as there are support classes for common {@link JavaSourceTaskFactory} implementations.
46  *
47  * This factory should be registered in the global lookup by listing its fully qualified
48  * name in file <code>META-INF/services/org.netbeans.api.java.source.JavaSourceTaskFactory</code>.
49  *
50  * @see EditorAwareJavaSourceTaskFactory
51  * @see CaretAwareJavaSourceTaskFactory
52  * @see LookupBasedJavaSourceTaskFactory
53  *
54  * @author Jan Lahoda
55  */

56 public abstract class JavaSourceTaskFactory {
57
58     private static final Logger JavaDoc LOG = Logger.getLogger(JavaSourceTaskFactory.class.getName());
59             static final String JavaDoc BEFORE_ADDING_REMOVING_TASKS = "beforeAddingRemovingTasks"; //NOI18N
60
static final String JavaDoc FILEOBJECTS_COMPUTATION = "fileObjectsComputation"; //NOI18N
61

62     private final Phase phase;
63     private final Priority priority;
64
65     /**Construct the JavaSourceTaskFactory with given {@link Phase} and {@link Priority}.
66      *
67      * @param phase phase to use for tasks created by {@link #createTask}
68      * @param priority priority to use for tasks created by {@link #createTask}
69      */

70     protected JavaSourceTaskFactory(Phase phase, Priority priority) {
71         this.phase = phase;
72         this.priority = priority;
73         this.file2Task = new HashMap JavaDoc<FileObject, CancellableTask<CompilationInfo>>();
74         this.file2JS = new HashMap JavaDoc<FileObject, JavaSource>();
75     }
76
77     /**Create task for a given file. This task will be registered into the {@link JavaSource}
78      * parsing harness with a given {@link #getPriority priority} and {@link #getPhase phase}.
79      *
80      * Please note that this method should run as quickly as possible.
81      *
82      * @param file for which file the task should be created.
83      * @return created {@link CancellableTask} for a given file.
84      */

85     protected abstract CancellableTask<CompilationInfo> createTask(FileObject file);
86
87     /**Specifies on which files should be registered tasks created by this factory.
88      * On {@link JavaSource}'s corresponding to {@link FileObject}s returned from
89      * this method will be registered tasks created by the {@link #createTask} method
90      * of this factory.
91      *
92      * If this list changes, a change event should be fired to all registered
93      * {@link ChangeListener}s.
94      *
95      * @return list of {@link FileObject} on which tasks from this factory should be
96      * registered.
97      * @see #createTask
98      * @see #addChangeListener
99      * @see EditorAwareJavaSourceTaskFactory
100      * @see CaretAwareJavaSourceTaskFactory
101      */

102     protected abstract Collection JavaDoc<FileObject> getFileObjects();
103
104     /**Notify the infrastructure that the collection of fileobjects has been changed.
105      * The infrastructure calls {@link #getFileObjects()} to get a new collection files.
106      */

107     protected final void fileObjectsChanged() {
108         LOG.log(Level.FINEST, FILEOBJECTS_COMPUTATION);
109
110         final List JavaDoc<FileObject> currentFiles = new ArrayList JavaDoc(getFileObjects());
111
112         if (SYNCHRONOUS_EVENTS) {
113             stateChangedImpl(currentFiles);
114         } else {
115             WORKER.post(new Runnable JavaDoc() {
116                 public void run() {
117                     stateChangedImpl(currentFiles);
118                 }
119             });
120         }
121     }
122
123     /**for tests:
124      */

125     static boolean SYNCHRONOUS_EVENTS = false;
126
127     private void stateChangedImpl(List JavaDoc<FileObject> currentFiles) {
128         Map JavaDoc<JavaSource, CancellableTask<CompilationInfo>> toRemove = new HashMap JavaDoc<JavaSource, CancellableTask<CompilationInfo>>();
129         Map JavaDoc<JavaSource, CancellableTask<CompilationInfo>> toAdd = new HashMap JavaDoc<JavaSource, CancellableTask<CompilationInfo>>();
130         
131         synchronized (this) {
132             List JavaDoc<FileObject> addedFiles = new ArrayList JavaDoc(currentFiles);
133             List JavaDoc<FileObject> removedFiles = new ArrayList JavaDoc(file2Task.keySet());
134             
135             addedFiles.removeAll(file2Task.keySet());
136             removedFiles.removeAll(currentFiles);
137             
138             //remove old tasks:
139
for (FileObject r : removedFiles) {
140                 JavaSource source = file2JS.remove(r);
141                 
142                 if (source == null) {
143                     //TODO: log
144
continue;
145                 }
146                 
147                 toRemove.put(source, file2Task.remove(r));
148             }
149             
150             //add new tasks:
151
for (FileObject a : addedFiles) {
152                 if (a == null)
153                     continue;
154                 if (!a.isValid()) {
155                     continue;
156                 }
157                 JavaSource js = JavaSource.forFileObject(a);
158                 
159                 if (js != null) {
160                     CancellableTask<CompilationInfo> task = createTask(a);
161                     
162                     toAdd.put(js, task);
163                     
164                     file2Task.put(a, task);
165                     file2JS.put(a, js);
166                 }
167             }
168         }
169         
170         LOG.log(Level.FINEST, BEFORE_ADDING_REMOVING_TASKS);
171         
172         for (Entry<JavaSource, CancellableTask<CompilationInfo>> e : toRemove.entrySet()) {
173             ACCESSOR2.removePhaseCompletionTask(e.getKey(), e.getValue());
174         }
175         
176         for (Entry<JavaSource, CancellableTask<CompilationInfo>> e : toAdd.entrySet()) {
177             try {
178                 ACCESSOR2.addPhaseCompletionTask(e.getKey(), e.getValue(), phase, priority);
179             } catch (FileObjects.InvalidFileException ie) {
180                 LOG.info("JavaSource.addPhaseCompletionTask called on deleted file"); //NOI18N
181
} catch (IOException JavaDoc ex) {
182                 ErrorManager.getDefault().notify(ex);
183             }
184         }
185     }
186        
187     /**Re-run task created by this factory for given file.
188      * If the task has not yet been run, does nothing.
189      *
190      * @param file task created by this factory for this file is re-run.
191      */

192     protected final synchronized void reschedule(FileObject file) throws IllegalArgumentException JavaDoc {
193         JavaSource source = file2JS.get(file);
194
195         if (source == null) {
196 // throw new IllegalArgumentException("No JavaSource for given file.");
197
return ;
198 }
199         
200         CancellableTask<CompilationInfo> task = file2Task.get(file);
201         
202         if (task == null) {
203 // throw new IllegalArgumentException("This factory did not created any task for " + FileUtil.getFileDisplayName(file)); // NOI18N
204
return ;
205         }
206         
207         ACCESSOR2.rescheduleTask(source, task);
208     }
209
210     private final Map JavaDoc<FileObject, CancellableTask<CompilationInfo>> file2Task;
211     private final Map JavaDoc<FileObject, JavaSource> file2JS;
212
213     private static RequestProcessor WORKER = new RequestProcessor("JavaSourceTaskFactory", 1);
214     
215     static {
216         JavaSourceTaskFactoryManager.ACCESSOR = new JavaSourceTaskFactoryManager.Accessor() {
217             public void fireChangeEvent(JavaSourceTaskFactory f) {
218                 f.fileObjectsChanged();
219             }
220         };
221         ACCESSOR2 = new Accessor2() {
222             public void addPhaseCompletionTask(JavaSource js, CancellableTask<CompilationInfo> task, Phase phase, Priority priority) throws IOException JavaDoc {
223                 js.addPhaseCompletionTask(task, phase, priority);
224             }
225
226             public void removePhaseCompletionTask(JavaSource js, CancellableTask<CompilationInfo> task) {
227                 js.removePhaseCompletionTask(task);
228             }
229
230             public void rescheduleTask(JavaSource js, CancellableTask<CompilationInfo> task) {
231                 js.rescheduleTask(task);
232             }
233         };
234     }
235
236     static interface Accessor2 {
237         public abstract void addPhaseCompletionTask(JavaSource js, CancellableTask<CompilationInfo> task, Phase phase, Priority priority ) throws IOException JavaDoc;
238         public abstract void removePhaseCompletionTask(JavaSource js, CancellableTask<CompilationInfo> task );
239         public abstract void rescheduleTask(JavaSource js, CancellableTask<CompilationInfo> task);
240     }
241     
242     
243     static Accessor2 ACCESSOR2;
244     
245 }
246
Popular Tags