Added
Link Here
|
1 |
/* |
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 |
* |
4 |
* Copyright 2014 Oracle and/or its affiliates. All rights reserved. |
5 |
* |
6 |
* Oracle and Java are registered trademarks of Oracle and/or its affiliates. |
7 |
* Other names may be trademarks of their respective owners. |
8 |
* |
9 |
* The contents of this file are subject to the terms of either the GNU |
10 |
* General Public License Version 2 only ("GPL") or the Common |
11 |
* Development and Distribution License("CDDL") (collectively, the |
12 |
* "License"). You may not use this file except in compliance with the |
13 |
* License. You can obtain a copy of the License at |
14 |
* http://www.netbeans.org/cddl-gplv2.html |
15 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the |
16 |
* specific language governing permissions and limitations under the |
17 |
* License. When distributing the software, include this License Header |
18 |
* Notice in each file and include the License file at |
19 |
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this |
20 |
* particular file as subject to the "Classpath" exception as provided |
21 |
* by Oracle in the GPL Version 2 section of the License file that |
22 |
* accompanied this code. If applicable, add the following below the |
23 |
* License Header, with the fields enclosed by brackets [] replaced by |
24 |
* your own identifying information: |
25 |
* "Portions Copyrighted [year] [name of copyright owner]" |
26 |
* |
27 |
* If you wish your version of this file to be governed by only the CDDL |
28 |
* or only the GPL Version 2, indicate your decision by adding |
29 |
* "[Contributor] elects to include this software in this distribution |
30 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a |
31 |
* single choice of license, a recipient has the option to distribute |
32 |
* your version of this file under either the CDDL, the GPL Version 2 or |
33 |
* to extend the choice of license to its licensees as provided above. |
34 |
* However, if you add GPL Version 2 code and therefore, elected the GPL |
35 |
* Version 2 license, then the option applies only if the new code is |
36 |
* made subject to such option by the copyright holder. |
37 |
* |
38 |
* Contributor(s): |
39 |
* |
40 |
* Portions Copyrighted 2014 Sun Microsystems, Inc. |
41 |
*/ |
42 |
|
43 |
package org.netbeans.modules.cnd.modelimpl.platform; |
44 |
|
45 |
import java.util.ArrayList; |
46 |
import java.util.Collection; |
47 |
import java.util.HashMap; |
48 |
import java.util.Iterator; |
49 |
import java.util.LinkedHashMap; |
50 |
import java.util.List; |
51 |
import java.util.Map; |
52 |
import java.util.logging.Level; |
53 |
import org.netbeans.modules.cnd.api.model.CsmFile; |
54 |
import org.netbeans.modules.cnd.api.project.NativeFileItem; |
55 |
import org.netbeans.modules.cnd.api.project.NativeProject; |
56 |
import org.netbeans.modules.cnd.modelimpl.csm.core.FileImpl; |
57 |
import org.netbeans.modules.cnd.modelimpl.csm.core.ProjectBase; |
58 |
import org.netbeans.modules.cnd.modelimpl.debug.TraceFlags; |
59 |
import org.netbeans.modules.cnd.modelimpl.repository.RepositoryUtils; |
60 |
import org.netbeans.modules.cnd.utils.CndUtils; |
61 |
import org.openide.filesystems.FileObject; |
62 |
import org.openide.filesystems.FileStateInvalidException; |
63 |
import org.openide.util.Exceptions; |
64 |
import org.openide.util.RequestProcessor; |
65 |
|
66 |
/** |
67 |
* @author Vladimir Voskresensky |
68 |
* @author Vladimir Kvashin |
69 |
*/ |
70 |
/*package*/ final class CsmEventListener { |
71 |
|
72 |
private final ProjectBase project; |
73 |
private final NativeProject nativeProject; |
74 |
private volatile boolean enabledEventsHandling = true; |
75 |
|
76 |
//private static final RequestProcessor RP = new RequestProcessor(CsmEventListener.class.getSimpleName()); |
77 |
private final RequestProcessor.Task task; |
78 |
private final Object eventsLock = new Object(); |
79 |
private int suspendCount = 0; |
80 |
|
81 |
private HashMap<String, CsmEvent> events = new LinkedHashMap<>(); |
82 |
|
83 |
private static final CsmEvent NULL = CsmEvent.createEmptyEvent(CsmEvent.Kind.NULL); |
84 |
|
85 |
public CsmEventListener(ProjectBase project) { |
86 |
assert project.getPlatformProject() instanceof NativeProject; |
87 |
this.project = project; |
88 |
this.nativeProject = (NativeProject) project.getPlatformProject(); |
89 |
this.task = ModelSupport.instance().getModel().createModelTask(new Worker(), getClass().getSimpleName()); |
90 |
} |
91 |
|
92 |
public ProjectBase getProject() { |
93 |
return project; |
94 |
} |
95 |
|
96 |
public NativeProject getNativeProject() { |
97 |
return nativeProject; |
98 |
} |
99 |
|
100 |
public void enableListening(boolean enable) { |
101 |
if (TraceFlags.TIMING) { |
102 |
CsmEvent.LOG.log(Level.INFO, "\n%{0} ProjectListeners {1}...", new Object[] {enable ? "enable" : "disable", |
103 |
nativeProject.getProjectDisplayName()}); |
104 |
} |
105 |
enabledEventsHandling = enable; |
106 |
} |
107 |
|
108 |
void fireEvent(CsmEvent event) { |
109 |
switch (event.getKind()) { |
110 |
case FILE_INDEXED: |
111 |
case FOLDER_CREATED: |
112 |
case FILE_ATTRIBUTE_CHANGED: |
113 |
case NULL: |
114 |
return; |
115 |
} |
116 |
CsmEvent.trace("%s dispatched to %s", event, project); |
117 |
checkEvent(event); |
118 |
String path = getPath(event); |
119 |
synchronized (eventsLock) { |
120 |
CsmEvent prev = events.get(path); |
121 |
events.put(path, convert(prev, event)); |
122 |
} |
123 |
task.schedule(0); // fe.runWhenDeliveryOver(taskScheduler); ??? |
124 |
} |
125 |
|
126 |
String getPath(CsmEvent event) { |
127 |
FileObject fo = event.getFileObject(); |
128 |
if (fo != null) { |
129 |
return fo.getPath(); |
130 |
} |
131 |
NativeFileItem item = event.getNativeFileItem(); |
132 |
if (item != null) { |
133 |
return item.getAbsolutePath(); |
134 |
} |
135 |
NativeProject np = event.getNativeProject(); |
136 |
if (np != null) { |
137 |
return np.getProjectRoot(); |
138 |
} |
139 |
return "/"; //NOI18N |
140 |
} |
141 |
|
142 |
void checkEvent(CsmEvent event) { |
143 |
FileObject fo = event.getFileObject(); |
144 |
if (fo != null) { |
145 |
try { |
146 |
assert fo.getFileSystem().equals(nativeProject.getFileSystem()); |
147 |
} catch (FileStateInvalidException ex) { |
148 |
Exceptions.printStackTrace(ex); |
149 |
} |
150 |
} |
151 |
NativeProject np = event.getNativeProject(); |
152 |
if (np == null) { |
153 |
NativeFileItem item = event.getNativeFileItem(); |
154 |
if (item != null) { |
155 |
np = item.getNativeProject(); |
156 |
} |
157 |
} |
158 |
if (np != null) { |
159 |
assert np.equals(nativeProject); |
160 |
} |
161 |
} |
162 |
|
163 |
void resume() { |
164 |
boolean schedule; |
165 |
synchronized (eventsLock) { |
166 |
CndUtils.assertTrue(suspendCount > 0, "resume without suspend " + suspendCount); |
167 |
suspendCount--; |
168 |
if (suspendCount < 0) { |
169 |
suspendCount = 0; |
170 |
} |
171 |
schedule = (suspendCount == 0); |
172 |
} |
173 |
if (schedule) { |
174 |
task.schedule(0); |
175 |
} |
176 |
} |
177 |
|
178 |
void suspend() { |
179 |
synchronized (eventsLock) { |
180 |
CndUtils.assertTrue(suspendCount >= 0, "suspend with " + suspendCount); |
181 |
suspendCount++; |
182 |
} |
183 |
} |
184 |
|
185 |
/*package*/void flush() { |
186 |
task.schedule(0); |
187 |
task.waitFinished(); |
188 |
} |
189 |
|
190 |
//<editor-fold defaultstate="collapsed" desc="old impl"> |
191 |
/*** |
192 |
private void processEvents(Collection<CsmEvent> events) { |
193 |
if (!enabledEventsHandling) { |
194 |
CsmEvent.trace("events processing disabled, skipping %d events", events.size()); |
195 |
return; |
196 |
} |
197 |
CsmEvent.trace("processing %d events", events.size()); |
198 |
boolean checkForRemoved = false; |
199 |
for (CsmEvent event : events) { |
200 |
CsmEvent.trace("processing %s", event); |
201 |
switch (event.getKind()) { |
202 |
case FILE_DELETED: |
203 |
case ITEM_REMOVED: |
204 |
case FILE_RENAMED_DELETED: |
205 |
case ITEM_RENAMED_DELETED: |
206 |
checkForRemoved = true; |
207 |
break; |
208 |
case FILE_CREATED: |
209 |
case FILE_RENAMED_CREATED: |
210 |
project.onFileObjectExternalCreate(event.getFileObject()); |
211 |
break; |
212 |
case ITEM_ADDED: |
213 |
project.onFileItemsAdded(Arrays.asList(event.getNativeFileItem())); |
214 |
break; |
215 |
case FOLDER_CREATED: |
216 |
// nothing |
217 |
break; |
218 |
case FILE_CHANGED: |
219 |
project.findFile(event.getPath(), false, false); |
220 |
break; |
221 |
case FILE_ATTRIBUTE_CHANGED: |
222 |
// nothing |
223 |
break; |
224 |
case ITEM_PROPERTY_CHANGED: |
225 |
project.onFileItemsPropertyChanged(Arrays.asList(event.getNativeFileItem()), false); |
226 |
break; |
227 |
case ITEMS_ALL_PROPERTY_CHANGED: |
228 |
List<NativeFileItem> items = new ArrayList<>(); |
229 |
for (NativeFileItem item : nativeProject.getAllFiles()) { |
230 |
if (!item.isExcluded()) { |
231 |
switch (item.getLanguage()) { |
232 |
case C: |
233 |
case CPP: |
234 |
case FORTRAN: |
235 |
items.add(item); |
236 |
break; |
237 |
default: |
238 |
break; |
239 |
} |
240 |
} |
241 |
project.onFileItemsPropertyChanged(items, true); |
242 |
} |
243 |
break; |
244 |
case ITEM_RENAMED_CREATED: |
245 |
project.onFileItemRenamed(event.getOldPath(), event.getNativeFileItem()); |
246 |
break; |
247 |
case PROJECT_DELETED: |
248 |
RepositoryUtils.onProjectDeleted(nativeProject); |
249 |
break; |
250 |
case FILES_IN_SOURCE_ROOT_DELETED: |
251 |
checkForRemoved = true; |
252 |
break; |
253 |
case FILE_INDEXED: |
254 |
CndUtils.assertTrue(false, "FILE_INDEXED event should never reach end listener"); //NOI18N |
255 |
break; |
256 |
case NULL: |
257 |
// nothing |
258 |
break; |
259 |
default: |
260 |
throw new AssertionError(event.getKind().name()); |
261 |
} |
262 |
if (checkForRemoved) { |
263 |
project.checkForRemoved(); |
264 |
} |
265 |
} |
266 |
} |
267 |
*/ |
268 |
//</editor-fold> |
269 |
|
270 |
private void processEvents(Collection<CsmEvent> events) { |
271 |
if (!enabledEventsHandling) { |
272 |
CsmEvent.trace("events processing disabled, skipping %d events", events.size()); |
273 |
return; |
274 |
} |
275 |
CsmEvent.trace("processing %d events", events.size()); |
276 |
|
277 |
boolean projectDeleted = false; |
278 |
boolean checkForRemoved = false; |
279 |
boolean projectRemoved = false; |
280 |
boolean allPropertiesChanged = false; |
281 |
List<FileObject> createdFiles = new ArrayList<>(); |
282 |
List<NativeFileItem> addedItems = new ArrayList<>(); |
283 |
List<NativeFileItem> changedItemProps = new ArrayList<>(); |
284 |
List<String> changedFiles = new ArrayList<>(); |
285 |
List<CsmEvent> renamedItems = new ArrayList<>(); |
286 |
|
287 |
for (CsmEvent event : events) { |
288 |
CsmEvent.trace("processing %s", event); |
289 |
switch (event.getKind()) { |
290 |
case FILE_DELETED: |
291 |
case ITEM_REMOVED: |
292 |
case FILE_RENAMED_DELETED: |
293 |
case ITEM_RENAMED_DELETED: |
294 |
checkForRemoved = true; |
295 |
break; |
296 |
case FILE_CREATED: |
297 |
case FILE_RENAMED_CREATED: |
298 |
createdFiles.add(event.getFileObject()); |
299 |
break; |
300 |
case ITEM_ADDED: |
301 |
addedItems.add(event.getNativeFileItem()); |
302 |
break; |
303 |
case FOLDER_CREATED: |
304 |
// nothing |
305 |
break; |
306 |
case FILE_CHANGED: |
307 |
changedFiles.add(event.getPath()); |
308 |
break; |
309 |
case FILE_ATTRIBUTE_CHANGED: |
310 |
// nothing |
311 |
break; |
312 |
case ITEM_PROPERTY_CHANGED: |
313 |
changedItemProps.add(event.getNativeFileItem()); |
314 |
break; |
315 |
case ITEMS_ALL_PROPERTY_CHANGED: |
316 |
allPropertiesChanged = true; |
317 |
break; |
318 |
case ITEM_RENAMED_CREATED: |
319 |
renamedItems.add(event); |
320 |
break; |
321 |
case PROJECT_DELETED: |
322 |
projectDeleted = true; |
323 |
break; |
324 |
case FILES_IN_SOURCE_ROOT_DELETED: |
325 |
checkForRemoved = true; |
326 |
break; |
327 |
case FILE_INDEXED: |
328 |
CndUtils.assertTrue(false, "FILE_INDEXED event should never reach end listener"); //NOI18N |
329 |
break; |
330 |
case NULL: |
331 |
// nothing |
332 |
break; |
333 |
default: |
334 |
throw new AssertionError(event.getKind().name()); |
335 |
} |
336 |
|
337 |
if (projectDeleted) { |
338 |
RepositoryUtils.onProjectDeleted(nativeProject); |
339 |
return; |
340 |
} |
341 |
|
342 |
if (!renamedItems.isEmpty()) { |
343 |
for (CsmEvent csmEvent : renamedItems) { |
344 |
project.onFileItemRenamed(event.getOldPath(), event.getNativeFileItem()); |
345 |
} |
346 |
} |
347 |
|
348 |
if (allPropertiesChanged) { |
349 |
List<NativeFileItem> items = new ArrayList<>(); |
350 |
for (NativeFileItem item : nativeProject.getAllFiles()) { |
351 |
if (!item.isExcluded()) { |
352 |
switch (item.getLanguage()) { |
353 |
case C: |
354 |
case CPP: |
355 |
case FORTRAN: |
356 |
items.add(item); |
357 |
break; |
358 |
default: |
359 |
break; |
360 |
} |
361 |
} |
362 |
project.onFileItemsPropertyChanged(items, true); |
363 |
} |
364 |
changedItemProps.clear(); |
365 |
} |
366 |
|
367 |
if(!changedFiles.isEmpty()) { |
368 |
for (String path : changedFiles) { |
369 |
CsmFile csmFile = project.findFile(path, false, false); |
370 |
if (csmFile != null) { |
371 |
project.onFileImplExternalChange((FileImpl) csmFile); |
372 |
} |
373 |
} |
374 |
} |
375 |
if (!changedItemProps.isEmpty()) { |
376 |
project.onFileItemsPropertyChanged(changedItemProps, false); |
377 |
} |
378 |
if (!createdFiles.isEmpty()) { |
379 |
project.onFileObjectExternalCreate(createdFiles); |
380 |
} |
381 |
if (!addedItems.isEmpty()) { |
382 |
project.onFileItemsAdded(addedItems); |
383 |
} |
384 |
if (checkForRemoved) { |
385 |
project.checkForRemoved(); |
386 |
} |
387 |
} |
388 |
} |
389 |
|
390 |
// the table below is incomplete: to me, it's easier to just fill the switch/case and add some comments there |
391 |
// but I left it just in case I decide to fill it later :) |
392 |
/*------------------------------------------------------------------------------------------------------------------------------------------- |
393 |
(prevKind) |
394 |
(curKind) | F/DEL | F/CR | F/REN_CR | F/REN_DL | F/CH | I/ADD | I/RM | I/PROP | I/ALPROP | I/REN_CR | I/REN_DL | P/DEL | F/RT_DEL | |
395 |
---------------------------------------------------------------------------------------------------------------------------------------------- |
396 |
F/DEL | F/DEL | null | null | assert | F/DEL | null | F/DEL | F/DEL | assert | null | assert | P/DEL | assert | |
397 |
I/RM | I/RM | null | null | assert | I/RM | null | I/RM | I/RM | assert | null | assert | P/DEL | assert | |
398 |
F/RT_DEL | assert | assert | assert | assert | assert | assert | assert | assert | assert | assert | assert | P/DEL | F/RT_DEL | |
399 |
F/CR | F/CH | F/CR | assert | F/CH | F/CH | I/ADD | ? | ? | assert | | | P/DEL | | |
400 |
I/ADD | I/ADD | I/ADD? | I/ADD | I/ADD | I/ADD? | I/ADD | F/CH | | assert | | | P/DEL | assert | |
401 |
F/REN_CR | F/CH | assert | assert | F/CH | assert | | | | assert | | | P/DEL | | |
402 |
I/REN_CR | | | | | | | | | assert | | | P/DEL | | |
403 |
F/REN_DL | assert | null (?)| null (?) | assert | F/REN_DL | | | | assert | | | P/DEL | | |
404 |
I/REN_DL | | | | | | | | | assert | | | P/DEL | | |
405 |
F/CH | assert | F/CR | F/REN_CR | assert | F/CH | | | | assert | | | P/DEL | | |
406 |
I/PROP | null | F/CR | null | assert | I/PROP | I/ADD | I/RM | I/PROP | assert | I/REN_CR | assert | P/DEL | assert | |
407 |
I/ALPROP | assert | assert | assert | assert | assert | assert | assert | assert | assert | assert | assert | P/DEL | | |
408 |
P/DEL | P/DEL | P/DEL | P/DEL | P/DEL | P/DEL | P/DEL | P/DEL | P/DEL | P/DEL | P/DEL | P/DEL | P/DEL | P/DEL | |
409 |
----------------------------------------------------------------------------------------------------------------------------------------------*/ |
410 |
|
411 |
private static CsmEvent convert(CsmEvent prev, CsmEvent cur) { |
412 |
if (prev == null || prev.getKind() == CsmEvent.Kind.NULL) { |
413 |
return cur; |
414 |
} |
415 |
|
416 |
if (prev.getKind() == CsmEvent.Kind.PROJECT_DELETED) { |
417 |
return prev; |
418 |
} else if (cur.getKind() == CsmEvent.Kind.PROJECT_DELETED) { |
419 |
return cur; |
420 |
} |
421 |
|
422 |
switch (cur.getKind()) { |
423 |
case FILE_DELETED: //<editor-fold defaultstate="collapsed" desc="..."> |
424 |
switch (prev.getKind()) { |
425 |
case FILE_DELETED: return cur; |
426 |
case ITEM_REMOVED: return cur; // doesn't matter, processing is the same |
427 |
case FILE_CREATED: return doNull(); |
428 |
case ITEM_ADDED: return doNull(); |
429 |
case FILE_RENAMED_CREATED: return doNull(); |
430 |
case ITEM_RENAMED_CREATED: return doNull(); |
431 |
case FILE_RENAMED_DELETED: return doAssert(prev, cur); |
432 |
case ITEM_RENAMED_DELETED: return doAssert(prev, cur); |
433 |
case FILE_CHANGED: return cur; |
434 |
case ITEM_PROPERTY_CHANGED: return cur; |
435 |
case ITEMS_ALL_PROPERTY_CHANGED: return doAssert(prev, cur, prev); // does that mean that the project is deleted? |
436 |
case FILES_IN_SOURCE_ROOT_DELETED: return cur; // doesn't matter, processing is thesame |
437 |
default: throw new IllegalArgumentException("unexpected " + prev.getKind()); // NOI18N |
438 |
} //</editor-fold> |
439 |
case FILE_CREATED://<editor-fold defaultstate="collapsed" desc="..."> |
440 |
switch (prev.getKind()) { |
441 |
case FILE_DELETED: return doChanged(cur); |
442 |
case ITEM_REMOVED: return doChanged(cur); |
443 |
case FILE_CREATED: return prev; |
444 |
case ITEM_ADDED: return prev; // item events are stronger |
445 |
case FILE_RENAMED_CREATED: return doAssert(prev, cur); |
446 |
case ITEM_RENAMED_CREATED: return prev; // ITEM_RENAMED_CREATED will finally cause checkForRemove and nativeItemAdded |
447 |
case FILE_RENAMED_DELETED: return doChanged(cur); |
448 |
case ITEM_RENAMED_DELETED: return doChanged(cur); |
449 |
case FILE_CHANGED: return prev; |
450 |
case ITEM_PROPERTY_CHANGED: return prev; // ? |
451 |
case ITEMS_ALL_PROPERTY_CHANGED: return doAssert(prev, cur, prev); // prev event path is a project path! |
452 |
case FILES_IN_SOURCE_ROOT_DELETED: return doAssert(prev, cur); // prev event path is a project path! |
453 |
default: throw new AssertionError(prev.getKind()); |
454 |
}//</editor-fold> |
455 |
case FILE_RENAMED_CREATED://<editor-fold defaultstate="collapsed" desc="..."> |
456 |
switch (prev.getKind()) { |
457 |
case FILE_DELETED: return doChanged(cur); |
458 |
case ITEM_REMOVED: return doChanged(cur); |
459 |
case FILE_CREATED: return doAssert(prev, cur); |
460 |
case ITEM_ADDED: return prev; |
461 |
case FILE_RENAMED_CREATED: return doAssert(prev, cur); |
462 |
case ITEM_RENAMED_CREATED: return doAssert(prev, cur); |
463 |
case FILE_RENAMED_DELETED: return doChanged(cur); |
464 |
case ITEM_RENAMED_DELETED: return doChanged(cur); |
465 |
case FILE_CHANGED: return doAssert(prev, cur); |
466 |
case ITEM_PROPERTY_CHANGED: return cur; //? |
467 |
case ITEMS_ALL_PROPERTY_CHANGED: return doAssert(prev, cur, prev); // prev event path is a project path! |
468 |
case FILES_IN_SOURCE_ROOT_DELETED: return doAssert(prev, cur, prev); // prev event path is a project path! |
469 |
default: throw new AssertionError(prev.getKind()); |
470 |
}//</editor-fold> |
471 |
case FILE_RENAMED_DELETED://<editor-fold defaultstate="collapsed" desc="..."> |
472 |
switch (prev.getKind()) { |
473 |
case FILE_DELETED: return doAssert(prev, cur); |
474 |
case ITEM_REMOVED: return doNullOnRename(prev, cur); //? |
475 |
case FILE_CREATED: return doNullOnRename(prev, cur); |
476 |
case ITEM_ADDED: return doNullOnRename(prev, cur); |
477 |
case FILE_RENAMED_CREATED: return doNullOnRename(prev, cur); |
478 |
case ITEM_RENAMED_CREATED: return doNullOnRename(prev, cur); |
479 |
case FILE_RENAMED_DELETED: return doAssert(prev, cur); |
480 |
case ITEM_RENAMED_DELETED: return doAssert(prev, cur); |
481 |
case FILE_CHANGED: return cur; |
482 |
case ITEM_PROPERTY_CHANGED: return cur; |
483 |
case ITEMS_ALL_PROPERTY_CHANGED: return doAssert(prev, cur, prev); // prev event path is a project path! |
484 |
case FILES_IN_SOURCE_ROOT_DELETED: return doAssert(prev, cur, prev); // prev event path is a project path! |
485 |
default: throw new AssertionError(prev.getKind()); |
486 |
}//</editor-fold> |
487 |
case FILE_CHANGED://<editor-fold defaultstate="collapsed" desc="..."> |
488 |
switch (prev.getKind()) { |
489 |
case FILE_DELETED: return doAssert(prev, cur); |
490 |
case ITEM_REMOVED: return cur; |
491 |
case FILE_CREATED: return prev; |
492 |
case FILE_RENAMED_CREATED: return prev; |
493 |
case FILE_RENAMED_DELETED: return doAssert(prev, cur); |
494 |
case FILE_CHANGED: return cur; |
495 |
case ITEM_ADDED: return cur; |
496 |
case ITEM_PROPERTY_CHANGED: return prev; |
497 |
case ITEM_RENAMED_CREATED: return prev; |
498 |
case ITEM_RENAMED_DELETED: return doAssert(prev, cur); |
499 |
case ITEMS_ALL_PROPERTY_CHANGED: return doAssert(prev, cur, prev); // prev event path is a project path! |
500 |
case FILES_IN_SOURCE_ROOT_DELETED: return doAssert(prev, cur, prev); // prev event path is a project path! |
501 |
default: throw new IllegalArgumentException("unexpected " + prev.getKind()); // NOI18N |
502 |
}//</editor-fold> |
503 |
case ITEM_ADDED://<editor-fold defaultstate="collapsed" desc="..."> |
504 |
switch (prev.getKind()) { |
505 |
case FILE_DELETED: return cur; |
506 |
case ITEM_REMOVED: return doChanged(CsmEvent.Kind.ITEM_PROPERTY_CHANGED, cur); |
507 |
case FILE_CREATED: return cur; |
508 |
case ITEM_ADDED: return cur; |
509 |
case FILE_RENAMED_CREATED: return cur; |
510 |
case ITEM_RENAMED_CREATED: return cur; //? |
511 |
case FILE_RENAMED_DELETED: return cur; //? |
512 |
case ITEM_RENAMED_DELETED: return cur; //? |
513 |
case FILE_CHANGED: return cur; |
514 |
case ITEM_PROPERTY_CHANGED: return cur; //? |
515 |
case ITEMS_ALL_PROPERTY_CHANGED: return doAssert(prev, cur, prev); // prev event path is a project path! |
516 |
case FILES_IN_SOURCE_ROOT_DELETED: return doAssert(prev, cur, prev); // prev event path is a project path! |
517 |
default: throw new IllegalArgumentException("unexpected " + prev.getKind()); // NOI18N |
518 |
}//</editor-fold> |
519 |
case ITEM_REMOVED://<editor-fold defaultstate="collapsed" desc="..."> |
520 |
switch (prev.getKind()) { |
521 |
case FILE_DELETED: return cur; // procssing is the same |
522 |
case ITEM_REMOVED: return cur; |
523 |
case FILE_CREATED: return cur; //? |
524 |
case ITEM_ADDED: return doNull(); |
525 |
case FILE_RENAMED_CREATED: return doNull(); |
526 |
case ITEM_RENAMED_CREATED: return doNull(); |
527 |
case FILE_RENAMED_DELETED: return cur; // processing is the same |
528 |
case ITEM_RENAMED_DELETED: return cur; // processing is the same |
529 |
case FILE_CHANGED: return cur; |
530 |
case ITEM_PROPERTY_CHANGED: return cur; //??? |
531 |
case ITEMS_ALL_PROPERTY_CHANGED: return doAssert(prev, cur, prev); // prev event path is a project path! |
532 |
case FILES_IN_SOURCE_ROOT_DELETED: return doAssert(prev, cur, prev); // prev event path is a project path! |
533 |
default: throw new IllegalArgumentException("unexpected " + prev.getKind()); // NOI18N |
534 |
}//</editor-fold> |
535 |
case ITEM_PROPERTY_CHANGED://<editor-fold defaultstate="collapsed" desc="..."> |
536 |
switch (prev.getKind()) { |
537 |
case FILE_DELETED: return doNull(); |
538 |
case ITEM_REMOVED: return doNull(); |
539 |
case FILE_CREATED: return cur; |
540 |
case ITEM_ADDED: return prev; |
541 |
case FILE_RENAMED_CREATED: return prev; |
542 |
case ITEM_RENAMED_CREATED: return prev; |
543 |
case FILE_RENAMED_DELETED: return doNull(); |
544 |
case ITEM_RENAMED_DELETED: return doNull(); |
545 |
case FILE_CHANGED: return cur; // item event is stronger |
546 |
case ITEM_PROPERTY_CHANGED: return cur; |
547 |
case ITEMS_ALL_PROPERTY_CHANGED: return doAssert(prev, cur, prev); // prev event path is a project path! |
548 |
case FILES_IN_SOURCE_ROOT_DELETED: return doAssert(prev, cur, prev); // prev event path is a project path! |
549 |
default: throw new IllegalArgumentException("unexpected " + prev.getKind()); // NOI18N |
550 |
}//</editor-fold> |
551 |
case ITEMS_ALL_PROPERTY_CHANGED://<editor-fold defaultstate="collapsed" desc="..."> |
552 |
switch (prev.getKind()) { |
553 |
case FILE_DELETED: // fallthrough |
554 |
case ITEM_REMOVED: // fallthrough |
555 |
case FILE_CREATED: // fallthrough |
556 |
case FILE_RENAMED_CREATED: // fallthrough |
557 |
case FILE_RENAMED_DELETED: // fallthrough |
558 |
case FILE_CHANGED: // fallthrough |
559 |
case ITEM_ADDED: // fallthrough |
560 |
case ITEM_PROPERTY_CHANGED: // fallthrough |
561 |
case ITEM_RENAMED_CREATED: // fallthrough |
562 |
case ITEM_RENAMED_DELETED: return doAssert(prev, cur); // cur path is project, prev path is file |
563 |
case ITEMS_ALL_PROPERTY_CHANGED: return cur; |
564 |
case FILES_IN_SOURCE_ROOT_DELETED: return cur; // should we create a synthetic event for this? |
565 |
default: throw new IllegalArgumentException("unexpected " + prev.getKind()); // NOI18N |
566 |
}//</editor-fold> |
567 |
case ITEM_RENAMED_DELETED://<editor-fold defaultstate="collapsed" desc="..."> |
568 |
switch (prev.getKind()) { |
569 |
case FILE_DELETED: return doNull(); |
570 |
case ITEM_REMOVED: return doNull(); |
571 |
case FILE_CREATED: return cur; |
572 |
case ITEM_ADDED: return doNull(); |
573 |
case FILE_RENAMED_CREATED: return doNull(); |
574 |
case ITEM_RENAMED_CREATED: return doNull(); |
575 |
case FILE_RENAMED_DELETED: return cur; |
576 |
case ITEM_RENAMED_DELETED: return cur; |
577 |
case FILE_CHANGED: return cur; |
578 |
case ITEM_PROPERTY_CHANGED: return cur; //??? |
579 |
case ITEMS_ALL_PROPERTY_CHANGED: return doAssert(prev, cur, prev); // prev event path is a project path! |
580 |
case FILES_IN_SOURCE_ROOT_DELETED: return doAssert(prev, cur, prev); // prev event path is a project path! |
581 |
default: throw new IllegalArgumentException("unexpected " + prev.getKind()); // NOI18N |
582 |
}//</editor-fold> |
583 |
case ITEM_RENAMED_CREATED://<editor-fold defaultstate="collapsed" desc="..."> |
584 |
switch (prev.getKind()) { |
585 |
case FILE_DELETED: return doChanged(cur); |
586 |
case ITEM_REMOVED: return doChanged(cur); |
587 |
case FILE_CREATED: return cur; |
588 |
case ITEM_ADDED: return prev;// or cur... doesn/t really matter |
589 |
case FILE_RENAMED_CREATED: return cur; |
590 |
case ITEM_RENAMED_CREATED: return cur; |
591 |
case FILE_RENAMED_DELETED: return doChanged(cur); |
592 |
case ITEM_RENAMED_DELETED: return doChanged(cur); |
593 |
case FILE_CHANGED: return cur; |
594 |
case ITEM_PROPERTY_CHANGED: return cur; |
595 |
case ITEMS_ALL_PROPERTY_CHANGED: return doAssert(prev, cur, prev); // prev event path is a project path! |
596 |
case FILES_IN_SOURCE_ROOT_DELETED: return doAssert(prev, cur, prev); // prev event path is a project path! |
597 |
default: throw new IllegalArgumentException("unexpected " + prev.getKind()); // NOI18N |
598 |
}//</editor-fold> |
599 |
case FILES_IN_SOURCE_ROOT_DELETED://<editor-fold defaultstate="collapsed" desc="..."> |
600 |
switch (prev.getKind()) { |
601 |
case FILE_DELETED: // fallthrough |
602 |
case ITEM_REMOVED: // fallthrough |
603 |
case FILE_CREATED: // fallthrough |
604 |
case ITEM_ADDED: // fallthrough |
605 |
case FILE_RENAMED_CREATED: // fallthrough |
606 |
case ITEM_RENAMED_CREATED: // fallthrough |
607 |
case FILE_RENAMED_DELETED: // fallthrough |
608 |
case ITEM_RENAMED_DELETED: // fallthrough |
609 |
case FILE_CHANGED: // fallthrough |
610 |
case ITEM_PROPERTY_CHANGED: return doAssert(prev, cur); // cur path is project, prev path is item ?! |
611 |
case ITEMS_ALL_PROPERTY_CHANGED: return prev; // ??? should we create a combined event? |
612 |
case FILES_IN_SOURCE_ROOT_DELETED: return cur; |
613 |
default: throw new IllegalArgumentException("unexpected " + prev.getKind()); // NOI18N |
614 |
}//</editor-fold> |
615 |
default: throw new AssertionError(prev.getKind()); |
616 |
} |
617 |
} |
618 |
|
619 |
private static CsmEvent doAssert(CsmEvent prev, CsmEvent cur) { |
620 |
return doAssert(prev, cur, cur); |
621 |
} |
622 |
|
623 |
private static CsmEvent doAssert(CsmEvent prev, CsmEvent cur, CsmEvent correct ){ |
624 |
CndUtils.assertTrueInConsole(false, "invalid states " + prev + " " + cur); |
625 |
return correct; |
626 |
} |
627 |
|
628 |
private static CsmEvent doChanged(CsmEvent.Kind kind, CsmEvent cur) { |
629 |
return CsmEvent.create(kind, cur); |
630 |
} |
631 |
|
632 |
private static CsmEvent doChanged(CsmEvent cur) { |
633 |
return CsmEvent.create(CsmEvent.Kind.FILE_CHANGED, cur); |
634 |
} |
635 |
|
636 |
private static CsmEvent doNull() { |
637 |
return NULL; |
638 |
} |
639 |
|
640 |
private static CsmEvent doNullOnRename(CsmEvent prev, CsmEvent cur) { |
641 |
return NULL; |
642 |
} |
643 |
|
644 |
private final class Worker implements Runnable { |
645 |
@Override |
646 |
public void run() { |
647 |
HashMap<String, CsmEvent> curEvents; |
648 |
synchronized (eventsLock) { |
649 |
if (events.isEmpty()) { |
650 |
return; |
651 |
} |
652 |
curEvents = events; |
653 |
if (suspendCount == 0) { |
654 |
events = new LinkedHashMap<>(); |
655 |
} else { |
656 |
HashMap<String, CsmEvent> suspendedRemoves = new LinkedHashMap<>(); |
657 |
for (Iterator<Map.Entry<String, CsmEvent>> it = curEvents.entrySet().iterator(); it.hasNext();) { |
658 |
Map.Entry<String, CsmEvent> entry = it.next(); |
659 |
CsmEvent value = entry.getValue(); |
660 |
// hold on with delete events and delete/create pair from rename event |
661 |
if (value.getKind() == CsmEvent.Kind.FILE_DELETED || value.getKind() == CsmEvent.Kind.ITEM_REMOVED) { |
662 |
//(value.getKind() == CsmEvent.Kind.FILE_CREATED && value.event instanceof FileRenameEvent)) { |
663 |
suspendedRemoves.put(entry.getKey(), value); |
664 |
it.remove(); |
665 |
} |
666 |
} |
667 |
events = suspendedRemoves; |
668 |
} |
669 |
} |
670 |
processEvents(curEvents.values()); |
671 |
} |
672 |
} |
673 |
} |