--- a/java.j2seproject/nbproject/project.xml +++ a/java.j2seproject/nbproject/project.xml @@ -180,7 +180,7 @@ 1 - 1.28 + 1.31 --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java +++ a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java @@ -156,7 +156,7 @@ private final PropertyEvaluator eval; private final ReferenceHelper refHelper; private final GeneratedFilesHelper genFilesHelper; - private final Lookup lookup; + private Lookup lookup; private final UpdateHelper updateHelper; private MainClassUpdater mainClassUpdater; private SourceRoots sourceRoots; @@ -313,7 +313,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()), new CoSAwareFileBuiltQueryImpl(QuerySupport.createFileBuiltQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots()), this), new RecommendedTemplatesImpl (this.updateHelper), @@ -335,6 +335,7 @@ LookupMergerSupport.createJFBLookupMerger(), QuerySupport.createBinaryForSourceQueryImplementation(this.sourceRoots, this.testRoots, this.helper, this.eval) //Does not use APH to get/put properties/cfgdata ); + lookup = base; // in case LookupProvider's call Project.getLookup return LookupProviderSupport.createCompositeLookup(base, "Projects/org-netbeans-modules-java-j2seproject/Lookup"); //NOI18N } --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SESources.java +++ a/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.modules.java.api.common.project.ProjectProperties; import org.netbeans.spi.project.support.GenericSources; @@ -72,20 +73,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; @@ -152,20 +151,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, false); - externalRootsRegistered = true; - } - } - }); + sourcesHelper.registerExternalRoots(FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT, false); return this.sourcesHelper.createSources(); } --- a/project.ant/apichanges.xml +++ a/project.ant/apichanges.xml @@ -104,6 +104,22 @@ + + + + Added SourcesHelper constructor accepting Project + + + + + +

+ The new constructor enables simplified control flow. +

+
+ + +
--- a/project.ant/manifest.mf +++ a/project.ant/manifest.mf @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.project.ant/1 -OpenIDE-Module-Specification-Version: 1.30 +OpenIDE-Module-Specification-Version: 1.31 OpenIDE-Module-Layer: org/netbeans/modules/project/ant/resources/mf-layer.xml OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/project/ant/Bundle.properties OpenIDE-Module-Install: org/netbeans/modules/project/ant/AntProjectModule.class --- a/project.ant/src/org/netbeans/spi/project/support/ant/SourcesHelper.java +++ a/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(boolean minimalSubfolders) { File loc = getActualLocation(); @@ -292,7 +293,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(); @@ -312,11 +314,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 org.netbeans.modules.project.ant/1 1.31 + */ + public SourcesHelper(Project project, AntProjectHelper aph, PropertyEvaluator evaluator) { + Parameters.notNull("project", project); this.project = project; + this.aph = aph; this.evaluator = evaluator; } @@ -470,7 +490,7 @@ } private Project getProject() { - return AntBasedProjectFactorySingleton.getProjectFor(project); + return project != null ? project : AntBasedProjectFactorySingleton.getProjectFor(aph); } /** @@ -504,11 +524,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} @@ -584,7 +607,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) { --- a/projectapi/src/org/netbeans/modules/projectapi/AuxiliaryConfigBasedPreferencesProvider.java +++ a/projectapi/src/org/netbeans/modules/projectapi/AuxiliaryConfigBasedPreferencesProvider.java @@ -95,6 +95,7 @@ } AuxiliaryConfiguration ac = ProjectUtils.getAuxiliaryConfiguration(p); + assert p.getLookup() != null : p; AuxiliaryProperties ap = p.getLookup().lookup(AuxiliaryProperties.class); target.put(p, new WeakReference(prov = new AuxiliaryConfigBasedPreferencesProvider(p, ac, ap, shared))); --- a/projectimport.eclipse.core/src/org/netbeans/modules/projectimport/eclipse/core/ProjectOpenHookImpl.java +++ a/projectimport.eclipse.core/src/org/netbeans/modules/projectimport/eclipse/core/ProjectOpenHookImpl.java @@ -40,31 +40,17 @@ package org.netbeans.modules.projectimport.eclipse.core; import java.util.concurrent.ExecutionException; -import java.util.logging.Logger; -import org.netbeans.api.project.Project; import org.netbeans.api.project.ui.OpenProjects; import org.netbeans.spi.project.ui.ProjectOpenedHook; import org.openide.util.Exceptions; import org.openide.util.RequestProcessor; -/** - * - */ public class ProjectOpenHookImpl extends ProjectOpenedHook{ private static final RequestProcessor PROJ_OPEN_HOOK_RESYNCHRONIZER = new RequestProcessor("Eclipse.Resynchronizer"); // NOI18N private static RequestProcessor.Task currentTask; - private UpgradableProject upgradable; - private Project project; - - private static final Logger LOG = - Logger.getLogger(ProjectOpenHookImpl.class.getName()); - - public ProjectOpenHookImpl(Project project, UpgradableProject upgradable) { - this.upgradable = upgradable; - this.project = project; - } + public ProjectOpenHookImpl() {} @Override protected synchronized void projectOpened() { --- a/projectimport.eclipse.core/src/org/netbeans/modules/projectimport/eclipse/core/spi/UpgradableProjectLookupProvider.java +++ a/projectimport.eclipse.core/src/org/netbeans/modules/projectimport/eclipse/core/spi/UpgradableProjectLookupProvider.java @@ -40,22 +40,33 @@ package org.netbeans.modules.projectimport.eclipse.core.spi; import org.netbeans.api.project.Project; +import org.netbeans.api.project.ProjectUtils; import org.netbeans.modules.projectimport.eclipse.core.ProjectOpenHookImpl; import org.netbeans.modules.projectimport.eclipse.core.UpgradableProject; import org.netbeans.spi.project.LookupProvider; import org.openide.util.Lookup; import org.openide.util.lookup.Lookups; -// registered separately in j2se and web modules, but could use @LookupProvider.Registration +// registered separately in j2se and web modules, otherwise could use @LookupProvider.Registration final public class UpgradableProjectLookupProvider implements LookupProvider { public Lookup createAdditionalLookup(Lookup baseContext) { Project p = baseContext.lookup(Project.class); assert p != null; - UpgradableProject up = new UpgradableProject(p); + if (ProjectUtils.getPreferences(p, UpgradableProjectLookupProvider.class, true). + get("project", null) == null) { // NOI18N + // Shortcut, the normal case: + return Lookup.EMPTY; + } else { + // Keep as separate method to try to delay class initialization: + return upgradeLookup(p); + } + } + + private static Lookup upgradeLookup(Project p) { return Lookups.fixed( - up, - new ProjectOpenHookImpl(p, up)); + new UpgradableProject(p), + new ProjectOpenHookImpl()); } } --- a/projectimport.eclipse.core/test/unit/src/org/netbeans/modules/projectimport/eclipse/core/spi/ProjectFactorySupportTest.java +++ a/projectimport.eclipse.core/test/unit/src/org/netbeans/modules/projectimport/eclipse/core/spi/ProjectFactorySupportTest.java @@ -46,7 +46,6 @@ import java.util.Collections; import java.util.List; import org.netbeans.api.java.platform.JavaPlatform; -import org.netbeans.api.project.FileOwnerQuery; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectManager; import org.netbeans.api.project.ProjectUtils; @@ -225,14 +224,6 @@ model.getEclipseTestSourceRootsAsFileArray(), null, null, null); J2SEProject p = (J2SEProject)ProjectManager.getDefault().findProject(helper.getProjectDirectory()); List importProblems = new ArrayList(); - - // - // NB-Core-Build #1293: "No project found to correspond to .../spcp/eclipse/src" from ProjectClassPathModifier.findExtensible - // - // Looks like J2SEProject registers its external source roots asynchronously and sometimes - // it is too late and above problem happens. Mark external source roots explicitly here: - FileOwnerQuery.markExternalOwner(model.getEclipseSourceRootsAsFileArray()[0].toURI(), p, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); - ProjectFactorySupport.updateProjectClassPath(helper, p.getReferenceHelper(), model, importProblems); EditableProperties ep = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); assertEquals( @@ -262,14 +253,6 @@ model.getEclipseTestSourceRootsAsFileArray(), null, null, null); J2SEProject p = (J2SEProject)ProjectManager.getDefault().findProject(helper.getProjectDirectory()); List importProblems = new ArrayList(); - - // - // NB-Core-Build #1293: "No project found to correspond to .../spcp/eclipse/src" from ProjectClassPathModifier.findExtensible - // - // Looks like J2SEProject registers its external source roots asynchronously and sometimes - // it is too late and above problem happens. Mark external source roots explicitly here: - FileOwnerQuery.markExternalOwner(model.getEclipseSourceRootsAsFileArray()[0].toURI(), p, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); - ProjectFactorySupport.updateProjectClassPath(helper, p.getReferenceHelper(), model, importProblems); EditableProperties ep = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); assertEquals( @@ -355,14 +338,6 @@ model.getEclipseTestSourceRootsAsFileArray(), null, null, null); J2SEProject p = (J2SEProject)ProjectManager.getDefault().findProject(helper.getProjectDirectory()); List importProblems = new ArrayList(); - - // - // NB-Core-Build #1293: "No project found to correspond to .../spcp/eclipse/src" from ProjectClassPathModifier.findExtensible - // - // Looks like J2SEProject registers its external source roots asynchronously and sometimes - // it is too late and above problem happens. Mark external source roots explicitly here: - FileOwnerQuery.markExternalOwner(model.getEclipseSourceRootsAsFileArray()[0].toURI(), p, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); - ProjectFactorySupport.updateProjectClassPath(helper, p.getReferenceHelper(), model, importProblems); EditableProperties ep = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); // required project "JavaLibrary1" is not available and therefore should not be @@ -411,14 +386,6 @@ mdl_d.getEclipseTestSourceRootsAsFileArray(), null, null, null); List problems = new ArrayList(); J2SEProject j2seprj_d = (J2SEProject) ProjectManager.getDefault().findProject(aph_d.getProjectDirectory()); - - // - // NB-Core-Build #1293: "No project found to correspond to .../spcp/eclipse/src" from ProjectClassPathModifier.findExtensible - // - // Looks like J2SEProject registers its external source roots asynchronously and sometimes - // it is too late and above problem happens. Mark external source roots explicitly here: - FileOwnerQuery.markExternalOwner(mdl_d.getEclipseSourceRootsAsFileArray()[0].toURI(), j2seprj_d, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); - ProjectFactorySupport.updateProjectClassPath(aph_d, j2seprj_d.getReferenceHelper(), mdl_d, problems); assertEquals(Collections.emptyList(), problems); assertEquals("${reference.c.jar}:${reference.b.jar}", aph_d.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH).get("javac.classpath")); --- a/web.project/src/org/netbeans/modules/web/project/WebProject.java +++ a/web.project/src/org/netbeans/modules/web/project/WebProject.java @@ -185,7 +185,7 @@ private final PropertyEvaluator eval; private final ReferenceHelper refHelper; private final GeneratedFilesHelper genFilesHelper; - private final Lookup lookup; + private Lookup lookup; private final ProjectWebModule webModule; private final CopyOnSaveSupport css; private final ArtifactCopyOnSaveSupport artifactSupport; @@ -529,6 +529,7 @@ LookupMergerSupport.createJFBLookupMerger(), QuerySupport.createBinaryForSourceQueryImplementation(sourceRoots, testRoots, helper, eval), }); + lookup = base; return LookupProviderSupport.createCompositeLookup(base, "Projects/org-netbeans-modules-web-project/Lookup"); //NOI18N }