Issue #146852: accept Project in a constructor for SourcesHelper to permit registerExternalRoots to run synch. Currently missing spec version, apichanges, usage in non-j2seproject project types, tests. Could also probably back out #b5f07b919bea, and #abb8ce297ad9 (incl. #69fe1d2f3765). diff --git a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java +++ b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java @@ -274,7 +274,7 @@ UILookupMergerSupport.createProjectOpenHookMerger(new ProjectOpenedHookImpl()), QuerySupport.createUnitTestForSourceQuery(getSourceRoots(), getTestSourceRoots()), QuerySupport.createSourceLevelQuery(evaluator()), - new J2SESources (this.helper, evaluator(), getSourceRoots(), getTestSourceRoots()), + new J2SESources(this, helper, evaluator(), getSourceRoots(), getTestSourceRoots()), QuerySupport.createSharabilityQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots()), QuerySupport.createFileBuiltQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots()), new RecommendedTemplatesImpl (this.updateHelper), diff --git a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SESources.java b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SESources.java --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SESources.java +++ b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SESources.java @@ -53,6 +53,7 @@ import org.netbeans.api.project.ProjectManager; import org.netbeans.api.project.FileOwnerQuery; import org.netbeans.api.java.project.JavaProjectConstants; +import org.netbeans.api.project.Project; import org.netbeans.modules.java.api.common.SourceRoots; import org.netbeans.spi.project.support.GenericSources; import org.netbeans.spi.project.support.ant.SourcesHelper; @@ -71,20 +72,18 @@ private static final String BUILD_DIR_PROP = "${" + J2SEProjectProperties.BUILD_DIR + "}"; //NOI18N private static final String DIST_DIR_PROP = "${" + J2SEProjectProperties.DIST_DIR + "}"; //NOI18N + private final Project project; private final AntProjectHelper helper; private final PropertyEvaluator evaluator; private final SourceRoots sourceRoots; private final SourceRoots testRoots; private SourcesHelper sourcesHelper; private Sources delegate; - /** - * Flag to forbid multiple invocation of {@link SourcesHelper#registerExternalRoots} - **/ - private boolean externalRootsRegistered; private final ChangeSupport changeSupport = new ChangeSupport(this); - J2SESources(AntProjectHelper helper, PropertyEvaluator evaluator, + J2SESources(Project project, AntProjectHelper helper, PropertyEvaluator evaluator, SourceRoots sourceRoots, SourceRoots testRoots) { + this.project = project; this.helper = helper; this.evaluator = evaluator; this.sourceRoots = sourceRoots; @@ -151,20 +150,12 @@ } private Sources initSources() { - this.sourcesHelper = new SourcesHelper(helper, evaluator); //Safe to pass APH + this.sourcesHelper = new SourcesHelper(project, helper, evaluator); //Safe to pass APH register(sourceRoots); register(testRoots); this.sourcesHelper.addNonSourceRoot(BUILD_DIR_PROP); this.sourcesHelper.addNonSourceRoot(DIST_DIR_PROP); - externalRootsRegistered = false; - ProjectManager.mutex().postWriteRequest(new Runnable() { - public void run() { - if (!externalRootsRegistered) { - sourcesHelper.registerExternalRoots(FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); - externalRootsRegistered = true; - } - } - }); + sourcesHelper.registerExternalRoots(FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); return this.sourcesHelper.createSources(); } diff --git a/project.ant/src/org/netbeans/spi/project/support/ant/SourcesHelper.java b/project.ant/src/org/netbeans/spi/project/support/ant/SourcesHelper.java --- a/project.ant/src/org/netbeans/spi/project/support/ant/SourcesHelper.java +++ b/project.ant/src/org/netbeans/spi/project/support/ant/SourcesHelper.java @@ -74,6 +74,7 @@ import org.openide.filesystems.FileStateInvalidException; import org.openide.filesystems.FileUtil; import org.openide.util.ChangeSupport; +import org.openide.util.Parameters; import org.openide.util.WeakListeners; // XXX should perhaps be legal to call add* methods at any time (should update things) @@ -98,7 +99,7 @@ if (val == null) { return null; } - return project.resolveFile(val); + return aph.resolveFile(val); } public Collection getIncludeRoots() { File loc = getActualLocation(); @@ -285,7 +286,8 @@ } } - private final AntProjectHelper project; + private final AntProjectHelper aph; + private final Project project; private final PropertyEvaluator evaluator; private final List principalSourceRoots = new ArrayList(); private final List nonSourceRoots = new ArrayList(); @@ -304,11 +306,29 @@ /** * Create the helper object, initially configured to recognize only sources * contained inside the project directory. - * @param project an Ant project helper + * @param aph an Ant project helper * @param evaluator a way to evaluate Ant properties used to define source locations + * @deprecated Rather use {@link #SourcesHelper(Project, AntProjectHelper, PropertyEvaluator)}. */ - public SourcesHelper(AntProjectHelper project, PropertyEvaluator evaluator) { + @Deprecated + public SourcesHelper(AntProjectHelper aph, PropertyEvaluator evaluator) { + this.project = null; + this.aph = aph; + this.evaluator = evaluator; + } + + /** + * Create the helper object, initially configured to recognize only sources + * contained inside the project directory. + * @param project the project object (need not yet be registered in {@link ProjectManager}) + * @param aph an Ant project helper + * @param evaluator a way to evaluate Ant properties used to define source locations + * @since XXX + */ + public SourcesHelper(Project project, AntProjectHelper aph, PropertyEvaluator evaluator) { + Parameters.notNull("project", project); this.project = project; + this.aph = aph; this.evaluator = evaluator; } @@ -462,7 +482,7 @@ } private Project getProject() { - return AntBasedProjectFactorySingleton.getProjectFor(project); + return project != null ? project : AntBasedProjectFactorySingleton.getProjectFor(aph); } /** @@ -496,11 +516,14 @@ * {@link FileOwnerQuery#EXTERNAL_ALGORITHM_TRANSIENT}. *

*

- * You may not call this method inside the project's constructor, as - * it requires the actual project to exist and be registered in {@link ProjectManager}. - * Typically you would use {@link org.openide.util.Mutex#postWriteRequest} to run it + * If you used the old constructor form + * {@link #SourcesHelper(AntProjectHelper, PropertyEvaluator)} + * then you may not call this method inside the project's constructor, as + * it requires the actual project to exist and be registered in {@link ProjectManager}; + * in this case you could still use {@link org.openide.util.Mutex#postWriteRequest} to run it * later, if you were creating the helper in your constructor, since the project construction * normally occurs in read access. + * Better to use {@link #SourcesHelper(Project, AntProjectHelper, PropertyEvaluator)}. *

* @param algorithm an external root registration algorithm as per * {@link FileOwnerQuery#markExternalOwner} @@ -521,7 +544,7 @@ allRoots.addAll(nonSourceRoots); allRoots.addAll(ownedFiles); Project p = getProject(); - FileObject pdir = project.getProjectDirectory(); + FileObject pdir = aph.getProjectDirectory(); // First time: register roots and add to lastRegisteredRoots. // Subsequent times: add to newRootsToRegister and maybe add them later. if (lastRegisteredRoots == null) {