Index: java/j2seproject/src/org/netbeans/modules/java/j2seproject/classpath/ClassPathProviderImpl.java =================================================================== RCS file: /cvs/java/j2seproject/src/org/netbeans/modules/java/j2seproject/classpath/ClassPathProviderImpl.java,v retrieving revision 1.14 diff -u -r1.14 ClassPathProviderImpl.java --- java/j2seproject/src/org/netbeans/modules/java/j2seproject/classpath/ClassPathProviderImpl.java 27 Nov 2004 16:46:57 -0000 1.14 +++ java/j2seproject/src/org/netbeans/modules/java/j2seproject/classpath/ClassPathProviderImpl.java 6 Jan 2005 13:00:29 -0000 @@ -20,6 +20,7 @@ import org.netbeans.api.java.classpath.ClassPath; import org.netbeans.spi.java.classpath.ClassPathFactory; import org.netbeans.spi.java.classpath.ClassPathProvider; +import org.netbeans.spi.java.project.classpath.support.ProjectClassPathSupport; import org.netbeans.spi.project.support.ant.AntProjectHelper; import org.netbeans.spi.project.support.ant.PropertyEvaluator; import org.netbeans.modules.java.j2seproject.SourceRoots; @@ -143,11 +144,13 @@ if ( cp == null) { if (type == 0) { cp = ClassPathFactory.createClassPath( - new ProjectClassPathImplementation(helper, "javac.classpath", evaluator)); // NOI18N + ProjectClassPathSupport.createPropertyBasedClassPathImplementation( + helper, evaluator, "javac.classpath")); // NOI18N } else { cp = ClassPathFactory.createClassPath( - new ProjectClassPathImplementation(helper, "javac.test.classpath", evaluator)); // NOI18N + ProjectClassPathSupport.createPropertyBasedClassPathImplementation( + helper, evaluator, "javac.test.classpath")); // NOI18N } cache[2+type] = cp; } @@ -169,17 +172,20 @@ if ( cp == null) { if (type == 0) { cp = ClassPathFactory.createClassPath( - new ProjectClassPathImplementation(helper, "run.classpath", evaluator)); // NOI18N + ProjectClassPathSupport.createPropertyBasedClassPathImplementation( + helper, evaluator, "run.classpath")); // NOI18N } else if (type == 1) { cp = ClassPathFactory.createClassPath( - new ProjectClassPathImplementation(helper, "run.test.classpath", evaluator)); // NOI18N + ProjectClassPathSupport.createPropertyBasedClassPathImplementation( + helper, evaluator,"run.test.classpath")); // NOI18N } else if (type == 2) { //Only to make the CompiledDataNode hapy //Todo: Strictly it should return ${run.classpath} - ${build.classes.dir} + ${dist.jar} cp = ClassPathFactory.createClassPath( - new ProjectClassPathImplementation(helper, DIST_JAR, evaluator)); // NOI18N + ProjectClassPathSupport.createPropertyBasedClassPathImplementation( + helper, evaluator, DIST_JAR)); // NOI18N } cache[4+type] = cp; } Index: java/j2seproject/src/org/netbeans/modules/java/j2seproject/classpath/ProjectClassPathImplementation.java =================================================================== RCS file: java/j2seproject/src/org/netbeans/modules/java/j2seproject/classpath/ProjectClassPathImplementation.java diff -N java/j2seproject/src/org/netbeans/modules/java/j2seproject/classpath/ProjectClassPathImplementation.java --- java/j2seproject/src/org/netbeans/modules/java/j2seproject/classpath/ProjectClassPathImplementation.java 26 Oct 2004 18:44:29 -0000 1.6 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,132 +0,0 @@ -/* - * Sun Public License Notice - * - * The contents of this file are subject to the Sun Public License - * Version 1.0 (the "License"). You may not use this file except in - * compliance with the License. A copy of the License is available at - * http://www.sun.com/ - * - * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun - * Microsystems, Inc. All Rights Reserved. - */ - -package org.netbeans.modules.java.j2seproject.classpath; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import org.netbeans.api.project.ProjectManager; -import org.netbeans.spi.java.classpath.ClassPathImplementation; -import org.netbeans.spi.java.classpath.support.ClassPathSupport; -import org.netbeans.spi.project.support.ant.AntProjectHelper; -import org.netbeans.spi.project.support.ant.PropertyEvaluator; -import org.netbeans.spi.project.support.ant.PropertyUtils; -import org.openide.filesystems.FileUtil; -import org.openide.util.WeakListeners; - -// XXX needs unit test! - -/** - * Implementation of a single classpath that is derived from one Ant property. - */ -final class ProjectClassPathImplementation implements ClassPathImplementation, PropertyChangeListener, Runnable { - - private PropertyChangeSupport support = new PropertyChangeSupport(this); - private AntProjectHelper helper; - private String propertyName; - private List resources; - private final PropertyEvaluator evaluator; - private boolean dirty = false; - - /** - * Construct the implementation. - * @param helper an Ant project, used to resolve file paths - * @param propertyName the name of an Ant property which will supply the classpath - * @param evaluator a property evaluator used to find the value of the classpath - */ - public ProjectClassPathImplementation(AntProjectHelper helper, String propertyName, PropertyEvaluator evaluator) { - assert helper != null && propertyName != null; - this.helper = helper; - this.evaluator = evaluator; - this.propertyName = propertyName; - evaluator.addPropertyChangeListener(WeakListeners.propertyChange(this, evaluator)); - } - - public synchronized List /**/ getResources() { - if (this.resources == null) { - this.resources = this.getPath (); - } - return this.resources; - } - - public void addPropertyChangeListener(PropertyChangeListener listener) { - support.addPropertyChangeListener (listener); - } - - public void removePropertyChangeListener(PropertyChangeListener listener) { - support.removePropertyChangeListener (listener); - } - - - public void propertyChange(PropertyChangeEvent evt) { - if (!evt.getPropertyName().equals(propertyName)) { - // Not interesting to us. - return; - } - // Coalesce changes; can come in fast after huge CP changes (#47910): - if (!dirty) { - dirty = true; - ProjectManager.mutex().postReadRequest(this); - } - } - - public void run() { - dirty = false; - List newRoots = getPath (); - boolean fire = false; - synchronized (this) { - if (this.resources != null && !this.resources.equals(newRoots)) { - this.resources = newRoots; - fire = true; - } - } - if (fire) { - support.firePropertyChange (PROP_RESOURCES,null,null); - } - } - - private List getPath() { - List result = new ArrayList (); - String prop = evaluator.getProperty(propertyName); - if (prop != null) { - String[] pieces = PropertyUtils.tokenizePath(prop); - for (int i = 0; i < pieces.length; i++) { - File f = helper.resolveFile(pieces[i]); - try { - URL entry = f.toURI().toURL(); - if (FileUtil.isArchiveFile(entry) || (f.isFile() && f.length()<4)) { //XXX: Not yet closed archive file - entry = FileUtil.getArchiveRoot(entry); - } else if (!f.exists()) { - // if file does not exist (e.g. build/classes folder - // was not created yet) then corresponding File will - // not be ended with slash. Fix that. - assert !entry.toExternalForm().endsWith("/") : f; // NOI18N - entry = new URL(entry.toExternalForm() + "/"); // NOI18N - } - result.add(ClassPathSupport.createResource(entry)); - } catch (MalformedURLException mue) { - assert false : mue; - } - } - } - return Collections.unmodifiableList(result); - } - -} Index: java/project/apichanges.xml =================================================================== RCS file: /cvs/java/project/apichanges.xml,v retrieving revision 1.2 diff -u -r1.2 apichanges.xml --- java/project/apichanges.xml 23 Dec 2004 22:01:31 -0000 1.2 +++ java/project/apichanges.xml 6 Jan 2005 13:00:30 -0000 @@ -69,12 +69,28 @@ Java Project API + Classpath Support SPI - + + + Added helper method for creating ClassPathImplementation based on the ant property + + + + + +

+ Added new helper class org.netbeans.spi.java.project.classpath.support.ProjectClassPathSupport + with a static method createPropertyBasedClassPathImplementation (AntProjectHelper, PropertyEvaluator, String). + This method creates a live classpath based on the single Ant property holding the path. The classpath + implementation listens on changes of the property value updates its state and fires events to clients. +

+
+
Index: java/project/arch.xml =================================================================== RCS file: /cvs/java/project/arch.xml,v retrieving revision 1.8 diff -u -r1.8 arch.xml --- java/project/arch.xml 23 Dec 2004 22:01:31 -0000 1.8 +++ java/project/arch.xml 6 Jan 2005 13:00:30 -0000 @@ -57,6 +57,12 @@ classpath of a J2SE project automatically.

+ +

+ Support class containg helper method for creating ClassPathImplementation based + on the Ant propery. +

+
Index: java/project/nbproject/project.properties =================================================================== RCS file: /cvs/java/project/nbproject/project.properties,v retrieving revision 1.10 diff -u -r1.10 project.properties --- java/project/nbproject/project.properties 14 Oct 2004 17:26:44 -0000 1.10 +++ java/project/nbproject/project.properties 6 Jan 2005 13:00:30 -0000 @@ -17,11 +17,14 @@ javadoc.arch=${basedir}/arch.xml javadoc.apichanges=${basedir}/apichanges.xml -test.unit.cp.extra=${nb_all}/projects/projectapi/build/test/unit/classes +test.unit.cp.extra=${nb_all}/projects/projectapi/build/test/unit/classes:\ + ${nb_all}/ant/project/build/test/unit/classes # masterfs needed for the usual reasons; tools.jar needed for Ant's to work test.unit.run.cp.extra=\ ${openide/masterfs.dir}/${nb.modules.dir}/org-netbeans-modules-masterfs.jar:\ - ${jdkhome}/lib/tools.jar + ${jdkhome}/lib/tools.jar:\ + ${diff.dir}/${nb.modules.dir}/org-netbeans-modules-diff.jar:\ + ${libs/xerces.dir}/${nb.modules/autoload.dir}/ext/xerces-2.6.2.jar test-unit-sys-prop.test.data.dir=${nb_all}/java/project/test/unit/data test-unit-sys-prop.test.bridge.jar=${ant.dir}/ant/nblib/bridge.jar # May be overridden to e.g. test against a different version of Ant: Index: java/project/nbproject/project.xml =================================================================== RCS file: /cvs/java/project/nbproject/project.xml,v retrieving revision 1.16 diff -u -r1.16 project.xml --- java/project/nbproject/project.xml 23 Dec 2004 22:01:30 -0000 1.16 +++ java/project/nbproject/project.xml 6 Jan 2005 13:00:30 -0000 @@ -134,6 +134,7 @@ org.netbeans.api.java.project org.netbeans.spi.java.project.support.ui org.netbeans.spi.java.project.support.ui.templates + org.netbeans.spi.java.project.classpath.support Index: java/project/src/org/netbeans/spi/java/project/classpath/support/ProjectClassPathImplementation.java =================================================================== RCS file: java/project/src/org/netbeans/spi/java/project/classpath/support/ProjectClassPathImplementation.java diff -N java/project/src/org/netbeans/spi/java/project/classpath/support/ProjectClassPathImplementation.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ java/project/src/org/netbeans/spi/java/project/classpath/support/ProjectClassPathImplementation.java 6 Jan 2005 13:00:31 -0000 @@ -0,0 +1,131 @@ +/* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package org.netbeans.spi.java.project.classpath.support; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.netbeans.api.project.ProjectManager; +import org.netbeans.spi.java.classpath.ClassPathImplementation; +import org.netbeans.spi.java.classpath.support.ClassPathSupport; +import org.netbeans.spi.project.support.ant.AntProjectHelper; +import org.netbeans.spi.project.support.ant.PropertyEvaluator; +import org.netbeans.spi.project.support.ant.PropertyUtils; +import org.openide.filesystems.FileUtil; +import org.openide.util.WeakListeners; + + +/** + * Implementation of a single classpath that is derived from one Ant property. + */ +final class ProjectClassPathImplementation implements ClassPathImplementation, PropertyChangeListener, Runnable { + + private PropertyChangeSupport support = new PropertyChangeSupport(this); + private AntProjectHelper helper; + private String propertyName; + private List resources; + private final PropertyEvaluator evaluator; + private boolean dirty = false; + + /** + * Construct the implementation. + * @param helper an Ant project, used to resolve file paths + * @param propertyName the name of an Ant property which will supply the classpath + * @param evaluator a property evaluator used to find the value of the classpath + */ + public ProjectClassPathImplementation(AntProjectHelper helper, String propertyName, PropertyEvaluator evaluator) { + assert helper != null && propertyName != null; + this.helper = helper; + this.evaluator = evaluator; + this.propertyName = propertyName; + evaluator.addPropertyChangeListener(WeakListeners.propertyChange(this, evaluator)); + } + + public synchronized List /**/ getResources() { + if (this.resources == null) { + this.resources = this.getPath (); + } + return this.resources; + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + support.addPropertyChangeListener (listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + support.removePropertyChangeListener (listener); + } + + + public void propertyChange(PropertyChangeEvent evt) { + if (!evt.getPropertyName().equals(propertyName)) { + // Not interesting to us. + return; + } + // Coalesce changes; can come in fast after huge CP changes (#47910): + if (!dirty) { + dirty = true; + ProjectManager.mutex().postReadRequest(this); + } + } + + public void run() { + dirty = false; + List newRoots = getPath (); + boolean fire = false; + synchronized (this) { + if (this.resources != null && !this.resources.equals(newRoots)) { + this.resources = newRoots; + fire = true; + } + } + if (fire) { + support.firePropertyChange (PROP_RESOURCES,null,null); + } + } + + private List getPath() { + List result = new ArrayList (); + String prop = evaluator.getProperty(propertyName); + if (prop != null) { + String[] pieces = PropertyUtils.tokenizePath(prop); + for (int i = 0; i < pieces.length; i++) { + File f = helper.resolveFile(pieces[i]); + try { + URL entry = f.toURI().toURL(); + if (FileUtil.isArchiveFile(entry) || (f.isFile() && f.length()<4)) { //XXX: Not yet closed archive file + entry = FileUtil.getArchiveRoot(entry); + } else if (!f.exists()) { + // if file does not exist (e.g. build/classes folder + // was not created yet) then corresponding File will + // not be ended with slash. Fix that. + assert !entry.toExternalForm().endsWith("/") : f; // NOI18N + entry = new URL(entry.toExternalForm() + "/"); // NOI18N + } + result.add(ClassPathSupport.createResource(entry)); + } catch (MalformedURLException mue) { + assert false : mue; + } + } + } + return Collections.unmodifiableList(result); + } + +} Index: java/project/src/org/netbeans/spi/java/project/classpath/support/ProjectClassPathSupport.java =================================================================== RCS file: java/project/src/org/netbeans/spi/java/project/classpath/support/ProjectClassPathSupport.java diff -N java/project/src/org/netbeans/spi/java/project/classpath/support/ProjectClassPathSupport.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ java/project/src/org/netbeans/spi/java/project/classpath/support/ProjectClassPathSupport.java 6 Jan 2005 13:00:31 -0000 @@ -0,0 +1,45 @@ +/* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun + * Microsystems, Inc. All Rights Reserved. + */ +package org.netbeans.spi.java.project.classpath.support; + +import org.netbeans.spi.java.classpath.ClassPathImplementation; +import org.netbeans.spi.project.support.ant.AntProjectHelper; +import org.netbeans.spi.project.support.ant.PropertyEvaluator; + +/** + * ProjectClassPathSupport is a support class for creating classpath based + * on the single ant property. + * @since org.netbeans.modules.java.project 1.3 + * @author Tomas Zezula + */ +public class ProjectClassPathSupport { + + /** Creates a new instance of NewClass */ + private ProjectClassPathSupport() { + } + + + /** + * Creates new classpath based on the ant property. The returned classpath + * listens on changes of property value. + * @param helper {@link AntProjectHelper} used to resolve files + * @param evaluator {@link PropertyEvaluator} used for obtaining the value of + * given property and listening on value changes. + * @param propertyName the name of ant property holding the classpath + */ + public static ClassPathImplementation createPropertyBasedClassPathImplementation (AntProjectHelper helper, + PropertyEvaluator evaluator, String propertyName) { + return new ProjectClassPathImplementation (helper, propertyName, evaluator); + } + +} Index: java/project/test/unit/src/org/netbeans/spi/java/project/classpath/support/ProjectClassPathImplementationTest.java =================================================================== RCS file: java/project/test/unit/src/org/netbeans/spi/java/project/classpath/support/ProjectClassPathImplementationTest.java diff -N java/project/test/unit/src/org/netbeans/spi/java/project/classpath/support/ProjectClassPathImplementationTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ java/project/test/unit/src/org/netbeans/spi/java/project/classpath/support/ProjectClassPathImplementationTest.java 6 Jan 2005 13:00:31 -0000 @@ -0,0 +1,130 @@ +/* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package org.netbeans.spi.java.project.classpath.support; + + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import org.netbeans.api.java.classpath.ClassPath; +import org.netbeans.api.project.Project; +import org.netbeans.api.project.ProjectManager; +import org.netbeans.junit.NbTestCase; +import org.netbeans.spi.java.classpath.ClassPathFactory; +import org.netbeans.spi.java.classpath.ClassPathImplementation; +import org.netbeans.spi.java.classpath.support.ClassPathSupport; +import org.netbeans.spi.project.support.ant.AntBasedTestUtil; +import org.netbeans.spi.project.support.ant.PropertyEvaluator; +import org.netbeans.spi.project.support.ant.PropertyUtils; +import org.openide.filesystems.FileObject; +import org.netbeans.api.project.TestUtil; +import org.netbeans.spi.project.support.ant.AntProjectHelper; +import org.netbeans.spi.project.support.ant.EditableProperties; +import org.netbeans.spi.project.support.ant.ProjectGenerator; +import org.openide.filesystems.FileUtil; +import org.openide.filesystems.Repository; +import org.openide.util.Lookup; + +/** + * Tests for {@link ProjectClassPathImplementation}. + * @author Tomas Zezula + */ +public class ProjectClassPathImplementationTest extends NbTestCase { + + private static final String PROP_NAME = "classpath"; //NOI18N + + public ProjectClassPathImplementationTest(String testName) { + super(testName); + } + + private FileObject scratch; + private FileObject projdir; + private FileObject[] cpRoots; + private AntProjectHelper helper; + private PropertyEvaluator evaluator; + + protected void setUp() throws Exception { + super.setUp(); + TestUtil.setLookup(new Object[] { + new org.netbeans.modules.projectapi.SimpleFileOwnerQueryImplementation(), + AntBasedTestUtil.testAntBasedProjectType(), + }, ProjectClassPathImplementation.class.getClassLoader()); + } + + protected void tearDown() throws Exception { + scratch = null; + projdir = null; + cpRoots = null; + helper = null; + evaluator = null; + TestUtil.setLookup(Lookup.EMPTY); + super.tearDown(); + } + + + private void prepareProject () throws IOException { + scratch = TestUtil.makeScratchDir(this); + projdir = scratch.createFolder("proj"); //NOI18N + cpRoots = new FileObject[2]; + cpRoots[0] = scratch.createFolder("cpRoot1"); //NOI18N + cpRoots[1] = scratch.createFolder("cpRoot2"); //NOI18N + helper = ProjectGenerator.createProject(projdir, "test"); //NOI18N + evaluator = helper.getStandardPropertyEvaluator(); + setClassPath(cpRoots); + } + + public void testBootClassPathImplementation () throws Exception { + prepareProject(); + ClassPathImplementation cpImpl = ProjectClassPathSupport.createPropertyBasedClassPathImplementation(helper, evaluator, PROP_NAME); + ClassPath cp = ClassPathFactory.createClassPath(cpImpl); + FileObject[] fo = cp.getRoots(); + assertEquals ("Wrong ClassPath roots",Arrays.asList(cpRoots), Arrays.asList(fo)); //NOI18N + cpRoots = new FileObject[] {cpRoots[0]}; + setClassPath(cpRoots); + fo = cp.getRoots(); + assertEquals ("Wrong ClassPath roots",Arrays.asList(cpRoots), Arrays.asList(fo)); //NOI18N + } + + + + private void setClassPath (FileObject[] cpRoots) { + EditableProperties props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); + props.setProperty (PROP_NAME,toPath(cpRoots)); + helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props); + } + + + private static String toPath (FileObject[] cpRoots) { + StringBuffer result = new StringBuffer (); + for (int i=0; i0) { + result.append(':'); //NOI18N + } + File f = FileUtil.toFile (cpRoots[i]); + result.append (f.getAbsolutePath()); + } + return result.toString(); + } + + + + + +} Index: ide/golden/public-packages.txt =================================================================== RCS file: /cvs/ide/golden/public-packages.txt,v retrieving revision 1.6 diff -u -r1.6 public-packages.txt --- ide/golden/public-packages.txt 5 Jan 2005 11:47:50 -0000 1.6 +++ ide/golden/public-packages.txt 6 Jan 2005 13:00:32 -0000 @@ -230,6 +230,7 @@ org.netbeans.spi.java.classpath org.netbeans.spi.java.classpath.support org.netbeans.spi.java.platform +org.netbeans.spi.java.project.classpath.support org.netbeans.spi.java.project.support.ui org.netbeans.spi.java.project.support.ui.templates org.netbeans.spi.java.queries