1 19 package org.netbeans.api.java.source; 20 21 import java.io.IOException ; 22 import java.util.ArrayList ; 23 import java.util.Collection ; 24 import java.util.HashMap ; 25 import java.util.List ; 26 import java.util.Map ; 27 import java.util.Map.Entry; 28 import java.util.logging.Level ; 29 import java.util.logging.Logger ; 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 56 public abstract class JavaSourceTaskFactory { 57 58 private static final Logger LOG = Logger.getLogger(JavaSourceTaskFactory.class.getName()); 59 static final String BEFORE_ADDING_REMOVING_TASKS = "beforeAddingRemovingTasks"; static final String FILEOBJECTS_COMPUTATION = "fileObjectsComputation"; 62 private final Phase phase; 63 private final Priority priority; 64 65 70 protected JavaSourceTaskFactory(Phase phase, Priority priority) { 71 this.phase = phase; 72 this.priority = priority; 73 this.file2Task = new HashMap <FileObject, CancellableTask<CompilationInfo>>(); 74 this.file2JS = new HashMap <FileObject, JavaSource>(); 75 } 76 77 85 protected abstract CancellableTask<CompilationInfo> createTask(FileObject file); 86 87 102 protected abstract Collection <FileObject> getFileObjects(); 103 104 107 protected final void fileObjectsChanged() { 108 LOG.log(Level.FINEST, FILEOBJECTS_COMPUTATION); 109 110 final List <FileObject> currentFiles = new ArrayList (getFileObjects()); 111 112 if (SYNCHRONOUS_EVENTS) { 113 stateChangedImpl(currentFiles); 114 } else { 115 WORKER.post(new Runnable () { 116 public void run() { 117 stateChangedImpl(currentFiles); 118 } 119 }); 120 } 121 } 122 123 125 static boolean SYNCHRONOUS_EVENTS = false; 126 127 private void stateChangedImpl(List <FileObject> currentFiles) { 128 Map <JavaSource, CancellableTask<CompilationInfo>> toRemove = new HashMap <JavaSource, CancellableTask<CompilationInfo>>(); 129 Map <JavaSource, CancellableTask<CompilationInfo>> toAdd = new HashMap <JavaSource, CancellableTask<CompilationInfo>>(); 130 131 synchronized (this) { 132 List <FileObject> addedFiles = new ArrayList (currentFiles); 133 List <FileObject> removedFiles = new ArrayList (file2Task.keySet()); 134 135 addedFiles.removeAll(file2Task.keySet()); 136 removedFiles.removeAll(currentFiles); 137 138 for (FileObject r : removedFiles) { 140 JavaSource source = file2JS.remove(r); 141 142 if (source == null) { 143 continue; 145 } 146 147 toRemove.put(source, file2Task.remove(r)); 148 } 149 150 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"); } catch (IOException ex) { 182 ErrorManager.getDefault().notify(ex); 183 } 184 } 185 } 186 187 192 protected final synchronized void reschedule(FileObject file) throws IllegalArgumentException { 193 JavaSource source = file2JS.get(file); 194 195 if (source == null) { 196 return ; 198 } 199 200 CancellableTask<CompilationInfo> task = file2Task.get(file); 201 202 if (task == null) { 203 return ; 205 } 206 207 ACCESSOR2.rescheduleTask(source, task); 208 } 209 210 private final Map <FileObject, CancellableTask<CompilationInfo>> file2Task; 211 private final Map <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 { 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 ; 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 |