Index: projects/projectapi/apichanges.xml =================================================================== RCS file: /shared/data/ccvs/repository/projects/projectapi/apichanges.xml,v retrieving revision 1.12 diff -u -r1.12 apichanges.xml --- projects/projectapi/apichanges.xml 26 Sep 2007 21:04:25 -0000 1.12 +++ projects/projectapi/apichanges.xml 9 Jan 2008 16:30:52 -0000 @@ -104,6 +104,25 @@ + + + Support for more easily replaceable projects + + + + + + +

+ ProjectManager.clearNonProjectCache() now discards + also projects which are named in a special way. If their class name + contains NonProject, then they are freed from the cache. +

+
+ + +
+ Added support for composing project's lookup from multiple sources. Index: projects/projectapi/arch.xml =================================================================== RCS file: /shared/data/ccvs/repository/projects/projectapi/arch.xml,v retrieving revision 1.12 diff -u -r1.12 arch.xml --- projects/projectapi/arch.xml 26 Sep 2007 21:04:25 -0000 1.12 +++ projects/projectapi/arch.xml 9 Jan 2008 16:30:53 -0000 @@ -457,9 +457,11 @@ --> -

- No. -

+ + ProjectManager.clearNonProjectCache() now discards + also projects which are named in a special way. If their class name + contains NonProject, then they are freed from the cache. +
Index: projects/projectapi/manifest.mf =================================================================== RCS file: /shared/data/ccvs/repository/projects/projectapi/manifest.mf,v retrieving revision 1.17 diff -u -r1.17 manifest.mf --- projects/projectapi/manifest.mf 9 Nov 2007 17:58:58 -0000 1.17 +++ projects/projectapi/manifest.mf 9 Jan 2008 16:30:53 -0000 @@ -1,5 +1,5 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.projectapi/1 -OpenIDE-Module-Specification-Version: 1.14 +OpenIDE-Module-Specification-Version: 1.15 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/projectapi/Bundle.properties Index: projects/projectapi/src/org/netbeans/api/project/ProjectManager.java =================================================================== RCS file: /shared/data/ccvs/repository/projects/projectapi/src/org/netbeans/api/project/ProjectManager.java,v retrieving revision 1.39 diff -u -r1.39 ProjectManager.java --- projects/projectapi/src/org/netbeans/api/project/ProjectManager.java 14 Dec 2007 16:11:26 -0000 1.39 +++ projects/projectapi/src/org/netbeans/api/project/ProjectManager.java 9 Jan 2008 16:30:53 -0000 @@ -48,6 +48,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.WeakHashMap; import java.util.logging.Level; @@ -466,6 +467,10 @@ * This may be useful after creating project metadata in a folder, etc. * Cached project objects, i.e. folders that are known to be * projects, are not affected. + *

+ * Since version 1.15, this method also discards + * projects which are named in a special way. If their class name + * contains NonProject, then they are freed from the cache. */ public void clearNonProjectCache() { synchronized (dir2Proj) { @@ -477,6 +482,20 @@ // will stay while its delegates are changed, which does no good // XXX should there be any way to signal that a particular // folder should be "reloaded" by a new factory? + + // clearing every project that is marked as NonProject + Iterator, LoadStatus>>> it = dir2Proj.entrySet().iterator(); + while (it.hasNext()) { + Union2, LoadStatus> union = it.next().getValue(); + if (union.hasFirst()) { + Reference ref = union.first(); + Project prj = ref.get(); + if (prj == null || prj.getClass().getSimpleName().indexOf("NonProject") == -1) { // NOI18N + continue; + } + it.remove(); + } + } } } Index: projects/projectapi/test/unit/src/org/netbeans/api/project/ProjectManagerTest.java =================================================================== RCS file: /shared/data/ccvs/repository/projects/projectapi/test/unit/src/org/netbeans/api/project/ProjectManagerTest.java,v retrieving revision 1.16 diff -u -r1.16 ProjectManagerTest.java --- projects/projectapi/test/unit/src/org/netbeans/api/project/ProjectManagerTest.java 14 Dec 2007 16:11:26 -0000 1.16 +++ projects/projectapi/test/unit/src/org/netbeans/api/project/ProjectManagerTest.java 9 Jan 2008 16:30:53 -0000 @@ -50,9 +50,13 @@ import java.util.Set; import java.util.logging.Level; import org.netbeans.junit.Log; +import org.netbeans.junit.MockServices; import org.netbeans.junit.NbTestCase; import org.netbeans.modules.projectapi.TimedWeakReference; +import org.netbeans.spi.project.ProjectFactory; +import org.netbeans.spi.project.ProjectState; import org.openide.filesystems.FileObject; +import org.openide.util.Lookup; import org.openide.util.test.MockLookup; /* XXX tests needed: @@ -174,6 +178,60 @@ assertNotNull("Can load goodproject yet again", p); assertEquals("Correct project directory set again", goodproject, p.getProjectDirectory()); assertEquals("ProjectFactory was called only once on new goodproject folder object", 1, TestUtil.projectLoadCount(goodproject)); + } + + + public static final class NonProjectFactory implements ProjectFactory { + static FileObject recognize; + + public boolean isProject(FileObject projectDirectory) { + return projectDirectory.equals(recognize); + } + public Project loadProject(FileObject projectDirectory, ProjectState state) throws IOException { + if (isProject(projectDirectory)) { + recognize = null; + return new MyNonProject(projectDirectory); + } + return null; + } + public void saveProject(Project project) throws IOException, ClassCastException { + } + } + static final class MyNonProject implements Project { + FileObject dir; + + public MyNonProject(FileObject dir) { + this.dir = dir; + } + + public FileObject getProjectDirectory() { + return dir; + } + + public Lookup getLookup() { + return Lookup.EMPTY; + } + } + + public void testProjectCanBeGCedWhenItContainsNameNonProject() throws Exception { + MockLookup.setInstances(new NonProjectFactory(), TestUtil.testProjectFactory()); + Project prev = null; + NonProjectFactory.recognize = goodproject; + prev = pm.findProject(goodproject); + assertNotNull("Project recognized", prev); + assertEquals(MyNonProject.class, prev.getClass()); + pm.clearNonProjectCache(); + Project p = pm.findProject(goodproject); + assertNotNull("Should have recognized goodproject", p); + assertEquals("ProjectFactory was called once so far on goodproject", 1, TestUtil.projectLoadCount(goodproject)); + + Reference weak = new WeakReference(prev); + prev = null; + assertGC("NonProject can disappear", weak); + + // continue the normal test + p = null; + testFindProjectGC(); } public void testFindProjectDoesNotCacheLoadErrors() throws Exception {