diff -r 259515477877 java.j2seproject/test/unit/src/org/netbeans/modules/java/j2seproject/J2SEConfigurationProviderTest.java --- a/java.j2seproject/test/unit/src/org/netbeans/modules/java/j2seproject/J2SEConfigurationProviderTest.java Wed Sep 03 18:04:01 2008 +0200 +++ b/java.j2seproject/test/unit/src/org/netbeans/modules/java/j2seproject/J2SEConfigurationProviderTest.java Thu Sep 04 10:29:06 2008 +0200 @@ -212,23 +212,45 @@ } public void testInitialListening() throws Exception { // #84781 - ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction() { + class Action implements Mutex.ExceptionAction { + int stage = 0; + Properties props; + TestListener l; + public Void run() throws Exception { - TestListener l = new TestListener(); + switch (stage++) { + case 0: initWrite(); break; + case 1: sndWrite(); break; + case 2: rest(); break; + default: fail(); break; + } + return null; + } + private void initWrite() throws Exception { + l = new TestListener(); pcp.addPropertyChangeListener(l); - Properties props = new Properties(); + props = new Properties(); props.setProperty("$label", "X"); write(props, d, "nbproject/configs/x.properties"); + } + + private void sndWrite() throws Exception { props = new Properties(); props.setProperty("config", "x"); write(props, d, "nbproject/private/config.properties"); + } + + private void rest() throws Exception { assertEquals(new HashSet(Arrays.asList(ProjectConfigurationProvider.PROP_CONFIGURATIONS, ProjectConfigurationProvider.PROP_CONFIGURATION_ACTIVE)), l.events()); assertEquals(2, pcp.getConfigurations().size()); assertEquals("X", pcp.getActiveConfiguration().getDisplayName()); - return null; } - }); + } + Action action = new Action(); + ProjectManager.mutex().writeAccess(action); + ProjectManager.mutex().writeAccess(action); + ProjectManager.mutex().writeAccess(action); } private void write(Properties p, FileObject d, String path) throws IOException { diff -r 259515477877 project.ant/src/org/netbeans/modules/project/ant/FileChangeSupport.java --- a/project.ant/src/org/netbeans/modules/project/ant/FileChangeSupport.java Wed Sep 03 18:04:01 2008 +0200 +++ b/project.ant/src/org/netbeans/modules/project/ant/FileChangeSupport.java Thu Sep 04 10:29:06 2008 +0200 @@ -158,7 +158,7 @@ } } - private void someChange(FileObject modified) { + private void someChange(FileEvent orig, FileObject modified) { FileChangeSupportListener listener; FileObject oldCurrent, nueCurrent; File oldCurrentF, nueCurrentF; @@ -177,39 +177,39 @@ nueCurrentF = currentF; } if (modified != null && modified == nueCurrent) { - FileChangeSupportEvent event = new FileChangeSupportEvent(DEFAULT, FileChangeSupportEvent.EVENT_MODIFIED, path); + FileChangeSupportEvent event = new FileChangeSupportEvent(orig, DEFAULT, FileChangeSupportEvent.EVENT_MODIFIED, path); listener.fileModified(event); } else { boolean oldWasCorrect = path.equals(oldCurrentF); boolean nueIsCorrect = path.equals(nueCurrentF); if (oldWasCorrect && !nueIsCorrect) { - FileChangeSupportEvent event = new FileChangeSupportEvent(DEFAULT, FileChangeSupportEvent.EVENT_DELETED, path); + FileChangeSupportEvent event = new FileChangeSupportEvent(orig, DEFAULT, FileChangeSupportEvent.EVENT_DELETED, path); listener.fileDeleted(event); } else if (nueIsCorrect && !oldWasCorrect) { - FileChangeSupportEvent event = new FileChangeSupportEvent(DEFAULT, FileChangeSupportEvent.EVENT_CREATED, path); + FileChangeSupportEvent event = new FileChangeSupportEvent(orig, DEFAULT, FileChangeSupportEvent.EVENT_CREATED, path); listener.fileCreated(event); } } } public void fileChanged(FileEvent fe) { - someChange(fe.getFile()); + someChange(fe, fe.getFile()); } public void fileDeleted(FileEvent fe) { - someChange(null); + someChange(fe, null); } public void fileDataCreated(FileEvent fe) { - someChange(null); + someChange(fe, null); } public void fileFolderCreated(FileEvent fe) { - someChange(null); + someChange(fe, null); } public void fileRenamed(FileRenameEvent fe) { - someChange(null); + someChange(fe, null); } public void fileAttributeChanged(FileAttributeEvent fe) { diff -r 259515477877 project.ant/src/org/netbeans/modules/project/ant/FileChangeSupportEvent.java --- a/project.ant/src/org/netbeans/modules/project/ant/FileChangeSupportEvent.java Wed Sep 03 18:04:01 2008 +0200 +++ b/project.ant/src/org/netbeans/modules/project/ant/FileChangeSupportEvent.java Thu Sep 04 10:29:06 2008 +0200 @@ -44,6 +44,7 @@ import java.util.EventObject; +import org.openide.filesystems.FileEvent; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; @@ -60,11 +61,13 @@ private final int type; private final File path; + private final FileEvent original; - FileChangeSupportEvent(FileChangeSupport support, int type, File path) { + FileChangeSupportEvent(FileEvent orig, FileChangeSupport support, int type, File path) { super(support); this.type = type; this.path = path; + this.original = orig; } public int getType() { @@ -78,7 +81,12 @@ public FileObject getFileObject() { return FileUtil.toFileObject(path); } + + public FileEvent getOriginal() { + return original; + } + @Override public String toString() { return "FCSE[" + "CDM".charAt(type) + ":" + path + "]"; // NOI18N } diff -r 259515477877 project.ant/src/org/netbeans/spi/project/support/ant/ProjectProperties.java --- a/project.ant/src/org/netbeans/spi/project/support/ant/ProjectProperties.java Wed Sep 03 18:04:01 2008 +0200 +++ b/project.ant/src/org/netbeans/spi/project/support/ant/ProjectProperties.java Thu Sep 04 10:29:06 2008 +0200 @@ -207,7 +207,7 @@ } else { properties = null; } - fireChange(); + fireChange(null); } return modifying; } @@ -282,7 +282,7 @@ private void reload() { helper.cancelPendingHook(); // Revert the save. - diskChange(); + diskChange(null); } }); } @@ -323,7 +323,7 @@ cs.removeChangeListener(l); } - private void fireChange() { + private void fireChange(FileChangeSupportEvent ev) { if (!cs.hasListeners()) { return; } @@ -333,6 +333,11 @@ return null; } }; + if (ev != null && ProjectManager.firedWithMutexAccess(ev.getOriginal())) { + ProjectManager.mutex().readAccess(action); + return; + } + if (ProjectManager.mutex().isWriteAccess()) { // Run it right now. postReadRequest would be too late. ProjectManager.mutex().readAccess(action); @@ -349,27 +354,27 @@ } } - private void diskChange() { + private void diskChange(FileChangeSupportEvent ev) { // XXX should check for a possible clobber from in-memory data if (!writing) { loaded = false; } - fireChange(); + fireChange(ev); if (!writing) { helper.fireExternalChange(path); } } public void fileCreated(FileChangeSupportEvent event) { - diskChange(); + diskChange(event); } public void fileDeleted(FileChangeSupportEvent event) { - diskChange(); + diskChange(event); } public void fileModified(FileChangeSupportEvent event) { - diskChange(); + diskChange(event); } } diff -r 259515477877 projectapi/src/org/netbeans/api/project/ProjectManager.java --- a/projectapi/src/org/netbeans/api/project/ProjectManager.java Wed Sep 03 18:04:01 2008 +0200 +++ b/projectapi/src/org/netbeans/api/project/ProjectManager.java Thu Sep 04 10:29:06 2008 +0200 @@ -112,19 +112,43 @@ return DEFAULT; } - private static final Executor FS_EXEC = new Executor() { - public void execute(final Runnable command) { + private static final PostCommand FS_EXEC = new PostCommand(); + + private static class PostCommand implements Executor, FileSystem.AtomicAction { + private Runnable run; + + public void execute(Runnable run) { + PostCommand p = new PostCommand(); + p.run = run; try { - FileUtil.runAtomicAction(new FileSystem.AtomicAction() { - public void run() throws IOException { - command.run(); - } - }); + FileUtil.runAtomicAction(p); } catch (IOException ex) { throw (IllegalStateException) new IllegalStateException().initCause(ex); } } - }; + + public void run() throws IOException { + run.run(); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + return obj.getClass().equals(getClass()); + } + } + + // XXX: apichange, maybe test in this module + public static boolean firedWithMutexAccess(FileEvent ev) { + return ev.firedFrom(FS_EXEC); + } private static final Mutex MUTEX = new Mutex(new Mutex.Privileged(), FS_EXEC);