changeset: 81852:fc4d12ede2eb user: Tomas Zezula date: Fri May 30 08:37:03 2008 +0200 summary: Splitting api.java into api.java.classpath and api.java diff --git a/api.java.classpath/arch.xml b/api.java.classpath/arch.xml new file mode 100644 --- /dev/null +++ b/api.java.classpath/arch.xml @@ -0,0 +1,1041 @@ + + + +]> + + + + &api-questions; + + + + + + The ClassPath APIs provides java classpath like ordered collection of (source) + roots with ability to listen on changes and helper methods like finding the file + under the roots, returning a path from root to given file. It also provides a + registry where projects register their classpaths to make them visible to languages + infrastructure. + + + + + + + +

+ Ought to be covered by unit tests. +

+
+ + + + + +

+ Essentially done. +

+
+ + + + + +

+ The API is widely used by all sorts of IDE modules which need to work with + sources. The SPI is intended mainly for (java) platforms and + library providers, and project type providers, to declare all of this + information. +

+
+ + + + + +

+ Models basic aspects of the metadata surrounding list of source roots, such as + the classpath. More information in the Javadoc. +

+
+ + + + + +

+ No I18N issues. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No settings. +

+
+ + + + + +

+ 1.5+. +

+
+ + + + + +

+ JRE. +

+
+ + + + + +
    +
  • + +

    + For many purposes. +

    +
    +
  • +
  • + +

    + NbClassLoader is used by + ClassPath.getClassLoader(...). +

    +
    +
  • +
+
+ + + + + +

+ None. +

+
+ + + + + +

+ Any. +

+
+ + + + +Nothing. + + + + + + +

+ Just a JAR. +

+
+ + + + + +

+ Yes. +

+
+ + + + + +

+ Yes, only API and SPI packages are exported. +

+
+ + + + + +

+ Anywhere. +

+
+ + + + + +

+ There is support for getting a class loader corresponding to a given + classpath, useful e.g. for loading user JavaBeans to introspect. This is not + used within the module itself. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ Currently each data structure is intended to be thread-safe. +

+
+ + + + + +

+ None. +

+
+ + + + + +

+ None. +

+
+ + + + + +

+ None. +

+
+ + + + + +

+ Yes, query implementations are found using Lookup as usual. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ None known. +

+
+ + + + + +

+ TBD, but probably little. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ Queries perform linearly in number of implementations, but as usual there will + typically be only one or two implementations, e.g. delegating to owner + projects. +

+

+ Currently ClassPaths keep global file change listeners to permit + roots to be invalidated, and this makes file change events linear in the + number of ClassPath objects. This area is being studied and will + hopefully be optimized, perhaps reducing overhead to a small constant. + May require explicit support from the Filesystems API to fully optimize. +

+
+ + + + + +

+ No special provisions. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + +

+ ClassPath.getClassLoader(...) is granted all permissions. +

+
+ + + + + +

+ No. +

+
+ + + + + + + + + + + + + + +

+ XXX no answer for compat-deprecation +

+
+ + + + + +

+ XXX no answer for exec-ant-tasks +

+
+ + + + + +

+ XXX no answer for resources-preferences +

+
+ +
diff --git a/api.java.classpath/build.xml b/api.java.classpath/build.xml new file mode 100644 --- /dev/null +++ b/api.java.classpath/build.xml @@ -0,0 +1,5 @@ + + + Builds, tests, and runs the project org.netbeans.api.java.classpath + + diff --git a/api.java.classpath/manifest.mf b/api.java.classpath/manifest.mf new file mode 100644 --- /dev/null +++ b/api.java.classpath/manifest.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +OpenIDE-Module: org.netbeans.api.java.classpath/1 +OpenIDE-Module-Localizing-Bundle: org/netbeans/api/java/classpath/Bundle.properties +OpenIDE-Module-Specification-Version: 1.0 + diff --git a/api.java.classpath/nbproject/project.properties b/api.java.classpath/nbproject/project.properties new file mode 100644 --- /dev/null +++ b/api.java.classpath/nbproject/project.properties @@ -0,0 +1,4 @@ +is.autoload=true +javac.source=1.5 +javac.compilerargs=-Xlint -Xlint:-serial +test.unit.run.cp.extra=${o.n.core.dir}/lib/boot.jar:${o.n.core.dir}/core/core.jar diff --git a/api.java.classpath/nbproject/project.xml b/api.java.classpath/nbproject/project.xml new file mode 100644 --- /dev/null +++ b/api.java.classpath/nbproject/project.xml @@ -0,0 +1,68 @@ + + + org.netbeans.modules.apisupport.project + + + org.netbeans.api.java.classpath + + + org.openide.execution + + + + 1.12 + + + + org.openide.filesystems + + + + 7.9 + + + + org.openide.io + + + + 1.13 + + + + org.openide.util + + + + 7.13 + + + + + + unit + + org.openide.util + + + org.openide.modules + + + org.netbeans.modules.masterfs + + + + qa-functional + + + + org.netbeans.api.java.classpath + org.netbeans.api.java.queries + org.netbeans.spi.java.classpath + org.netbeans.spi.java.classpath.support + org.netbeans.spi.java.queries + org.netbeans.spi.java.queries.support + + + + diff --git a/api.java/src/org/netbeans/api/java/classpath/Bundle.properties b/api.java.classpath/src/org/netbeans/api/java/classpath/Bundle.properties rename from api.java/src/org/netbeans/api/java/classpath/Bundle.properties rename to api.java.classpath/src/org/netbeans/api/java/classpath/Bundle.properties --- a/api.java/src/org/netbeans/api/java/classpath/Bundle.properties +++ b/api.java.classpath/src/org/netbeans/api/java/classpath/Bundle.properties @@ -1,46 +1,5 @@ -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. -# -# Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. -# -# The contents of this file are subject to the terms of either the GNU -# General Public License Version 2 only ("GPL") or the Common -# Development and Distribution License("CDDL") (collectively, the -# "License"). You may not use this file except in compliance with the -# License. You can obtain a copy of the License at -# http://www.netbeans.org/cddl-gplv2.html -# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the -# specific language governing permissions and limitations under the -# License. When distributing the software, include this License Header -# Notice in each file and include the License file at -# nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this -# particular file as subject to the "Classpath" exception as provided -# by Sun in the GPL Version 2 section of the License file that -# accompanied this code. If applicable, add the following below the -# License Header, with the fields enclosed by brackets [] replaced by -# your own identifying information: -# "Portions Copyrighted [year] [name of copyright owner]" -# -# Contributor(s): -# -# The Original Software is NetBeans. The Initial Developer of the Original -# Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun -# Microsystems, Inc. All Rights Reserved. -# -# If you wish your version of this file to be governed by only the CDDL -# or only the GPL Version 2, indicate your decision by adding -# "[Contributor] elects to include this software in this distribution -# under the [CDDL or GPL Version 2] license." If you do not indicate a -# single choice of license, a recipient has the option to distribute -# your version of this file under either the CDDL, the GPL Version 2 or -# to extend the choice of license to its licensees as provided above. -# However, if you add GPL Version 2 code and therefore, elected the GPL -# Version 2 license, then the option applies only if the new code is -# made subject to such option by the copyright holder. - -# Localizable strings from module's manifest -OpenIDE-Module-Name=Java Support APIs -OpenIDE-Module-Display-Category=Infrastructure -OpenIDE-Module-Short-Description=APIs for Java development support modules -OpenIDE-Module-Long-Description=Allows other modules to use services \ -provided by Java module. - +OpenIDE-Module-Display-Category=Base IDE +OpenIDE-Module-Long-Description=\ + Provides Classpath representing list of (source) roots and operations on them. +OpenIDE-Module-Name=Classpath APIs +OpenIDE-Module-Short-Description=Classpath APIs diff --git a/api.java/src/org/netbeans/api/java/classpath/ClassLoaderSupport.java b/api.java.classpath/src/org/netbeans/api/java/classpath/ClassLoaderSupport.java rename from api.java/src/org/netbeans/api/java/classpath/ClassLoaderSupport.java rename to api.java.classpath/src/org/netbeans/api/java/classpath/ClassLoaderSupport.java diff --git a/api.java/src/org/netbeans/api/java/classpath/ClassPath.java b/api.java.classpath/src/org/netbeans/api/java/classpath/ClassPath.java rename from api.java/src/org/netbeans/api/java/classpath/ClassPath.java rename to api.java.classpath/src/org/netbeans/api/java/classpath/ClassPath.java diff --git a/api.java/src/org/netbeans/api/java/classpath/GlobalPathRegistry.java b/api.java.classpath/src/org/netbeans/api/java/classpath/GlobalPathRegistry.java rename from api.java/src/org/netbeans/api/java/classpath/GlobalPathRegistry.java rename to api.java.classpath/src/org/netbeans/api/java/classpath/GlobalPathRegistry.java diff --git a/api.java/src/org/netbeans/api/java/classpath/GlobalPathRegistryEvent.java b/api.java.classpath/src/org/netbeans/api/java/classpath/GlobalPathRegistryEvent.java rename from api.java/src/org/netbeans/api/java/classpath/GlobalPathRegistryEvent.java rename to api.java.classpath/src/org/netbeans/api/java/classpath/GlobalPathRegistryEvent.java diff --git a/api.java/src/org/netbeans/api/java/classpath/GlobalPathRegistryListener.java b/api.java.classpath/src/org/netbeans/api/java/classpath/GlobalPathRegistryListener.java rename from api.java/src/org/netbeans/api/java/classpath/GlobalPathRegistryListener.java rename to api.java.classpath/src/org/netbeans/api/java/classpath/GlobalPathRegistryListener.java diff --git a/api.java/src/org/netbeans/api/java/classpath/package.html b/api.java.classpath/src/org/netbeans/api/java/classpath/package.html rename from api.java/src/org/netbeans/api/java/classpath/package.html rename to api.java.classpath/src/org/netbeans/api/java/classpath/package.html diff --git a/api.java/src/org/netbeans/api/java/queries/BinaryForSourceQuery.java b/api.java.classpath/src/org/netbeans/api/java/queries/BinaryForSourceQuery.java rename from api.java/src/org/netbeans/api/java/queries/BinaryForSourceQuery.java rename to api.java.classpath/src/org/netbeans/api/java/queries/BinaryForSourceQuery.java diff --git a/api.java/src/org/netbeans/api/java/queries/SourceForBinaryQuery.java b/api.java.classpath/src/org/netbeans/api/java/queries/SourceForBinaryQuery.java rename from api.java/src/org/netbeans/api/java/queries/SourceForBinaryQuery.java rename to api.java.classpath/src/org/netbeans/api/java/queries/SourceForBinaryQuery.java diff --git a/api.java.classpath/src/org/netbeans/modules/java/classpath/ClassPathAccessor.java b/api.java.classpath/src/org/netbeans/modules/java/classpath/ClassPathAccessor.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/modules/java/classpath/ClassPathAccessor.java @@ -0,0 +1,65 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.modules.java.classpath; + +import org.netbeans.api.java.classpath.ClassPath; +import org.netbeans.spi.java.classpath.ClassPathImplementation; + + +public abstract class ClassPathAccessor { + + public static ClassPathAccessor DEFAULT; + + // force loading of ClassPath class. That will set DEFAULT variable. + static { + Class c = ClassPath.class; + try { + Class.forName(c.getName(), true, c.getClassLoader()); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public abstract ClassPath createClassPath(ClassPathImplementation spiClasspath); + + public abstract ClassPathImplementation getClassPathImpl (ClassPath cp); + +} diff --git a/api.java.classpath/src/org/netbeans/modules/java/classpath/ProxyClassPathImplementation.java b/api.java.classpath/src/org/netbeans/modules/java/classpath/ProxyClassPathImplementation.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/modules/java/classpath/ProxyClassPathImplementation.java @@ -0,0 +1,145 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.modules.java.classpath; + +import org.netbeans.spi.java.classpath.ClassPathImplementation; +import org.netbeans.spi.java.classpath.PathResourceImplementation; + +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Collections; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeEvent; +import org.openide.util.WeakListeners; + +/** ProxyClassPathImplementation provides read only proxy for ClassPathImplementations. + * The order of the resources is given by the order of its delegates. + * The proxy is designed to be used as a union of class paths. + * E.g. to be able to easily iterate or listen on all design resources = sources + compile resources + */ +public class ProxyClassPathImplementation implements ClassPathImplementation { + + private ClassPathImplementation[] classPaths; + private List resourcesCache; + private ArrayList listeners; + private PropertyChangeListener classPathsListener; + + public ProxyClassPathImplementation (ClassPathImplementation[] classPaths) { + if (classPaths == null) + throw new IllegalArgumentException (); + List impls = new ArrayList (); + classPathsListener = new DelegatesListener (); + for (ClassPathImplementation cpImpl : classPaths) { + if (cpImpl == null) + continue; + cpImpl.addPropertyChangeListener (WeakListeners.propertyChange(classPathsListener,cpImpl)); + impls.add (cpImpl); + } + this.classPaths = impls.toArray(new ClassPathImplementation[impls.size()]); + } + + + + public List getResources() { + synchronized (this) { + if (this.resourcesCache != null) { + return this.resourcesCache; + } + } + + ArrayList result = new ArrayList (classPaths.length*10); + for (ClassPathImplementation cpImpl : classPaths) { + List subPath = cpImpl.getResources(); + assert subPath != null : "ClassPathImplementation.getResources() returned null. ClassPathImplementation.class: " + + cpImpl.getClass().toString() + " ClassPathImplementation: " + cpImpl.toString(); + result.addAll (subPath); + } + + synchronized (this) { + if (this.resourcesCache == null) { + resourcesCache = Collections.unmodifiableList (result); + } + return this.resourcesCache; + } + } + + public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { + if (this.listeners == null) + this.listeners = new ArrayList (); + this.listeners.add (listener); + } + + public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { + if (this.listeners == null) + return; + this.listeners.remove (listener); + } + + public String toString () { + StringBuilder builder = new StringBuilder("["); //NOI18N + for (ClassPathImplementation cpImpl : this.classPaths) { + builder.append (cpImpl.toString()); + builder.append(", "); //NOI18N + } + builder.append ("]"); //NOI18N + return builder.toString (); + } + + + private class DelegatesListener implements PropertyChangeListener { + + public void propertyChange(PropertyChangeEvent evt) { + PropertyChangeListener[] _listeners; + synchronized (ProxyClassPathImplementation.this) { + ProxyClassPathImplementation.this.resourcesCache = null; //Clean the cache + if (ProxyClassPathImplementation.this.listeners == null) + return; + _listeners = ProxyClassPathImplementation.this.listeners.toArray(new PropertyChangeListener[ProxyClassPathImplementation.this.listeners.size()]); + } + PropertyChangeEvent event = new PropertyChangeEvent (ProxyClassPathImplementation.this, evt.getPropertyName(),null,null); + for (PropertyChangeListener l : _listeners) { + l.propertyChange (event); + } + } + } + +} diff --git a/api.java.classpath/src/org/netbeans/modules/java/classpath/SimpleClassPathImplementation.java b/api.java.classpath/src/org/netbeans/modules/java/classpath/SimpleClassPathImplementation.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/modules/java/classpath/SimpleClassPathImplementation.java @@ -0,0 +1,91 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.modules.java.classpath; + +import java.util.List; +import java.beans.PropertyChangeListener; +import java.net.URL; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; + +import org.netbeans.spi.java.classpath.ClassPathImplementation; +import org.netbeans.spi.java.classpath.PathResourceImplementation; + + +public class SimpleClassPathImplementation implements ClassPathImplementation { + + List entries; + + public SimpleClassPathImplementation() { + this(new ArrayList()); + } + + public SimpleClassPathImplementation(List entries) { + this.entries = entries; + } + + public List getResources() { + return Collections.unmodifiableList(entries); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + // XXX TBD + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + // XXX TBD + } + + public String toString () { + StringBuilder builder = new StringBuilder ("SimpleClassPathImplementation["); //NOI18N + for (PathResourceImplementation impl : this.entries) { + URL[] roots = impl.getRoots(); + for (URL root : roots) { + builder.append (root.toExternalForm()); + builder.append (", "); //NOI18N + } + } + builder.append ("]"); //NOI18N + return builder.toString (); + } +} diff --git a/api.java.classpath/src/org/netbeans/modules/java/classpath/SimplePathResourceImplementation.java b/api.java.classpath/src/org/netbeans/modules/java/classpath/SimplePathResourceImplementation.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/modules/java/classpath/SimplePathResourceImplementation.java @@ -0,0 +1,91 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.modules.java.classpath; + + +import org.netbeans.spi.java.classpath.support.PathResourceBase; +import org.netbeans.spi.java.classpath.ClassPathImplementation; + +import java.net.URL; + + +/** + * Provides implementation of the single rooted PathResoruceImplementation + */ + +public final class SimplePathResourceImplementation extends PathResourceBase { + + private URL[] url; + + + + public SimplePathResourceImplementation (URL root) { + if (root == null) + throw new IllegalArgumentException (); + this.url = new URL[] {root}; + } + + + public URL[] getRoots() { + return this.url; + } + + public ClassPathImplementation getContent() { + return null; + } + + public String toString () { + return "SimplePathResource{"+this.getRoots()[0]+"}"; //NOI18N + } + + public int hashCode () { + return this.url[0].hashCode(); + } + + public boolean equals (Object other) { + if (other instanceof SimplePathResourceImplementation) { + SimplePathResourceImplementation opr = (SimplePathResourceImplementation) other; + return this.url[0].equals (opr.url[0]); + } + else + return false; + } +} diff --git a/api.java.classpath/src/org/netbeans/modules/java/queries/SFBQImpl2Result.java b/api.java.classpath/src/org/netbeans/modules/java/queries/SFBQImpl2Result.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/modules/java/queries/SFBQImpl2Result.java @@ -0,0 +1,83 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2008 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.java.queries; + +import javax.swing.event.ChangeListener; +import org.netbeans.api.java.queries.SourceForBinaryQuery; +import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; + +/** + * + * @author Tomas Zezula + */ +public class SFBQImpl2Result implements SourceForBinaryQueryImplementation2.Result { + + private final SourceForBinaryQuery.Result delegate; + + public SFBQImpl2Result (final SourceForBinaryQuery.Result result) { + assert result != null; + this.delegate = result; + } + + public boolean preferSources() { + //Preserve the old behavior from 4.0 to 6.1, ignore sources inside archives + final FileObject[] roots = this.delegate.getRoots(); + for (FileObject root : roots) { + if (FileUtil.getArchiveFile(root) != null) { + return false; + } + } + return true; + } + + public FileObject[] getRoots () { + return this.delegate.getRoots(); + } + + public void addChangeListener(ChangeListener l) { + this.delegate.addChangeListener(l); + } + + public void removeChangeListener(ChangeListener l) { + this.delegate.removeChangeListener(l); + } +} diff --git a/api.java.classpath/src/org/netbeans/spi/java/classpath/ClassPathFactory.java b/api.java.classpath/src/org/netbeans/spi/java/classpath/ClassPathFactory.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/spi/java/classpath/ClassPathFactory.java @@ -0,0 +1,88 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ + +package org.netbeans.spi.java.classpath; + +import java.net.URL; +import org.netbeans.api.java.classpath.ClassPath; +import org.netbeans.modules.java.classpath.ClassPathAccessor; +import org.openide.filesystems.FileUtil; + +/** + * Most general way to create {@link ClassPath} instances. + * You are not permitted to create them directly; instead you implement + * {@link ClassPathImplementation} and use this factory. + * See also {@link org.netbeans.spi.java.classpath.support.ClassPathSupport} + * for easier ways to create classpaths. + * @since org.netbeans.api.java/1 1.4 + */ +public final class ClassPathFactory { + + private ClassPathFactory() { + } + + /** + * Create API classpath instance for the given SPI classpath. + * @param spiClasspath instance of SPI classpath + * @return instance of API classpath + */ + public static ClassPath createClassPath(ClassPathImplementation spiClasspath) { +// assert checkEntries (spiClasspath) : "ClassPathImplementation contains invalid root: " + spiClasspath.toString(); //Commented, not to decrease the performance even in the dev build. + return ClassPathAccessor.DEFAULT.createClassPath(spiClasspath); + } + + + private static boolean checkEntries (ClassPathImplementation spiClasspath) { + for (PathResourceImplementation impl : spiClasspath.getResources()) { + URL[] roots = impl.getRoots(); + for (URL root : roots) { + if (FileUtil.isArchiveFile(root)) { + return false; + } + if (root.toExternalForm().endsWith("/")) { // NOI18N + return false; + } + } + } + return true; + } + +} diff --git a/api.java.classpath/src/org/netbeans/spi/java/classpath/ClassPathImplementation.java b/api.java.classpath/src/org/netbeans/spi/java/classpath/ClassPathImplementation.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/spi/java/classpath/ClassPathImplementation.java @@ -0,0 +1,74 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.spi.java.classpath; + +import java.util.List; +import java.beans.PropertyChangeListener; + +/** + * SPI interface for ClassPath. + * @see ClassPathFactory + * @since org.netbeans.api.java/1 1.4 + */ +public interface ClassPathImplementation { + + public static final String PROP_RESOURCES = "resources"; //NOI18N + + /** + * Returns list of entries, the list is unmodifiable. + * @return List of PathResourceImplementation, never returns null + * it may return an empty List + */ + public List getResources(); + + /** + * Adds property change listener. + * The listener is notified when the set of entries has changed. + * @param listener + */ + public void addPropertyChangeListener(PropertyChangeListener listener); + + /** + * Removes property change listener + * @param listener + */ + public void removePropertyChangeListener(PropertyChangeListener listener); +} diff --git a/api.java.classpath/src/org/netbeans/spi/java/classpath/ClassPathProvider.java b/api.java.classpath/src/org/netbeans/spi/java/classpath/ClassPathProvider.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/spi/java/classpath/ClassPathProvider.java @@ -0,0 +1,123 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ + +package org.netbeans.spi.java.classpath; + +import org.netbeans.api.java.classpath.ClassPath; +import org.openide.filesystems.FileObject; + +/** + * Provider interface for Java classpaths. + *

+ * The org.netbeans.modules.java.project module registers an + * implementation of this interface to global lookup which looks for the + * project which owns a file (if any) and checks its lookup for this interface, + * and if it finds an instance, delegates to it. Therefore it is not normally + * necessary for a project type provider to register its own instance just to + * define the classpaths for files it owns, assuming it depends on the Java + * Project module. + *

+ *
+ *

+ * Note that to make editor code completion functionality work for a Java source file the + * following classpaths must be available for it: + *

+ *
    + *
  1. The {@link ClassPath#BOOT} type of classpath + * is required or the source file will not be parsable and + * code completion will be disabled. See also + * {@link org.netbeans.spi.java.queries.SourceLevelQueryImplementation}.
  2. + *
  3. The {@link ClassPath#SOURCE} type of classpath + * is required or code completion will be disabled. + * Providing this classpath will enable code completion, but only elements + * defined on this classpath will be offered if the compile classpath is missing.
  4. + *
  5. The {@link ClassPath#COMPILE} type of classpath + * is recommended to be provide to make code completion work fully + * by suggesting all classes against which the source is developed.
  6. + *
+ *

{@link ClassPath#EXECUTE} is also recommended for e.g. I18N functionality to work. + * This should contain the full run-time classpath of the class, including its build + * location (bytecode).

+ *

You should return these classpaths for the package root folder and any + * files or folders inside it.

+ *

You should register classpaths for source files of all these types in + * {@link org.netbeans.api.java.classpath.GlobalPathRegistry} + * when they are to be exposed in the GUI as available for use (e.g. for the editor's Fast Open dialog), + * and unregister them when they are no longer to be exposed. Typically this is done as part of + * ProjectOpenedHook. + *

It is also desirable to produce classpath information for compiled class files + * (bytecode), including their package roots (whether a disk folder or a JAR root). + * This will enable parsing of the class files, which is sometimes needed (e.g. for + * expanding the class file node and seeing its members). + * Compiled classes should have:

+ *
    + *
  1. {@link ClassPath#BOOT} corresponding to the Java platform to be used with the classes.
  2. + *
  3. {@link ClassPath#EXECUTE} containing the bytecode's package root itself, plus any other + * libraries it needs to resolve against. Should normally be the same as the execute classpath + * of the corresponding source files.
  4. + *
+ *

If no specific class path providers are available for a given source file or bytecode file, + * i.e. null is returned from all providers, there may be a fallback implementation + * which would provide reasonable defaults. For source files, this could mean a boot classpath + * corresponding to the default Java platform (i.e. the JDK being used to run the IDE); empty + * compile and execute classpaths; and a sourcepath computed based on the package statement in the + * source file (if this is possible). For class files, this could mean a boot classpath determined + * as for source files, and an execute classpath containing the package root apparently owning the + * class file (computed according to the class file's package information, if this is possible).

+ *
+ * @see ClassPath#getClassPath + * @see org.netbeans.api.java.classpath.GlobalPathRegistry + * @author Jesse Glick + * @since org.netbeans.api.java/1 1.4 + */ +public interface ClassPathProvider { + + /** + * Find some kind of a classpath for a given file. + * @param file a file somewhere, or a source root + * @param type a classpath type such as {@link ClassPath#COMPILE} + * @return an appropriate classpath, or null for no answer + * @see ClassPathFactory + * @see org.netbeans.spi.java.classpath.support.ClassPathSupport + */ + ClassPath findClassPath(FileObject file, String type); + +} diff --git a/api.java.classpath/src/org/netbeans/spi/java/classpath/FilteringPathResourceImplementation.java b/api.java.classpath/src/org/netbeans/spi/java/classpath/FilteringPathResourceImplementation.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/spi/java/classpath/FilteringPathResourceImplementation.java @@ -0,0 +1,75 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ + +package org.netbeans.spi.java.classpath; + +import java.net.URL; + +/** + * SPI interface for a classpath entry which can include or exclude particular files. + * @author Jesse Glick + * @see "issue #49026" + * @since org.netbeans.api.java/1 1.13 + */ +public interface FilteringPathResourceImplementation extends PathResourceImplementation { + + /** + * Property name to fire in case {@link #includes} would change. + * (The old and new value should be left null.) + *

+ * Special usage note: + * If multiple {@link FilteringPathResourceImplementation}s inside a single + * {@link ClassPathImplementation} fire changes in this pseudo-property in + * succession, all using the same non-null {@link java.beans.PropertyChangeEvent#setPropagationId}, + * {@link org.netbeans.api.java.classpath.ClassPath#PROP_INCLUDES} will be fired just once. This can be used + * to prevent "event storms" from triggering excessive Java source root rescanning. + */ + String PROP_INCLUDES = "includes"; // NOI18N + + /** + * Determines whether a given resource is included in the classpath or not. + * @param root one of the roots given by {@link #getRoots} (else may throw {@link IllegalArgumentException}) + * @param resource a relative resource path within that root; may refer to a file or slash-terminated folder; the empty string refers to the root itself + * @return true if included (or, in the case of a folder, at least partially included); false if excluded + */ + boolean includes(URL root, String resource); + +} diff --git a/api.java.classpath/src/org/netbeans/spi/java/classpath/PathResourceImplementation.java b/api.java.classpath/src/org/netbeans/spi/java/classpath/PathResourceImplementation.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/spi/java/classpath/PathResourceImplementation.java @@ -0,0 +1,87 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.spi.java.classpath; + +import java.beans.PropertyChangeListener; +import java.net.URL; + +/** + * SPI interface for one classpath entry. + * @see ClassPathImplementation + * @since org.netbeans.api.java/1 1.4 + */ +public interface PathResourceImplementation { + + public static final String PROP_ROOTS = "roots"; //NOI18N + + /** Roots of the class path entry. + * In the case of simple resource it returns array containing just one URL. + * In the case of composite resource it returns array containing one or more URL. + * @return array of URL, never returns null. + */ + public URL[] getRoots(); + + /** + * Returns ClassPathImplementation representing the content of the PathResourceImplementation. + * If the PathResourceImplementation represents leaf resource, it returns null. + * The ClassPathImplementation is live and can be used for path resource content + * modification. + *

Semi-deprecated. There was never a real reason for this method to exist. + * If implementing PathResourceImplementation you can simply return null; + * it is unlikely anyone will call this method anyway. + * @return classpath handle in case of composite resource; null for leaf resource + */ + public ClassPathImplementation getContent(); + + /** + * Adds property change listener. + * The listener is notified when the roots of the entry are changed. + * @param listener + */ + public void addPropertyChangeListener(PropertyChangeListener listener); + + /** + * Removes property change listener. + * @param listener + */ + public void removePropertyChangeListener(PropertyChangeListener listener); + +} diff --git a/api.java.classpath/src/org/netbeans/spi/java/classpath/package.html b/api.java.classpath/src/org/netbeans/spi/java/classpath/package.html new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/spi/java/classpath/package.html @@ -0,0 +1,73 @@ + + + + +SPI permitting new classpaths to be constructed and registered. + +

{@link org.netbeans.spi.java.classpath.ClassPathProvider}s can be registered +to default lookup in order to associate information about classpaths with files. +For example, a Java-oriented project type would normally indicate that its Java +sources have a certain classpath associated with them.
+For a source file the ClassPathProvider has to return a +{@link org.netbeans.api.java.classpath.ClassPath} of the following ClassPath types: +

    +
  • ClassPath.SOURCE - the classpath contains the source roots of the project
  • +
  • ClassPath.BOOT - the classpath contains the jdk runtime libraries
  • +
  • ClassPath.COMPILE - the classpath contains the project compile libraries (compile classpath)
  • +
+it may also return a ClassPath of type ClassPath.EXEC pointing to the build output folder. +
+For build output the ClassPathProvider has to return a ClassPath of the following +types: +
    +
  • ClassPath.BOOT - the classpath contains the jdk runtime libraries
  • +
  • ClassPath.COMPILE - the classpath contains the project compile libraries (compile classpath)
  • +
  • ClassPath.EXEC - the classpath contains the build output folder
  • +
+

+ +

{@link org.netbeans.spi.java.classpath.ClassPathFactory} may be used to +create new {@link org.netbeans.api.java.classpath.ClassPath} instances.

+ + + diff --git a/api.java.classpath/src/org/netbeans/spi/java/classpath/support/ClassPathSupport.java b/api.java.classpath/src/org/netbeans/spi/java/classpath/support/ClassPathSupport.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/spi/java/classpath/support/ClassPathSupport.java @@ -0,0 +1,213 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.spi.java.classpath.support; + +import java.io.File; +import org.netbeans.spi.java.classpath.PathResourceImplementation; +import org.netbeans.spi.java.classpath.ClassPathImplementation; +import org.netbeans.spi.java.classpath.ClassPathFactory; +import org.netbeans.modules.java.classpath.*; +import org.netbeans.api.java.classpath.ClassPath; +import org.openide.ErrorManager; +import org.openide.filesystems.FileObject; + +import java.net.URL; +import java.util.List; +import java.util.ArrayList; +import org.openide.filesystems.FileStateInvalidException; +import org.openide.filesystems.FileUtil; + +/** + * Convenience factory for creating classpaths of common sorts. + * @since org.netbeans.api.java/1 1.4 + */ +public class ClassPathSupport { + + private ClassPathSupport () { + } + + + /** Creates leaf PathResourceImplementation. + * The created PathResourceImplementation has exactly one immutable root. + * @param url the root of the resource. The URL must refer to folder. In the case of archive file + * the jar protocol URL must be used. + * @return PathResourceImplementation + */ + public static PathResourceImplementation createResource (URL url) { + if (url == null) { + throw new NullPointerException("Cannot pass null URL to ClassPathSupport.createResource"); // NOI18N + } + // FU.iAF is a bit slow, so don't call it except when assertions are on: + boolean assertions = false; + assert assertions = true; + if (assertions && FileUtil.isArchiveFile(url)) { + throw new IllegalArgumentException("File URL pointing to " + // NOI18N + "JAR is not valid classpath entry. Use jar: URL. Was: "+url); // NOI18N + } + if (!url.toExternalForm().endsWith("/")) { // NOI18N + throw new IllegalArgumentException("URL must be a folder URL (append '/' if necessary): " + url); // NOI18N + } + return new SimplePathResourceImplementation (url); + } + + + /** + * Create ClassPathImplementation for the given list of + * {@link PathResourceImplementation} entries. + * @param entries list of {@link PathResourceImplementation} instances; + * cannot be null; can be empty + * @return SPI classpath + */ + public static ClassPathImplementation createClassPathImplementation(List< ? extends PathResourceImplementation> entries) { + if (entries == null) { + throw new NullPointerException("Cannot pass null entries"); // NOI18N + } + return new SimpleClassPathImplementation(entries); + } + + + /** + * Create ClassPath for the given list of + * {@link PathResourceImplementation} entries. + * @param entries list of {@link PathResourceImplementation} instances; + * cannot be null; can be empty + * @return API classpath + */ + public static ClassPath createClassPath(List entries) { + if (entries == null) { + throw new NullPointerException("Cannot pass null entries"); // NOI18N + } + return ClassPathFactory.createClassPath(createClassPathImplementation(entries)); + } + + + /** + * Create ClassPath for the given array of class path roots + * @param roots array of fileobjects which must correspond to directory. + * In the case of archive file, the FileObject representing the root of the + * archive must be used. Cannot be null; can be empty array; array can contain nulls. + * @return API classpath + */ + public static ClassPath createClassPath(FileObject... roots) { + assert roots != null; + List l = new ArrayList (); + for (FileObject root : roots) { + if (root == null) { + continue; + } + try { + URL u = root.getURL(); + l.add(createResource(u)); + } catch (FileStateInvalidException e) { + ErrorManager.getDefault().notify (e); + } + } + return createClassPath (l); + } + + + /** + * Create ClassPath for the given array of class path roots + * @param roots array of URLs which must correspond to directory. + * In the case of archive file, the jar protocol URL must be used. + * Cannot be null; can be empty array; array can contain nulls. + * @return API classpath + */ + public static ClassPath createClassPath(URL... roots) { + assert roots != null; + List l = new ArrayList (); + for (URL root : roots) { + if (root == null) + continue; + l.add (createResource(root)); + } + return createClassPath(l); + } + + /** + * Convenience method to create a classpath object from a conventional string representation. + * @param jvmPath a JVM-style classpath (folder or archive paths separated by {@link File#pathSeparator}) + * @return a corresponding classpath object + * @throws IllegalArgumentException in case a path entry looks to be invalid + * @since org.netbeans.api.java/1 1.15 + * @see FileUtil#urlForArchiveOrDir + * @see ClassPath#toJVMPath + */ + public static ClassPath createClassPath(String jvmPath) throws IllegalArgumentException { + List l = new ArrayList(); + for (String piece : jvmPath.split(File.pathSeparator)) { + File f = FileUtil.normalizeFile(new File(piece)); + URL u = FileUtil.urlForArchiveOrDir(f); + if (u == null) { + throw new IllegalArgumentException("Path entry looks to be invalid: " + piece); // NOI18N + } + l.add(createResource(u)); + } + return createClassPath(l); + } + + /** + * Creates read only proxy ClassPathImplementation for given delegates. + * The order of resources is given by the order of the delegates + * @param delegates ClassPathImplementations to delegate to. + * @return SPI classpath + */ + public static ClassPathImplementation createProxyClassPathImplementation(ClassPathImplementation... delegates) { + return new ProxyClassPathImplementation (delegates); + } + + + /** + * Creates read only proxy ClassPath for given delegates. + * The order of resources is given by the order of the delegates + * @param delegates ClassPaths to delegate to. + * @return API classpath + */ + public static ClassPath createProxyClassPath(ClassPath... delegates) { + assert delegates != null; + ClassPathImplementation[] impls = new ClassPathImplementation [delegates.length]; + for (int i = 0; i < delegates.length; i++) { + impls[i] = ClassPathAccessor.DEFAULT.getClassPathImpl (delegates[i]); + } + return ClassPathFactory.createClassPath (createProxyClassPathImplementation(impls)); + } + +} diff --git a/api.java.classpath/src/org/netbeans/spi/java/classpath/support/CompositePathResourceBase.java b/api.java.classpath/src/org/netbeans/spi/java/classpath/support/CompositePathResourceBase.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/spi/java/classpath/support/CompositePathResourceBase.java @@ -0,0 +1,157 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.spi.java.classpath.support; + +import org.netbeans.spi.java.classpath.PathResourceImplementation; +import org.netbeans.spi.java.classpath.ClassPathImplementation; + +import java.net.URL; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeEvent; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Arrays; + +/** + * This class provides a base class for PathResource implementations + * @since org.netbeans.api.java/1 1.4 + */ +public abstract class CompositePathResourceBase implements PathResourceImplementation { + + private URL[] roots; + private ClassPathImplementation model; + private ArrayList pListeners; + + /** + * Returns the roots of the PathResource + * @return URL[] + */ + public final URL[] getRoots() { + if (this.roots == null) { + synchronized (this) { + if (this.roots == null) { + initContent (); + List result = new ArrayList (); + for (PathResourceImplementation pri : this.model.getResources()) { + result.addAll (Arrays.asList(pri.getRoots())); + } + this.roots = result.toArray (new URL [result.size()]); + } + } + } + return this.roots; + } + + + /** + * Returns the ClassPathImplementation representing the content of this PathResourceImplementation + * @return ClassPathImplementation + */ + public final ClassPathImplementation getContent() { + initContent (); + return this.model; + } + + /** + * Adds property change listener. + * The listener is notified when the roots of the PathResource are changed. + * @param listener + */ + public synchronized final void addPropertyChangeListener(PropertyChangeListener listener) { + if (this.pListeners == null) + this.pListeners = new ArrayList (); + this.pListeners.add (listener); + } + + /** + * Removes PropertyChangeListener + * @param listener + */ + public synchronized final void removePropertyChangeListener(PropertyChangeListener listener) { + if (this.pListeners == null) + return; + this.pListeners.remove (listener); + } + + /** + * Fires PropertyChangeEvent + * @param propName name of property + * @param oldValue old property value or null + * @param newValue new property value or null + */ + protected final void firePropertyChange (String propName, Object oldValue, Object newValue) { + PropertyChangeListener[] _listeners; + synchronized (this) { + if (this.pListeners == null) + return; + _listeners = this.pListeners.toArray(new PropertyChangeListener[this.pListeners.size()]); + } + PropertyChangeEvent event = new PropertyChangeEvent (this, propName, oldValue, newValue); + for (PropertyChangeListener l : _listeners) { + l.propertyChange (event); + } + } + + /** Creates the array of the roots of PathResource. + * Most PathResource (directory, jar) have single root, + * but the PathResource can have more than one root to + * represent more complex resources like libraries. + * The returned value is cached. + * @return ClassPathImplementation + */ + protected abstract ClassPathImplementation createContent (); + + + private synchronized void initContent () { + if (this.model == null) { + ClassPathImplementation cp = createContent (); + assert cp != null; + cp.addPropertyChangeListener (new PropertyChangeListener () { + public void propertyChange (PropertyChangeEvent event) { + roots = null; + firePropertyChange (PROP_ROOTS, null,null); + } + }); + this.model = cp; + } + } +} diff --git a/api.java.classpath/src/org/netbeans/spi/java/classpath/support/PathResourceBase.java b/api.java.classpath/src/org/netbeans/spi/java/classpath/support/PathResourceBase.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/spi/java/classpath/support/PathResourceBase.java @@ -0,0 +1,98 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.spi.java.classpath.support; + + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeEvent; +import java.util.ArrayList; +import java.util.Iterator; +import org.netbeans.spi.java.classpath.PathResourceImplementation; + +/** + * This class provides a base class for PathResource implementations + * @since org.netbeans.api.java/1 1.4 + */ +public abstract class PathResourceBase implements PathResourceImplementation { + + private ArrayList pListeners; + + + /** + * Adds property change listener. + * The listener is notified when the roots of the PathResource are changed. + * @param listener + */ + public synchronized final void addPropertyChangeListener(PropertyChangeListener listener) { + if (this.pListeners == null) + this.pListeners = new ArrayList (); + this.pListeners.add (listener); + } + + /** + * Removes PropertyChangeListener + * @param listener + */ + public synchronized final void removePropertyChangeListener(PropertyChangeListener listener) { + if (this.pListeners == null) + return; + this.pListeners.remove (listener); + } + + /** + * Fires PropertyChangeEvent + * @param propName name of property + * @param oldValue old property value or null + * @param newValue new property value or null + */ + protected final void firePropertyChange (String propName, Object oldValue, Object newValue) { + PropertyChangeListener[] _listeners; + synchronized (this) { + if (this.pListeners == null) + return; + _listeners = this.pListeners.toArray(new PropertyChangeListener[this.pListeners.size()]); + } + PropertyChangeEvent event = new PropertyChangeEvent (this, propName, oldValue, newValue); + for (PropertyChangeListener l : _listeners) { + l.propertyChange (event); + } + } +} diff --git a/api.java.classpath/src/org/netbeans/spi/java/classpath/support/package.html b/api.java.classpath/src/org/netbeans/spi/java/classpath/support/package.html new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/spi/java/classpath/support/package.html @@ -0,0 +1,56 @@ + + + + +Convenience classes to make it easier to create classpaths. + +

{@link org.netbeans.spi.java.classpath.support.ClassPathSupport} provides +various ways to create {@link org.netbeans.api.java.classpath.ClassPath} objects +beyond what the plain SPI provides.

+ +

{@link org.netbeans.spi.java.classpath.support.PathResourceBase} and +{@link org.netbeans.spi.java.classpath.support.CompositePathResourceBase} can be +used to define parts of a classpath in a controlled way.

+ + + diff --git a/api.java/src/org/netbeans/spi/java/queries/BinaryForSourceQueryImplementation.java b/api.java.classpath/src/org/netbeans/spi/java/queries/BinaryForSourceQueryImplementation.java rename from api.java/src/org/netbeans/spi/java/queries/BinaryForSourceQueryImplementation.java rename to api.java.classpath/src/org/netbeans/spi/java/queries/BinaryForSourceQueryImplementation.java diff --git a/api.java/src/org/netbeans/spi/java/queries/SourceForBinaryQueryImplementation.java b/api.java.classpath/src/org/netbeans/spi/java/queries/SourceForBinaryQueryImplementation.java rename from api.java/src/org/netbeans/spi/java/queries/SourceForBinaryQueryImplementation.java rename to api.java.classpath/src/org/netbeans/spi/java/queries/SourceForBinaryQueryImplementation.java diff --git a/api.java/src/org/netbeans/spi/java/queries/SourceForBinaryQueryImplementation2.java b/api.java.classpath/src/org/netbeans/spi/java/queries/SourceForBinaryQueryImplementation2.java rename from api.java/src/org/netbeans/spi/java/queries/SourceForBinaryQueryImplementation2.java rename to api.java.classpath/src/org/netbeans/spi/java/queries/SourceForBinaryQueryImplementation2.java diff --git a/api.java.classpath/src/org/netbeans/spi/java/queries/support/SourceForBinaryQueryImpl2Base.java b/api.java.classpath/src/org/netbeans/spi/java/queries/support/SourceForBinaryQueryImpl2Base.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/src/org/netbeans/spi/java/queries/support/SourceForBinaryQueryImpl2Base.java @@ -0,0 +1,73 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2008 Sun Microsystems, Inc. + */ + +package org.netbeans.spi.java.queries.support; + +import org.netbeans.api.java.queries.SourceForBinaryQuery; +import org.netbeans.modules.java.queries.SFBQImpl2Result; +import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2; +import org.openide.util.Parameters; + +/** + * Base class for {@link SourceForBinaryQueryImplementation2} which need to delegate + * to other {@link SourceForBinaryQueryImplementation}. + * @since 1.16 + * @author Tomas Zezula + */ +public abstract class SourceForBinaryQueryImpl2Base implements SourceForBinaryQueryImplementation2 { + + /** + * Creates a wrapper for {@link SourceForBinaryQuery.Result}. This method + * should be used by delegating {@link SourceForBinaryQueryImplementation2} + * which need to delegate to {@link SourceForBinaryQueryImplementation}. + * @param result returned by {@link SourceForBinaryQueryImplementation}, + * When result is already instanceof {@link SourceForBinaryQueryImplementation2.Result} + * it's returned without wrapping. + * @return a {@link SourceForBinaryQueryImplementation2.Result}. + */ + protected final Result asResult (SourceForBinaryQuery.Result result) { + Parameters.notNull("result", result); //NOI18N + if (result instanceof Result) { + return (Result) result; + } + else { + return new SFBQImpl2Result(result); + } + } +} diff --git a/api.java.classpath/test/unit/src/org/netbeans/api/java/classpath/ClassPathTest.java b/api.java.classpath/test/unit/src/org/netbeans/api/java/classpath/ClassPathTest.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/test/unit/src/org/netbeans/api/java/classpath/ClassPathTest.java @@ -0,0 +1,701 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ + +package org.netbeans.api.java.classpath; + +import java.io.File; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.FileOutputStream; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.StringTokenizer; +import java.util.TreeSet; +import java.util.jar.JarOutputStream; +import java.util.logging.Level; +import java.util.zip.ZipEntry; +import org.netbeans.junit.Log; +import org.netbeans.junit.NbTestCase; +import org.netbeans.spi.java.classpath.support.ClassPathSupport; +import org.netbeans.spi.java.classpath.ClassPathImplementation; +import org.netbeans.spi.java.classpath.ClassPathFactory; +import org.netbeans.spi.java.classpath.FilteringPathResourceImplementation; +import org.netbeans.spi.java.classpath.PathResourceImplementation; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; + +public class ClassPathTest extends NbTestCase { + + public ClassPathTest(String testName) { + super(testName); + } + + protected @Override void setUp() throws Exception { + super.setUp(); + clearWorkDir(); + } + + private File getBaseDir() throws Exception { + return FileUtil.normalizeFile(getWorkDir()); + } + + /** + * Tests ClassPath.getResourceName (); + */ + public void testGetResourceName() throws Exception { + File f = getBaseDir(); + f = new File(f.getPath()+"/w.e.i.r.d/f o l d e r"); + f.mkdirs(); + File f2 = new File(f, "org/netbeans/test"); + f2.mkdirs(); + File f3 = new File(f2, "Main.java"); + f3.createNewFile(); + + FileObject cpRoot = FileUtil.toFileObject(f); + FileObject cpItem = FileUtil.toFileObject(f2); + FileObject clazz = FileUtil.toFileObject(f3); + ClassPath cp = ClassPathSupport.createClassPath(new FileObject[]{cpRoot}); + String pkg = cp.getResourceName(cpItem); + assertEquals("org/netbeans/test", pkg); + + pkg = cp.getResourceName(cpItem, '.', true); + assertEquals("org.netbeans.test", pkg); + + pkg = cp.getResourceName(cpItem, '.', false); + assertEquals("org.netbeans.test", pkg); + + pkg = cp.getResourceName(cpItem, '#', true); + assertEquals("org#netbeans#test", pkg); + + pkg = cp.getResourceName(cpItem, '#', false); + assertEquals("org#netbeans#test", pkg); + + pkg = cp.getResourceName(clazz); + assertEquals("org/netbeans/test/Main.java", pkg); + + pkg = cp.getResourceName(clazz, '.', true); + assertEquals("org.netbeans.test.Main.java", pkg); + + pkg = cp.getResourceName(clazz, '.', false); + assertEquals("org.netbeans.test.Main", pkg); + + pkg = cp.getResourceName(clazz, '@', true); + assertEquals("org@netbeans@test@Main.java", pkg); + + pkg = cp.getResourceName(clazz, '@', false); + assertEquals("org@netbeans@test@Main", pkg); + } + + /** + * Tests ClassPath.findAllResources(), ClassPath.findResoruce(), + * ClassPath.contains (), ClassPath.findOwnerRoot(), + * ClassPath.isResourceVisible () + */ + public void testGetResource () throws Exception { + File root_1 = new File (getBaseDir(),"root_1"); + root_1.mkdir(); + File root_2 = new File (getBaseDir(),"root_2"); + root_2.mkdir(); + FileObject[] roots = new FileObject [] { + FileUtil.toFileObject(root_1), + FileUtil.toFileObject(root_2), + }; + + FileObject tmp = roots[0].createFolder("org"); + tmp = tmp.createFolder("me"); + FileObject testFo_1 = tmp.createData("Foo","txt"); + tmp = roots[1].createFolder("org"); + tmp = tmp.createFolder("me"); + FileObject testFo_2 = tmp.createData("Foo","txt"); + ClassPath cp = ClassPathSupport.createClassPath(roots); + + //findResource + assertTrue(cp.findResource ("org/me/Foo.txt")==testFo_1); + assertTrue (cp.findResource("org/me/None.txt")==null); + + //findAllResources + List res = cp.findAllResources ("org/me/Foo.txt"); + assertTrue (res.size() == 2); + assertTrue (res.contains(testFo_1)); + assertTrue (res.contains(testFo_2)); + + //contains + assertTrue (cp.contains (testFo_1)); + assertTrue (cp.contains (testFo_2)); + assertFalse (cp.contains (roots[0].getParent())); + + //findOwnerRoot + assertTrue (cp.findOwnerRoot(testFo_1)==roots[0]); + assertTrue (cp.findOwnerRoot(testFo_2)==roots[1]); + + /* + //isResourceVisible + assertTrue (cp.isResourceVisible(testFo_1)); + assertFalse (cp.isResourceVisible(testFo_2)); + */ + + cp = null; + roots[0].delete(); + roots[1].delete(); + } + + /** + * Test ClassPath.getRoots(), ClassPath.addPropertyChangeListener (), + * ClassPath.entries () and classpath SPI. + */ + public void testListening() throws Exception { + // XXX unreliable, would be improved by usage of TestFileUtils methods: + + File root_1 = new File (getBaseDir(),"root_1"); + root_1.mkdir(); + File root_2 = new File (getBaseDir(),"root_2"); + root_2.mkdir(); + File root_3 = new File (getBaseDir(),"root_3.jar"); + JarOutputStream out = new JarOutputStream ( new FileOutputStream (root_3)); + try { + out.putNextEntry(new ZipEntry("test.txt")); + out.write ("test".getBytes()); + } finally { + out.close (); + } + assertNotNull("Cannot find file",FileUtil.toFileObject(root_1)); + assertNotNull("Cannot find file",FileUtil.toFileObject(root_2)); + assertNotNull("Cannot find file",FileUtil.toFileObject(root_3)); + TestClassPathImplementation impl = new TestClassPathImplementation(); + ClassPath cp = ClassPathFactory.createClassPath (impl); + impl.addResource(root_1.toURI().toURL()); + cp.addPropertyChangeListener (impl); + impl.addResource (root_2.toURI().toURL()); + impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS); + assertTrue (cp.getRoots().length==2); + impl.removeResource (root_2.toURI().toURL()); + impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS); + assertTrue (cp.getRoots().length==1); + FileObject fo = cp.getRoots()[0]; + FileObject parentFolder = fo.getParent(); + fo.delete(); + impl.assertEvents(ClassPath.PROP_ROOTS); + assertTrue (cp.getRoots().length==0); + parentFolder.createFolder("root_1"); + assertTrue (cp.getRoots().length==1); + impl.assertEvents(ClassPath.PROP_ROOTS); + FileObject archiveFile = FileUtil.toFileObject(root_3); + impl.addResource(FileUtil.getArchiveRoot(archiveFile.getURL())); + assertEquals (cp.getRoots().length,2); + impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS); + root_3.delete(); + root_3 = new File (getBaseDir(),"root_3.jar"); + Thread.sleep(1000); + out = new JarOutputStream ( new FileOutputStream (root_3)); + try { + out.putNextEntry(new ZipEntry("test2.txt")); + out.write ("test2".getBytes()); + } finally { + out.close (); + } + archiveFile.refresh(); + impl.assertEvents(ClassPath.PROP_ROOTS); + root_1.delete(); + root_2.delete(); + root_3.delete(); + cp = null; + } + + public void testListening2() throws Exception { + // Checks that changes in PathResourceImplementation.PROP_ROOTS matter. + class FiringPRI implements PathResourceImplementation { + private URL[] roots = new URL[0]; + public URL[] getRoots() { + return roots; + } + void changeRoots(URL[] nue) { + roots = nue; + pcs.firePropertyChange(PROP_ROOTS, null, null); + } + public ClassPathImplementation getContent() { + return null; + } + PropertyChangeSupport pcs = new PropertyChangeSupport(this); + public void addPropertyChangeListener(PropertyChangeListener listener) { + pcs.addPropertyChangeListener(listener); + } + public void removePropertyChangeListener(PropertyChangeListener listener) { + pcs.removePropertyChangeListener(listener); + } + } + FiringPRI pri = new FiringPRI(); + TestClassPathImplementation impl = new TestClassPathImplementation(); + impl.addResource(pri); + ClassPath cp = ClassPathFactory.createClassPath(impl); + assertEquals(Collections.emptyList(), Arrays.asList(cp.getRoots())); + cp.addPropertyChangeListener(impl); + File d = new File(getBaseDir(), "d"); + d.mkdir(); + pri.changeRoots(new URL[] {d.toURI().toURL()}); + impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS); + assertEquals(Collections.singletonList(FileUtil.toFileObject(d)), Arrays.asList(cp.getRoots())); + } + + public void testChangesAcknowledgedWithoutListener() throws Exception { + // Discovered in #72573. + clearWorkDir(); + File root = new File(getWorkDir(), "root"); + URL rootU = root.toURI().toURL(); + if (!rootU.toExternalForm().endsWith("/")) { + rootU = new URL(rootU.toExternalForm() + "/"); + } + ClassPath cp = ClassPathSupport.createClassPath(new URL[] {rootU}); + assertEquals("nothing there yet", null, cp.findResource("f")); + FileObject f = FileUtil.createData(FileUtil.toFileObject(getWorkDir()), "root/f"); + assertEquals("found new file", f, cp.findResource("f")); + f.delete(); + assertEquals("again empty", null, cp.findResource("f")); + } + + static final class TestClassPathImplementation implements ClassPathImplementation, PropertyChangeListener { + + private final PropertyChangeSupport support = new PropertyChangeSupport (this); + private final List resources = new ArrayList (); + private final SortedSet events = new TreeSet(); + + public synchronized void addResource (URL resource) { + PathResourceImplementation pr = ClassPathSupport.createResource (resource); + addResource(pr); + } + + public synchronized void addResource(PathResourceImplementation pr) { + this.resources.add (pr); + this.support.firePropertyChange (ClassPathImplementation.PROP_RESOURCES,null,null); + } + + public synchronized void removeResource (URL resource) { + for (Iterator it = this.resources.iterator(); it.hasNext();) { + PathResourceImplementation pr = (PathResourceImplementation) it.next (); + if (Arrays.asList(pr.getRoots()).contains (resource)) { + this.resources.remove (pr); + this.support.firePropertyChange (ClassPathImplementation.PROP_RESOURCES,null,null); + break; + } + } + } + + public synchronized List getResources() { + return this.resources; + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + this.support.addPropertyChangeListener (listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + this.support.removePropertyChangeListener (listener); + } + + public void propertyChange (PropertyChangeEvent event) { + events.add(event.getPropertyName()); + } + + void assertEvents(String... events) { + assertEquals(new TreeSet(Arrays.asList(events)), this.events); + this.events.clear(); + } + } + + public void testFilteredClassPaths() throws Exception { + FileObject bd = FileUtil.toFileObject(getBaseDir()); + FileObject u1fo = bd.createFolder("u1"); + FileObject u2fo = bd.createFolder("u2"); + final URL u1 = u1fo.getURL(); + final URL u2 = u2fo.getURL(); + class FPRI implements FilteringPathResourceImplementation { + private int modulus = 2; + public void changeIncludes(int modulus) { + this.modulus = modulus; + pcs.firePropertyChange(PROP_INCLUDES, null, null); + } + public URL[] getRoots() { + return new URL[] {u1, u2}; + } + public boolean includes(URL root, String resource) { + int offset; + if (root.equals(u1)) { + offset = 0; + } else if (root.equals(u2)) { + offset = 1; + } else { + throw new IllegalArgumentException(root.toString()); + } + return (offset + resource.length()) % modulus == 0; + } + public ClassPathImplementation getContent() { + return null; + } + private PropertyChangeSupport pcs = new PropertyChangeSupport(this); + public void addPropertyChangeListener(PropertyChangeListener listener) { + pcs.addPropertyChangeListener(listener); + } + public void removePropertyChangeListener(PropertyChangeListener listener) { + pcs.removePropertyChangeListener(listener); + } + } + FPRI pr = new FPRI(); + TestClassPathImplementation impl = new TestClassPathImplementation(); + impl.addResource(pr); + ClassPath cp = ClassPathFactory.createClassPath(impl); + FileObject xx1 = u1fo.createData("xx"); + FileObject xxx1 = u1fo.createData("xxx"); + FileObject xy1 = FileUtil.createData(u1fo, "x/y"); + FileObject x_1 = u1fo.createData("x "); + String cau = "\u010Dau"; + FileObject cau1 = u1fo.createData(cau); + FileObject folder = u1fo.createFolder("folder"); + FileObject foldr = u1fo.createFolder("foldr"); + FileObject xx2 = u2fo.createData("xx"); + FileObject xxx2 = u2fo.createData("xxx"); + FileObject xy2 = FileUtil.createData(u2fo, "x/y"); + FileObject x_2 = u2fo.createData("x "); + FileObject cau2 = u2fo.createData(cau); + assertEquals(Arrays.asList(u1fo, u2fo), Arrays.asList(cp.getRoots())); + assertTrue(cp.contains(xx1)); + assertTrue(cp.contains(x_1)); + assertFalse(cp.contains(xxx1)); + assertFalse(cp.contains(cau1)); + assertFalse(cp.contains(xy1)); + assertFalse(cp.contains(xx2)); + assertFalse(cp.contains(x_2)); + assertTrue(cp.contains(xxx2)); + assertTrue(cp.contains(cau2)); + assertTrue(cp.contains(xy2)); + assertFalse(cp.contains(folder)); + assertTrue(cp.contains(foldr)); + assertEquals(xx1, cp.findResource("xx")); + assertEquals(x_1, cp.findResource("x ")); + assertEquals(xxx2, cp.findResource("xxx")); + assertEquals(cau2, cp.findResource(cau)); + assertEquals(xy2, cp.findResource("x/y")); + assertEquals(null, cp.findResource("folder")); + assertEquals(foldr, cp.findResource("foldr")); + assertEquals(Collections.singletonList(xx1), cp.findAllResources("xx")); + assertEquals(Collections.singletonList(x_1), cp.findAllResources("x ")); + assertEquals(Collections.singletonList(xxx2), cp.findAllResources("xxx")); + assertEquals(Collections.singletonList(cau2), cp.findAllResources(cau)); + assertEquals(Collections.singletonList(xy2), cp.findAllResources("x/y")); + assertEquals(Collections.emptyList(), cp.findAllResources("folder")); + assertEquals(Collections.singletonList(foldr), cp.findAllResources("foldr")); + assertEquals("xx", cp.getResourceName(xx1)); + assertEquals("x ", cp.getResourceName(x_1)); + assertEquals("xxx", cp.getResourceName(xxx1)); + assertEquals(cau, cp.getResourceName(cau1)); + assertEquals("x/y", cp.getResourceName(xy1)); + assertEquals("folder", cp.getResourceName(folder)); + assertEquals("foldr", cp.getResourceName(foldr)); + assertEquals(u1fo, cp.findOwnerRoot(xx1)); + assertEquals(u1fo, cp.findOwnerRoot(x_1)); + assertEquals(u1fo, cp.findOwnerRoot(xxx1)); + assertEquals(u1fo, cp.findOwnerRoot(cau1)); + assertEquals(u1fo, cp.findOwnerRoot(xy1)); + assertEquals(u1fo, cp.findOwnerRoot(folder)); + assertEquals(u1fo, cp.findOwnerRoot(foldr)); + assertTrue(cp.isResourceVisible(xx1)); + assertTrue(cp.isResourceVisible(x_1)); + assertFalse(cp.isResourceVisible(xxx1)); + assertFalse(cp.isResourceVisible(cau1)); + assertFalse(cp.isResourceVisible(xy1)); + assertFalse(cp.isResourceVisible(folder)); + assertTrue(cp.isResourceVisible(foldr)); + ClassPath.Entry e1 = cp.entries().get(0); + assertTrue(e1.includes("xx")); + assertTrue(e1.includes("x ")); + assertFalse(e1.includes("xxx")); + assertFalse(e1.includes(cau)); + assertFalse(e1.includes("x/y")); + assertFalse(e1.includes("folder/")); + assertTrue(e1.includes("foldr/")); + assertTrue(e1.includes(xx1)); + assertTrue(e1.includes(x_1)); + assertFalse(e1.includes(xxx1)); + assertFalse(e1.includes(cau1)); + assertFalse(e1.includes(xy1)); + assertFalse(e1.includes(folder)); + assertTrue(e1.includes(foldr)); + try { + e1.includes(xx2); + fail(); + } catch (IllegalArgumentException iae) {} + assertTrue(e1.includes(xx1.getURL())); + assertTrue(e1.includes(x_1.getURL())); + assertFalse(e1.includes(xxx1.getURL())); + assertFalse(e1.includes(cau1.getURL())); + assertFalse(e1.includes(xy1.getURL())); + assertFalse(e1.includes(folder.getURL())); + assertTrue(e1.includes(foldr.getURL())); + try { + e1.includes(xx2.getURL()); + fail(); + } catch (IllegalArgumentException iae) {} + cp.addPropertyChangeListener(impl); + pr.changeIncludes(3); + impl.assertEvents(ClassPath.PROP_INCLUDES); + assertFalse(cp.contains(xx1)); + assertFalse(cp.contains(x_1)); + assertTrue(cp.contains(xxx1)); + assertTrue(cp.contains(cau1)); + assertTrue(cp.contains(xy1)); + assertTrue(cp.contains(xx2)); + assertTrue(cp.contains(x_2)); + assertFalse(cp.contains(xxx2)); + assertFalse(cp.contains(cau2)); + assertFalse(cp.contains(xy2)); + assertEquals(xx2, cp.findResource("xx")); + assertEquals(x_2, cp.findResource("x ")); + assertEquals(xxx1, cp.findResource("xxx")); + assertEquals(cau1, cp.findResource(cau)); + assertEquals(xy1, cp.findResource("x/y")); + e1 = cp.entries().get(0); + assertFalse(e1.includes("xx")); + assertFalse(e1.includes("x ")); + assertTrue(e1.includes("xxx")); + assertTrue(e1.includes(cau)); + assertTrue(e1.includes("x/y")); + assertFalse(e1.includes(xx1)); + assertFalse(e1.includes(x_1)); + assertTrue(e1.includes(xxx1)); + assertTrue(e1.includes(cau1)); + assertTrue(e1.includes(xy1)); + assertFalse(e1.includes(xx1.getURL())); + assertFalse(e1.includes(x_1.getURL())); + assertTrue(e1.includes(xxx1.getURL())); + assertTrue(e1.includes(cau1.getURL())); + assertTrue(e1.includes(xy1.getURL())); + } + + public void testFpriChangeFiring() throws Exception { + class FPRI implements FilteringPathResourceImplementation { + URL root; + PropertyChangeSupport pcs = new PropertyChangeSupport(this); + FPRI(URL root) { + this.root = root; + } + public boolean includes(URL root, String resource) { + return true; + } + public URL[] getRoots() { + return new URL[] {root}; + } + public ClassPathImplementation getContent() { + return null; + } + public void addPropertyChangeListener(PropertyChangeListener listener) { + pcs.addPropertyChangeListener(listener); + } + public void removePropertyChangeListener(PropertyChangeListener listener) { + pcs.removePropertyChangeListener(listener); + } + void fire(Object propid) { + PropertyChangeEvent e = new PropertyChangeEvent(this, FilteringPathResourceImplementation.PROP_INCLUDES, null, null); + e.setPropagationId(propid); + pcs.firePropertyChange(e); + } + } + FPRI fpri1 = new FPRI(new File(getWorkDir(), "src1").toURI().toURL()); + FPRI fpri2 = new FPRI(new File(getWorkDir(), "src2").toURI().toURL()); + class L implements PropertyChangeListener { + int cnt; + public void propertyChange(PropertyChangeEvent e) { + if (ClassPath.PROP_INCLUDES.equals(e.getPropertyName())) { + cnt++; + } + } + } + ClassPath cp = ClassPathSupport.createClassPath(Arrays.asList(fpri1, fpri2)); + L l = new L(); + cp.addPropertyChangeListener(l); + //No events fired before cp.entries() called + fpri1.fire(null); + assertEquals(0, l.cnt); + cp.entries(); + fpri1.fire(null); + assertEquals(1, l.cnt); + fpri2.fire(null); + assertEquals(2, l.cnt); + fpri1.fire("hello"); + assertEquals(3, l.cnt); + fpri2.fire("goodbye"); + assertEquals(4, l.cnt); + fpri1.fire("fixed"); + assertEquals(5, l.cnt); + fpri2.fire("fixed"); + assertEquals(5, l.cnt); + fpri1.fire("new"); + assertEquals(6, l.cnt); + } + + public void testLeakingClassPath() throws Exception { + ClassPath cp = ClassPathSupport.createClassPath(new URL("file:///a/"), new URL("file:///b/")); + ClassPath proxyCP = ClassPathSupport.createProxyClassPath(cp); + Reference proxy = new WeakReference(proxyCP); + + proxyCP.entries(); + + proxyCP = null; + + assertGC("the proxy classpath needs to GCable", proxy); + } + + public void testGetClassLoaderPerf () throws Exception { + final String bootPathProp = System.getProperty("sun.boot.class.path"); //NOI18N + List roots = new ArrayList (); + StringTokenizer tk = new StringTokenizer (bootPathProp,File.pathSeparator); + if (tk.hasMoreTokens()) { + final String path = tk.nextToken(); + final File f = FileUtil.normalizeFile(new File (path)); + if (f.canRead()) { + roots.add(f.toURI().toURL()); + } + } + final ClassLoader bootLoader = new URLClassLoader(roots.toArray(new URL[roots.size()]), null); + + final String classPathProp = System.getProperty("java.class.path"); //NOI18N + roots = new ArrayList (); + List roots2 = new ArrayList(); + tk = new StringTokenizer (classPathProp,File.pathSeparator); + while (tk.hasMoreTokens()) { + final String path = tk.nextToken(); + final File f = FileUtil.normalizeFile(new File (path)); + if (!f.canRead()) { + continue; + } + URL url = f.toURI().toURL(); + roots2.add(url); + if (FileUtil.isArchiveFile(url)) { + url = FileUtil.getArchiveRoot(url); + } + roots.add(url); + } + + final ClassPath cp = ClassPathSupport.createClassPath(roots.toArray(new URL[roots.size()])); +// final ClassLoader loader = ClassLoaderSupport.create(cp,bootLoader); +// final ClassLoader loader = new URLClassLoader(roots.toArray(new URL[roots.size()]),bootLoader); + final ClassLoader loader = new URLClassLoader(roots2.toArray(new URL[roots2.size()]),bootLoader); + + final Set classNames = getClassNames (cp); + int noLoaded = 0; + int noFailed = 0; + long st = System.currentTimeMillis(); + for (String className : classNames) { + try { + final Class c = loader.loadClass(className); + noLoaded++; + } catch (ClassNotFoundException e) { + noFailed++; + } + catch (NoClassDefFoundError e) { + noFailed++; + } + } + long et = System.currentTimeMillis(); + System.out.println("Loaded: " + noLoaded + " in: " + (et-st)+"ms"); + } + + private Set getClassNames (final ClassPath cp) { + Set classNames = new HashSet (); + for (FileObject root : cp.getRoots()) { + Enumeration fos = root.getChildren(true); + while (fos.hasMoreElements()) { + FileObject fo = fos.nextElement(); + if (isImportant (fo)) { + classNames.add(cp.getResourceName(fo, '.', false)); + } + } + } + return classNames; + } + + private boolean isImportant (final FileObject fo) { + if (fo.isFolder()) { + return false; + } + if (!"class".equals(fo.getExt())) { //NOI18N + return false; + } + return !fo.getName().contains("$"); //NOI18N + + } + + public void testJVMPathConversion() throws Exception { + String root = getWorkDir().toURI().toString(); + ClassPath cp = ClassPathSupport.createClassPath( + new URL(root + "folder/"), + new URL("jar:" + root + "file.zip!/"), + new URL("jar:" + root + "file.zip!/subdir/")); + assertEquals(massagePath("/folder:/file.zip"), cp.toString(ClassPath.PathConversionMode.SKIP)); + assertEquals(massagePath("/folder:/file.zip:") + "jar:" + root + "file.zip!/subdir/", cp.toString(ClassPath.PathConversionMode.PRINT)); + try { + cp.toString(ClassPath.PathConversionMode.FAIL); + fail(); + } catch (IllegalArgumentException x) {/* OK */} + CharSequence warnings = Log.enable(ClassPath.class.getName(), Level.WARNING); + assertEquals(massagePath("/folder:/file.zip"), cp.toString(ClassPath.PathConversionMode.WARN)); + assertTrue(warnings.toString(), warnings.toString().contains("subdir")); + + cp = ClassPathSupport.createClassPath( + new URL(root + "folder/"), + new URL("jar:" + root + "file.zip!/")); + assertEquals(cp.toString(), ClassPathSupport.createClassPath(cp.toString()).toString()); + // XXX could also test IAE (tricky - need to have a URLMapper in Lookup, etc.) + } + private String massagePath(String path) throws Exception { + return path.replace('/', File.separatorChar).replace(':', File.pathSeparatorChar).replace("", getWorkDir().getAbsolutePath()); + } + +} diff --git a/api.java.classpath/test/unit/src/org/netbeans/api/java/classpath/GlobalPathRegistryTest.java b/api.java.classpath/test/unit/src/org/netbeans/api/java/classpath/GlobalPathRegistryTest.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/test/unit/src/org/netbeans/api/java/classpath/GlobalPathRegistryTest.java @@ -0,0 +1,381 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ + +package org.netbeans.api.java.classpath; + +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.Map; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import org.netbeans.api.java.queries.SourceForBinaryQuery; +import org.netbeans.junit.MockServices; +import org.netbeans.junit.NbTestCase; +import org.netbeans.spi.java.classpath.support.ClassPathSupport; +import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation; +import org.openide.filesystems.FileObject; +import org.netbeans.spi.java.classpath.ClassPathFactory; +import org.netbeans.spi.java.classpath.ClassPathImplementation; +import org.netbeans.spi.java.classpath.FilteringPathResourceImplementation; +import org.netbeans.spi.java.classpath.support.PathResourceBase; +import org.openide.filesystems.FileStateInvalidException; +import org.openide.filesystems.FileUtil; +import org.openide.util.ChangeSupport; +import org.openide.util.Lookup; + +/** + * Test functionality of GlobalPathRegistry. + * @author Jesse Glick + */ +public class GlobalPathRegistryTest extends NbTestCase { + + public GlobalPathRegistryTest(String name) { + super(name); + MockServices.setServices(SFBQImpl.class, DeadLockSFBQImpl.class); + } + + private GlobalPathRegistry r; + private FileObject root; + private ClassPath cp1, cp2, cp3, cp4, cp5; + protected void setUp() throws Exception { + super.setUp(); + r = GlobalPathRegistry.getDefault(); + r.clear(); + clearWorkDir(); + root = FileUtil.toFileObject(getWorkDir()); + cp1 = ClassPathSupport.createClassPath(new FileObject[] {root.createFolder("1")}); + cp2 = ClassPathSupport.createClassPath(new FileObject[] {root.createFolder("2")}); + cp3 = ClassPathSupport.createClassPath(new FileObject[] {root.createFolder("3")}); + cp4 = ClassPathSupport.createClassPath(new FileObject[] {root.createFolder("4")}); + cp5 = ClassPathSupport.createClassPath(new FileObject[] {root.createFolder("5")}); + } + + public void testBasicOperation() throws Exception { + assertEquals("initially no paths of type a", Collections.emptySet(), r.getPaths("a")); + r.register("a", new ClassPath[] {cp1, cp2}); + assertEquals("added some paths of type a", new HashSet(Arrays.asList(new ClassPath[] {cp1, cp2})), r.getPaths("a")); + r.register("a", new ClassPath[0]); + assertEquals("did not add any new paths to a", new HashSet(Arrays.asList(new ClassPath[] {cp1, cp2})), r.getPaths("a")); + assertEquals("initially no paths of type b", Collections.emptySet(), r.getPaths("b")); + r.register("b", new ClassPath[] {cp3, cp4, cp5}); + assertEquals("added some paths of type b", new HashSet(Arrays.asList(new ClassPath[] {cp3, cp4, cp5})), r.getPaths("b")); + r.unregister("a", new ClassPath[] {cp1}); + assertEquals("only one path left of type a", Collections.singleton(cp2), r.getPaths("a")); + r.register("a", new ClassPath[] {cp2, cp3}); + assertEquals("only one new path added of type a", new HashSet(Arrays.asList(new ClassPath[] {cp2, cp3})), r.getPaths("a")); + r.unregister("a", new ClassPath[] {cp2}); + assertEquals("still have extra cp2 in a", new HashSet(Arrays.asList(new ClassPath[] {cp2, cp3})), r.getPaths("a")); + r.unregister("a", new ClassPath[] {cp2}); + assertEquals("last cp2 removed from a", Collections.singleton(cp3), r.getPaths("a")); + r.unregister("a", new ClassPath[] {cp3}); + assertEquals("a now empty", Collections.emptySet(), r.getPaths("a")); + r.unregister("a", new ClassPath[0]); + assertEquals("a still empty", Collections.emptySet(), r.getPaths("a")); + try { + r.unregister("a", new ClassPath[] {cp3}); + fail("should not have been permitted to unregister a nonexistent entry"); + } catch (IllegalArgumentException x) { + // Good. + } + } + + public void testListening() throws Exception { + assertEquals("initially no paths of type b", Collections.emptySet(), r.getPaths("b")); + L l = new L(); + r.addGlobalPathRegistryListener(l); + r.register("b", new ClassPath[] {cp1, cp2}); + GlobalPathRegistryEvent e = l.event(); + assertNotNull("got an event", e); + assertTrue("was an addition", l.added()); + assertEquals("right registry", r, e.getRegistry()); + assertEquals("right ID", "b", e.getId()); + assertEquals("right changed paths", new HashSet(Arrays.asList(new ClassPath[] {cp1, cp2})), e.getChangedPaths()); + r.register("b", new ClassPath[] {cp2, cp3}); + e = l.event(); + assertNotNull("got an event", e); + assertTrue("was an addition", l.added()); + assertEquals("right changed paths", Collections.singleton(cp3), e.getChangedPaths()); + r.register("b", new ClassPath[] {cp3}); + e = l.event(); + assertNull("no event for adding a dupe", e); + r.unregister("b", new ClassPath[] {cp1, cp3, cp3}); + e = l.event(); + assertNotNull("got an event", e); + assertFalse("was a removal", l.added()); + assertEquals("right changed paths", new HashSet(Arrays.asList(new ClassPath[] {cp1, cp3})), e.getChangedPaths()); + r.unregister("b", new ClassPath[] {cp2}); + e = l.event(); + assertNull("no event for removing an extra", e); + r.unregister("b", new ClassPath[] {cp2}); + e = l.event(); + assertNotNull("now an event for removing the last copy", e); + assertFalse("was a removal", l.added()); + assertEquals("right changed paths", Collections.singleton(cp2), e.getChangedPaths()); + } + + + public void testGetSourceRoots () throws Exception { + SFBQImpl query = Lookup.getDefault().lookup(SFBQImpl.class); + assertNotNull ("SourceForBinaryQueryImplementation not found in lookup",query); + query.addPair(cp3.getRoots()[0].getURL(),new FileObject[0]); + ClassPathTest.TestClassPathImplementation cpChangingImpl = new ClassPathTest.TestClassPathImplementation(); + ClassPath cpChanging = ClassPathFactory.createClassPath(cpChangingImpl); + assertEquals("cpChangingImpl is empty", 0, cpChanging.getRoots().length); + r.register(ClassPath.SOURCE, new ClassPath[] {cp1, cp2, cpChanging}); + r.register (ClassPath.COMPILE, new ClassPath[] {cp3}); + Set result = r.getSourceRoots(); + assertEquals ("Wrong number of source roots",result.size(),cp1.getRoots().length + cp2.getRoots().length); + assertTrue ("Missing roots from cp1",result.containsAll (Arrays.asList(cp1.getRoots()))); + assertTrue ("Missing roots from cp2",result.containsAll (Arrays.asList(cp2.getRoots()))); + // simulate classpath change: + URL u = cp5.entries().get(0).getURL(); + cpChangingImpl.addResource(u); + assertEquals("cpChangingImpl is not empty", 1, cpChanging.getRoots().length); + result = r.getSourceRoots(); + assertEquals ("Wrong number of source roots",result.size(),cp1.getRoots().length + cp2.getRoots().length + cpChanging.getRoots().length); + assertTrue ("Missing roots from cp1",result.containsAll (Arrays.asList(cp1.getRoots()))); + assertTrue ("Missing roots from cp2",result.containsAll (Arrays.asList(cp2.getRoots()))); + cpChangingImpl.removeResource(u); + + query.addPair(cp3.getRoots()[0].getURL(),cp4.getRoots()); + result = r.getSourceRoots(); + assertEquals ("Wrong number of source roots",result.size(),cp1.getRoots().length + cp2.getRoots().length+cp4.getRoots().length); + assertTrue ("Missing roots from cp1",result.containsAll (Arrays.asList(cp1.getRoots()))); + assertTrue ("Missing roots from cp2",result.containsAll (Arrays.asList(cp2.getRoots()))); + assertTrue ("Missing roots from cp4",result.containsAll (Arrays.asList(cp4.getRoots()))); + } + + /** + * Tests issue: #60976:Deadlock between JavaFastOpen$Evaluator and AntProjectHelper$something + */ + public void testGetSourceRootsDeadLock () throws Exception { + DeadLockSFBQImpl query = Lookup.getDefault().lookup(DeadLockSFBQImpl.class); + assertNotNull ("SourceForBinaryQueryImplementation not found in lookup",query); + r.register (ClassPath.COMPILE, new ClassPath[] {cp1}); + try { + query.setSynchronizedJob ( + new Runnable () { + public void run () { + r.register(ClassPath.COMPILE, new ClassPath[] {cp2}); + } + } + ); + r.getSourceRoots(); + } finally { + query.setSynchronizedJob (null); + } + } + + public void testFindResource() throws Exception { + final FileObject src1 = root.createFolder("src1"); + FileObject src1included = FileUtil.createData(src1, "included/file"); + FileUtil.createData(src1, "excluded/file1"); + FileUtil.createData(src1, "excluded/file2"); + FileObject src2 = root.createFolder("src2"); + FileObject src2included = FileUtil.createData(src2, "included/file"); + FileObject src2excluded1 = FileUtil.createData(src2, "excluded/file1"); + class PRI extends PathResourceBase implements FilteringPathResourceImplementation { + public URL[] getRoots() { + try { + return new URL[] {src1.getURL()}; + } catch (FileStateInvalidException x) { + throw new AssertionError(x); + } + } + public boolean includes(URL root, String resource) { + return resource.startsWith("incl"); + } + public ClassPathImplementation getContent() { + return null; + } + } + r.register(ClassPath.SOURCE, new ClassPath[] { + ClassPathSupport.createClassPath(Collections.singletonList(new PRI())), + ClassPathSupport.createClassPath(new FileObject[] {src2}) + }); + assertTrue(Arrays.asList(src1included, src2included).contains(r.findResource("included/file"))); + assertEquals(src2excluded1, r.findResource("excluded/file1")); + assertEquals(null, r.findResource("excluded/file2")); + assertEquals(null, r.findResource("nonexistent")); + } + + public void testMemoryLeak124055 () throws Exception { + final GlobalPathRegistry reg = GlobalPathRegistry.getDefault(); + final Set src = reg.getPaths(ClassPath.SOURCE); + final Set boot = reg.getPaths(ClassPath.BOOT); + final Set compile = reg.getPaths(ClassPath.COMPILE); + assertTrue(src.isEmpty()); + assertTrue(boot.isEmpty()); + assertTrue(compile.isEmpty()); + assertTrue(reg.getSourceRoots().isEmpty()); + r.register(ClassPath.COMPILE, new ClassPath[] {cp3}); + SFBQImpl query = Lookup.getDefault().lookup(SFBQImpl.class); + query.addPair(cp3.getRoots()[0].getURL(),cp4.getRoots()); + //There should be one translated source root + assertEquals(1, reg.getSourceRoots().size()); + assertEquals(1, reg.getResults().size()); + r.unregister(ClassPath.COMPILE, new ClassPath[] {cp3}); + //There shouldn't be registered source root + assertTrue(reg.getSourceRoots().isEmpty()); + assertTrue(reg.getResults().isEmpty()); + } + + private static final class L implements GlobalPathRegistryListener { + + private GlobalPathRegistryEvent e; + private boolean added; + + public L() {} + + public synchronized GlobalPathRegistryEvent event() { + GlobalPathRegistryEvent _e = e; + e = null; + return _e; + } + + public boolean added() { + return added; + } + + public synchronized void pathsAdded(GlobalPathRegistryEvent e) { + assertNull("checked for last event", this.e); + this.e = e; + added = true; + } + + public synchronized void pathsRemoved(GlobalPathRegistryEvent e) { + assertNull("checked for last event", this.e); + this.e = e; + added = false; + } + + } + + + public static class SFBQImpl implements SourceForBinaryQueryImplementation { + + private Map pairs = new HashMap (); + + void addPair (URL binaryRoot, FileObject[] sourceRoots) { + assert binaryRoot != null && sourceRoots != null; + Result r = (Result) this.pairs.get (binaryRoot); + if (r == null) { + r = new Result (sourceRoots); + this.pairs.put (binaryRoot, r); + } + else { + r.setSources(sourceRoots); + } + } + + public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) { + Result result = (Result) this.pairs.get (binaryRoot); + return result; + } + + + private static class Result implements SourceForBinaryQuery.Result { + + private FileObject[] sources; + private final ChangeSupport changeSupport = new ChangeSupport(this); + + public Result (FileObject[] sources) { + this.sources = sources; + } + + + void setSources (FileObject[] sources) { + this.sources = sources; + this.changeSupport.fireChange (); + } + + public void addChangeListener(javax.swing.event.ChangeListener l) { + changeSupport.addChangeListener (l); + } + + public FileObject[] getRoots() { + return this.sources; + } + + public void removeChangeListener(javax.swing.event.ChangeListener l) { + changeSupport.removeChangeListener (l); + } + + } + + } + + public static class DeadLockSFBQImpl extends Thread implements SourceForBinaryQueryImplementation { + + private Runnable r; + + public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) { + if (this.r != null) { + synchronized (this) { + this.start(); + try { + this.wait (); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + } + return null; + } + + public synchronized void run () { + r.run(); + this.notify(); + } + + public void setSynchronizedJob (Runnable r) { + this.r = r; + } + + } + +} diff --git a/api.java/test/unit/src/org/netbeans/api/java/queries/BinaryForSourceQueryTest.java b/api.java.classpath/test/unit/src/org/netbeans/api/java/queries/BinaryForSourceQueryTest.java rename from api.java/test/unit/src/org/netbeans/api/java/queries/BinaryForSourceQueryTest.java rename to api.java.classpath/test/unit/src/org/netbeans/api/java/queries/BinaryForSourceQueryTest.java diff --git a/api.java/test/unit/src/org/netbeans/api/java/queries/SourceForBinaryQueryTest.java b/api.java.classpath/test/unit/src/org/netbeans/api/java/queries/SourceForBinaryQueryTest.java rename from api.java/test/unit/src/org/netbeans/api/java/queries/SourceForBinaryQueryTest.java rename to api.java.classpath/test/unit/src/org/netbeans/api/java/queries/SourceForBinaryQueryTest.java diff --git a/api.java.classpath/test/unit/src/org/netbeans/modules/java/classpath/ProxyClassPathImplementationTest.java b/api.java.classpath/test/unit/src/org/netbeans/modules/java/classpath/ProxyClassPathImplementationTest.java new file mode 100644 --- /dev/null +++ b/api.java.classpath/test/unit/src/org/netbeans/modules/java/classpath/ProxyClassPathImplementationTest.java @@ -0,0 +1,138 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.modules.java.classpath; + + +import java.net.URL; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.locks.ReentrantLock; +import junit.framework.TestCase; +import junit.framework.*; +import org.netbeans.api.java.classpath.ClassPath; +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.PathResourceImplementation; +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Collections; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeEvent; +import org.netbeans.spi.java.classpath.support.ClassPathSupport; +import org.openide.util.WeakListeners; + +/** + * + * @author tom + */ +public class ProxyClassPathImplementationTest extends NbTestCase { + + public ProxyClassPathImplementationTest(String testName) { + super(testName); + } + + public void testResources () throws Exception { + final URL url1 = new URL ("file:///tmp/a/"); + final URL url2 = new URL ("file:///tmp/b/"); + final URL url3 = new URL ("file:///tmp/b/"); + + final ClassPath cp1 = ClassPathSupport.createClassPath(new URL[] {url1, url2}); + final ClassPath cp2 = ClassPathSupport.createClassPath(new URL[] {url3}); + final ClassPath prxCp = ClassPathSupport.createProxyClassPath(new ClassPath[] {cp1,cp2}); + List entries = prxCp.entries(); + assertEquals(3,entries.size()); + assertEquals(url1,entries.get(0).getURL()); + assertEquals(url2,entries.get(1).getURL()); + assertEquals(url3,entries.get(2).getURL()); + } + + public void testDeadLock() throws Exception{ + List resources = Collections.emptyList(); + final ReentrantLock lock = new ReentrantLock (false); + final CountDownLatch signal = new CountDownLatch (1); + final ClassPath cp = ClassPathFactory.createClassPath(ClassPathSupport.createProxyClassPathImplementation(new ClassPathImplementation[] {new LockClassPathImplementation (resources,lock, signal)})); + lock.lock(); + final ExecutorService es = Executors.newSingleThreadExecutor(); + try { + es.submit(new Runnable () { + public void run () { + cp.entries(); + } + }); + signal.await(); + cp.entries(); + } finally { + es.shutdownNow(); + } + } + + + private class LockClassPathImplementation implements ClassPathImplementation { + + private List resources; + private ReentrantLock lock; + private CountDownLatch signal; + + public LockClassPathImplementation (final List resources, final ReentrantLock lock, final CountDownLatch signal) { + this.resources = resources; + this.lock = lock; + this.signal = signal; + } + + public List getResources() { + this.signal.countDown(); + this.lock.lock(); + return this.resources; + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + } + + } + + +} diff --git a/api.java/apichanges.xml b/api.java/apichanges.xml --- a/api.java/apichanges.xml +++ b/api.java/apichanges.xml @@ -93,7 +93,22 @@ - + + + Splitting the java API to independent ClassPath API and the rest of the java API + + + + + +

+ The copy of the ClassPath API was used by generic scripting framework, which cannot depend on the java cluster. + To remove this copy of the ClassPath API the java API needs to be splitted into the ClassPath API (IDE cluster) + and the rest of the java API (java cluster). +

+
+ +
Support for delegating SourceForBinaryQueryImplementation2 diff --git a/api.java/arch.xml b/api.java/arch.xml --- a/api.java/arch.xml +++ b/api.java/arch.xml @@ -127,10 +127,8 @@

The API is widely used by all sorts of IDE modules which need to work with - Java sources. They can obtain the classpath or boot classpath for a file (if - there is one), find out where its source root is, find sources corresponding - to bytecode class files, find all sources or classpaths corresponding to open - projects, find Javadoc, etc. The SPI is intended mainly for Java platform and + Java sources. They can find Javadoc, unit tests, source level, etc. + The SPI is intended mainly for Java platform and library providers, and project type providers, to declare all of this information.

@@ -150,8 +148,8 @@ -->

- Models basic aspects of the metadata surrounding Java source files, such as - the classpath. More information in the Javadoc. + Provides java specific queries (javadc, source level) used by other modules like java language infrastructure. + More information in the Javadoc.

@@ -259,15 +257,7 @@ For many purposes.

- -
  • - -

    - NbClassLoader is used by - ClassPath.getClassLoader(...). -

    -
    -
  • + @@ -409,9 +399,7 @@ -->

    - There is support for getting a class loader corresponding to a given - classpath, useful e.g. for loading user JavaBeans to introspect. This is not - used within the module itself. + No.

    @@ -783,14 +771,7 @@ Queries perform linearly in number of implementations, but as usual there will typically be only one or two implementations, e.g. delegating to owner projects. -

    -

    - Currently ClassPaths keep global file change listeners to permit - roots to be invalidated, and this makes file change events linear in the - number of ClassPath objects. This area is being studied and will - hopefully be optimized, perhaps reducing overhead to a small constant. - May require explicit support from the Filesystems API to fully optimize. -

    +

    @@ -935,9 +916,7 @@ --> -

    - ClassPath.getClassLoader(...) is granted all permissions. -

    + No.
    diff --git a/api.java/manifest.mf b/api.java/manifest.mf --- a/api.java/manifest.mf +++ b/api.java/manifest.mf @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.api.java/1 -OpenIDE-Module-Specification-Version: 1.17 -OpenIDE-Module-Localizing-Bundle: org/netbeans/api/java/classpath/Bundle.properties +OpenIDE-Module-Specification-Version: 1.18 +OpenIDE-Module-Localizing-Bundle: org/netbeans/api/java/queries/Bundle.properties AutoUpdate-Show-In-Client: false diff --git a/api.java/module-auto-deps.xml b/api.java/module-auto-deps.xml new file mode 100644 --- /dev/null +++ b/api.java/module-auto-deps.xml @@ -0,0 +1,61 @@ + + + + + + + + + Splitting the api.java to api.java.classpath and api.java + + + + + + + + + + + + diff --git a/api.java/nbproject/project.xml b/api.java/nbproject/project.xml --- a/api.java/nbproject/project.xml +++ b/api.java/nbproject/project.xml @@ -47,11 +47,12 @@ org.netbeans.api.java - org.openide.execution + org.netbeans.api.java.classpath - 1.2 + 1 + 1.0 @@ -61,12 +62,6 @@ 7.8 - - - org.openide.io - - - org.openide.util diff --git a/api.java/src/org/netbeans/api/java/classpath/Bundle.properties b/api.java/src/org/netbeans/api/java/queries/Bundle.properties copy from api.java/src/org/netbeans/api/java/classpath/Bundle.properties copy to api.java/src/org/netbeans/api/java/queries/Bundle.properties diff --git a/api.java/src/org/netbeans/modules/java/classpath/ClassPathAccessor.java b/api.java/src/org/netbeans/modules/java/classpath/ClassPathAccessor.java deleted file mode 100644 --- a/api.java/src/org/netbeans/modules/java/classpath/ClassPathAccessor.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ -package org.netbeans.modules.java.classpath; - -import org.netbeans.api.java.classpath.ClassPath; -import org.netbeans.spi.java.classpath.ClassPathImplementation; - - -public abstract class ClassPathAccessor { - - public static ClassPathAccessor DEFAULT; - - // force loading of ClassPath class. That will set DEFAULT variable. - static { - Class c = ClassPath.class; - try { - Class.forName(c.getName(), true, c.getClassLoader()); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - public abstract ClassPath createClassPath(ClassPathImplementation spiClasspath); - - public abstract ClassPathImplementation getClassPathImpl (ClassPath cp); - -} diff --git a/api.java/src/org/netbeans/modules/java/classpath/ProxyClassPathImplementation.java b/api.java/src/org/netbeans/modules/java/classpath/ProxyClassPathImplementation.java deleted file mode 100644 --- a/api.java/src/org/netbeans/modules/java/classpath/ProxyClassPathImplementation.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ -package org.netbeans.modules.java.classpath; - -import org.netbeans.spi.java.classpath.ClassPathImplementation; -import org.netbeans.spi.java.classpath.PathResourceImplementation; - -import java.util.List; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Collections; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeEvent; -import org.openide.util.WeakListeners; - -/** ProxyClassPathImplementation provides read only proxy for ClassPathImplementations. - * The order of the resources is given by the order of its delegates. - * The proxy is designed to be used as a union of class paths. - * E.g. to be able to easily iterate or listen on all design resources = sources + compile resources - */ -public class ProxyClassPathImplementation implements ClassPathImplementation { - - private ClassPathImplementation[] classPaths; - private List resourcesCache; - private ArrayList listeners; - private PropertyChangeListener classPathsListener; - - public ProxyClassPathImplementation (ClassPathImplementation[] classPaths) { - if (classPaths == null) - throw new IllegalArgumentException (); - List impls = new ArrayList (); - classPathsListener = new DelegatesListener (); - for (ClassPathImplementation cpImpl : classPaths) { - if (cpImpl == null) - continue; - cpImpl.addPropertyChangeListener (WeakListeners.propertyChange(classPathsListener,cpImpl)); - impls.add (cpImpl); - } - this.classPaths = impls.toArray(new ClassPathImplementation[impls.size()]); - } - - - - public List getResources() { - synchronized (this) { - if (this.resourcesCache != null) { - return this.resourcesCache; - } - } - - ArrayList result = new ArrayList (classPaths.length*10); - for (ClassPathImplementation cpImpl : classPaths) { - List subPath = cpImpl.getResources(); - assert subPath != null : "ClassPathImplementation.getResources() returned null. ClassPathImplementation.class: " - + cpImpl.getClass().toString() + " ClassPathImplementation: " + cpImpl.toString(); - result.addAll (subPath); - } - - synchronized (this) { - if (this.resourcesCache == null) { - resourcesCache = Collections.unmodifiableList (result); - } - return this.resourcesCache; - } - } - - public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { - if (this.listeners == null) - this.listeners = new ArrayList (); - this.listeners.add (listener); - } - - public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { - if (this.listeners == null) - return; - this.listeners.remove (listener); - } - - public String toString () { - StringBuilder builder = new StringBuilder("["); //NOI18N - for (ClassPathImplementation cpImpl : this.classPaths) { - builder.append (cpImpl.toString()); - builder.append(", "); //NOI18N - } - builder.append ("]"); //NOI18N - return builder.toString (); - } - - - private class DelegatesListener implements PropertyChangeListener { - - public void propertyChange(PropertyChangeEvent evt) { - PropertyChangeListener[] _listeners; - synchronized (ProxyClassPathImplementation.this) { - ProxyClassPathImplementation.this.resourcesCache = null; //Clean the cache - if (ProxyClassPathImplementation.this.listeners == null) - return; - _listeners = ProxyClassPathImplementation.this.listeners.toArray(new PropertyChangeListener[ProxyClassPathImplementation.this.listeners.size()]); - } - PropertyChangeEvent event = new PropertyChangeEvent (ProxyClassPathImplementation.this, evt.getPropertyName(),null,null); - for (PropertyChangeListener l : _listeners) { - l.propertyChange (event); - } - } - } - -} diff --git a/api.java/src/org/netbeans/modules/java/classpath/SimpleClassPathImplementation.java b/api.java/src/org/netbeans/modules/java/classpath/SimpleClassPathImplementation.java deleted file mode 100644 --- a/api.java/src/org/netbeans/modules/java/classpath/SimpleClassPathImplementation.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ -package org.netbeans.modules.java.classpath; - -import java.util.List; -import java.beans.PropertyChangeListener; -import java.net.URL; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; - -import org.netbeans.spi.java.classpath.ClassPathImplementation; -import org.netbeans.spi.java.classpath.PathResourceImplementation; - - -public class SimpleClassPathImplementation implements ClassPathImplementation { - - List entries; - - public SimpleClassPathImplementation() { - this(new ArrayList()); - } - - public SimpleClassPathImplementation(List entries) { - this.entries = entries; - } - - public List getResources() { - return Collections.unmodifiableList(entries); - } - - public void addPropertyChangeListener(PropertyChangeListener listener) { - // XXX TBD - } - - public void removePropertyChangeListener(PropertyChangeListener listener) { - // XXX TBD - } - - public String toString () { - StringBuilder builder = new StringBuilder ("SimpleClassPathImplementation["); //NOI18N - for (PathResourceImplementation impl : this.entries) { - URL[] roots = impl.getRoots(); - for (URL root : roots) { - builder.append (root.toExternalForm()); - builder.append (", "); //NOI18N - } - } - builder.append ("]"); //NOI18N - return builder.toString (); - } -} diff --git a/api.java/src/org/netbeans/modules/java/classpath/SimplePathResourceImplementation.java b/api.java/src/org/netbeans/modules/java/classpath/SimplePathResourceImplementation.java deleted file mode 100644 --- a/api.java/src/org/netbeans/modules/java/classpath/SimplePathResourceImplementation.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ -package org.netbeans.modules.java.classpath; - - -import org.netbeans.spi.java.classpath.support.PathResourceBase; -import org.netbeans.spi.java.classpath.ClassPathImplementation; - -import java.net.URL; - - -/** - * Provides implementation of the single rooted PathResoruceImplementation - */ - -public final class SimplePathResourceImplementation extends PathResourceBase { - - private URL[] url; - - - - public SimplePathResourceImplementation (URL root) { - if (root == null) - throw new IllegalArgumentException (); - this.url = new URL[] {root}; - } - - - public URL[] getRoots() { - return this.url; - } - - public ClassPathImplementation getContent() { - return null; - } - - public String toString () { - return "SimplePathResource{"+this.getRoots()[0]+"}"; //NOI18N - } - - public int hashCode () { - return this.url[0].hashCode(); - } - - public boolean equals (Object other) { - if (other instanceof SimplePathResourceImplementation) { - SimplePathResourceImplementation opr = (SimplePathResourceImplementation) other; - return this.url[0].equals (opr.url[0]); - } - else - return false; - } -} diff --git a/api.java/src/org/netbeans/modules/java/queries/SFBQImpl2Result.java b/api.java/src/org/netbeans/modules/java/queries/SFBQImpl2Result.java deleted file mode 100644 --- a/api.java/src/org/netbeans/modules/java/queries/SFBQImpl2Result.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - * - * Contributor(s): - * - * Portions Copyrighted 2008 Sun Microsystems, Inc. - */ - -package org.netbeans.modules.java.queries; - -import javax.swing.event.ChangeListener; -import org.netbeans.api.java.queries.SourceForBinaryQuery; -import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2; -import org.openide.filesystems.FileObject; -import org.openide.filesystems.FileUtil; - -/** - * - * @author Tomas Zezula - */ -public class SFBQImpl2Result implements SourceForBinaryQueryImplementation2.Result { - - private final SourceForBinaryQuery.Result delegate; - - public SFBQImpl2Result (final SourceForBinaryQuery.Result result) { - assert result != null; - this.delegate = result; - } - - public boolean preferSources() { - //Preserve the old behavior from 4.0 to 6.1, ignore sources inside archives - final FileObject[] roots = this.delegate.getRoots(); - for (FileObject root : roots) { - if (FileUtil.getArchiveFile(root) != null) { - return false; - } - } - return true; - } - - public FileObject[] getRoots () { - return this.delegate.getRoots(); - } - - public void addChangeListener(ChangeListener l) { - this.delegate.addChangeListener(l); - } - - public void removeChangeListener(ChangeListener l) { - this.delegate.removeChangeListener(l); - } -} diff --git a/api.java/src/org/netbeans/spi/java/classpath/ClassPathFactory.java b/api.java/src/org/netbeans/spi/java/classpath/ClassPathFactory.java deleted file mode 100644 --- a/api.java/src/org/netbeans/spi/java/classpath/ClassPathFactory.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ - -package org.netbeans.spi.java.classpath; - -import java.net.URL; -import org.netbeans.api.java.classpath.ClassPath; -import org.netbeans.modules.java.classpath.ClassPathAccessor; -import org.openide.filesystems.FileUtil; - -/** - * Most general way to create {@link ClassPath} instances. - * You are not permitted to create them directly; instead you implement - * {@link ClassPathImplementation} and use this factory. - * See also {@link org.netbeans.spi.java.classpath.support.ClassPathSupport} - * for easier ways to create classpaths. - * @since org.netbeans.api.java/1 1.4 - */ -public final class ClassPathFactory { - - private ClassPathFactory() { - } - - /** - * Create API classpath instance for the given SPI classpath. - * @param spiClasspath instance of SPI classpath - * @return instance of API classpath - */ - public static ClassPath createClassPath(ClassPathImplementation spiClasspath) { -// assert checkEntries (spiClasspath) : "ClassPathImplementation contains invalid root: " + spiClasspath.toString(); //Commented, not to decrease the performance even in the dev build. - return ClassPathAccessor.DEFAULT.createClassPath(spiClasspath); - } - - - private static boolean checkEntries (ClassPathImplementation spiClasspath) { - for (PathResourceImplementation impl : spiClasspath.getResources()) { - URL[] roots = impl.getRoots(); - for (URL root : roots) { - if (FileUtil.isArchiveFile(root)) { - return false; - } - if (root.toExternalForm().endsWith("/")) { // NOI18N - return false; - } - } - } - return true; - } - -} diff --git a/api.java/src/org/netbeans/spi/java/classpath/ClassPathImplementation.java b/api.java/src/org/netbeans/spi/java/classpath/ClassPathImplementation.java deleted file mode 100644 --- a/api.java/src/org/netbeans/spi/java/classpath/ClassPathImplementation.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ -package org.netbeans.spi.java.classpath; - -import java.util.List; -import java.beans.PropertyChangeListener; - -/** - * SPI interface for ClassPath. - * @see ClassPathFactory - * @since org.netbeans.api.java/1 1.4 - */ -public interface ClassPathImplementation { - - public static final String PROP_RESOURCES = "resources"; //NOI18N - - /** - * Returns list of entries, the list is unmodifiable. - * @return List of PathResourceImplementation, never returns null - * it may return an empty List - */ - public List getResources(); - - /** - * Adds property change listener. - * The listener is notified when the set of entries has changed. - * @param listener - */ - public void addPropertyChangeListener(PropertyChangeListener listener); - - /** - * Removes property change listener - * @param listener - */ - public void removePropertyChangeListener(PropertyChangeListener listener); -} diff --git a/api.java/src/org/netbeans/spi/java/classpath/ClassPathProvider.java b/api.java/src/org/netbeans/spi/java/classpath/ClassPathProvider.java deleted file mode 100644 --- a/api.java/src/org/netbeans/spi/java/classpath/ClassPathProvider.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ - -package org.netbeans.spi.java.classpath; - -import org.netbeans.api.java.classpath.ClassPath; -import org.openide.filesystems.FileObject; - -/** - * Provider interface for Java classpaths. - *

    - * The org.netbeans.modules.java.project module registers an - * implementation of this interface to global lookup which looks for the - * project which owns a file (if any) and checks its lookup for this interface, - * and if it finds an instance, delegates to it. Therefore it is not normally - * necessary for a project type provider to register its own instance just to - * define the classpaths for files it owns, assuming it depends on the Java - * Project module. - *

    - *
    - *

    - * Note that to make editor code completion functionality work for a Java source file the - * following classpaths must be available for it: - *

    - *
      - *
    1. The {@link ClassPath#BOOT} type of classpath - * is required or the source file will not be parsable and - * code completion will be disabled. See also - * {@link org.netbeans.spi.java.queries.SourceLevelQueryImplementation}.
    2. - *
    3. The {@link ClassPath#SOURCE} type of classpath - * is required or code completion will be disabled. - * Providing this classpath will enable code completion, but only elements - * defined on this classpath will be offered if the compile classpath is missing.
    4. - *
    5. The {@link ClassPath#COMPILE} type of classpath - * is recommended to be provide to make code completion work fully - * by suggesting all classes against which the source is developed.
    6. - *
    - *

    {@link ClassPath#EXECUTE} is also recommended for e.g. I18N functionality to work. - * This should contain the full run-time classpath of the class, including its build - * location (bytecode).

    - *

    You should return these classpaths for the package root folder and any - * files or folders inside it.

    - *

    You should register classpaths for source files of all these types in - * {@link org.netbeans.api.java.classpath.GlobalPathRegistry} - * when they are to be exposed in the GUI as available for use (e.g. for the editor's Fast Open dialog), - * and unregister them when they are no longer to be exposed. Typically this is done as part of - * ProjectOpenedHook. - *

    It is also desirable to produce classpath information for compiled class files - * (bytecode), including their package roots (whether a disk folder or a JAR root). - * This will enable parsing of the class files, which is sometimes needed (e.g. for - * expanding the class file node and seeing its members). - * Compiled classes should have:

    - *
      - *
    1. {@link ClassPath#BOOT} corresponding to the Java platform to be used with the classes.
    2. - *
    3. {@link ClassPath#EXECUTE} containing the bytecode's package root itself, plus any other - * libraries it needs to resolve against. Should normally be the same as the execute classpath - * of the corresponding source files.
    4. - *
    - *

    If no specific class path providers are available for a given source file or bytecode file, - * i.e. null is returned from all providers, there may be a fallback implementation - * which would provide reasonable defaults. For source files, this could mean a boot classpath - * corresponding to the default Java platform (i.e. the JDK being used to run the IDE); empty - * compile and execute classpaths; and a sourcepath computed based on the package statement in the - * source file (if this is possible). For class files, this could mean a boot classpath determined - * as for source files, and an execute classpath containing the package root apparently owning the - * class file (computed according to the class file's package information, if this is possible).

    - *
    - * @see ClassPath#getClassPath - * @see org.netbeans.api.java.classpath.GlobalPathRegistry - * @author Jesse Glick - * @since org.netbeans.api.java/1 1.4 - */ -public interface ClassPathProvider { - - /** - * Find some kind of a classpath for a given file. - * @param file a file somewhere, or a source root - * @param type a classpath type such as {@link ClassPath#COMPILE} - * @return an appropriate classpath, or null for no answer - * @see ClassPathFactory - * @see org.netbeans.spi.java.classpath.support.ClassPathSupport - */ - ClassPath findClassPath(FileObject file, String type); - -} diff --git a/api.java/src/org/netbeans/spi/java/classpath/FilteringPathResourceImplementation.java b/api.java/src/org/netbeans/spi/java/classpath/FilteringPathResourceImplementation.java deleted file mode 100644 --- a/api.java/src/org/netbeans/spi/java/classpath/FilteringPathResourceImplementation.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ - -package org.netbeans.spi.java.classpath; - -import java.net.URL; - -/** - * SPI interface for a classpath entry which can include or exclude particular files. - * @author Jesse Glick - * @see "issue #49026" - * @since org.netbeans.api.java/1 1.13 - */ -public interface FilteringPathResourceImplementation extends PathResourceImplementation { - - /** - * Property name to fire in case {@link #includes} would change. - * (The old and new value should be left null.) - *

    - * Special usage note: - * If multiple {@link FilteringPathResourceImplementation}s inside a single - * {@link ClassPathImplementation} fire changes in this pseudo-property in - * succession, all using the same non-null {@link java.beans.PropertyChangeEvent#setPropagationId}, - * {@link org.netbeans.api.java.classpath.ClassPath#PROP_INCLUDES} will be fired just once. This can be used - * to prevent "event storms" from triggering excessive Java source root rescanning. - */ - String PROP_INCLUDES = "includes"; // NOI18N - - /** - * Determines whether a given resource is included in the classpath or not. - * @param root one of the roots given by {@link #getRoots} (else may throw {@link IllegalArgumentException}) - * @param resource a relative resource path within that root; may refer to a file or slash-terminated folder; the empty string refers to the root itself - * @return true if included (or, in the case of a folder, at least partially included); false if excluded - */ - boolean includes(URL root, String resource); - -} diff --git a/api.java/src/org/netbeans/spi/java/classpath/PathResourceImplementation.java b/api.java/src/org/netbeans/spi/java/classpath/PathResourceImplementation.java deleted file mode 100644 --- a/api.java/src/org/netbeans/spi/java/classpath/PathResourceImplementation.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ -package org.netbeans.spi.java.classpath; - -import java.beans.PropertyChangeListener; -import java.net.URL; - -/** - * SPI interface for one classpath entry. - * @see ClassPathImplementation - * @since org.netbeans.api.java/1 1.4 - */ -public interface PathResourceImplementation { - - public static final String PROP_ROOTS = "roots"; //NOI18N - - /** Roots of the class path entry. - * In the case of simple resource it returns array containing just one URL. - * In the case of composite resource it returns array containing one or more URL. - * @return array of URL, never returns null. - */ - public URL[] getRoots(); - - /** - * Returns ClassPathImplementation representing the content of the PathResourceImplementation. - * If the PathResourceImplementation represents leaf resource, it returns null. - * The ClassPathImplementation is live and can be used for path resource content - * modification. - *

    Semi-deprecated. There was never a real reason for this method to exist. - * If implementing PathResourceImplementation you can simply return null; - * it is unlikely anyone will call this method anyway. - * @return classpath handle in case of composite resource; null for leaf resource - */ - public ClassPathImplementation getContent(); - - /** - * Adds property change listener. - * The listener is notified when the roots of the entry are changed. - * @param listener - */ - public void addPropertyChangeListener(PropertyChangeListener listener); - - /** - * Removes property change listener. - * @param listener - */ - public void removePropertyChangeListener(PropertyChangeListener listener); - -} diff --git a/api.java/src/org/netbeans/spi/java/classpath/package.html b/api.java/src/org/netbeans/spi/java/classpath/package.html deleted file mode 100644 --- a/api.java/src/org/netbeans/spi/java/classpath/package.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - -SPI permitting new classpaths to be constructed and registered. - -

    {@link org.netbeans.spi.java.classpath.ClassPathProvider}s can be registered -to default lookup in order to associate information about classpaths with files. -For example, a Java-oriented project type would normally indicate that its Java -sources have a certain classpath associated with them.
    -For a source file the ClassPathProvider has to return a -{@link org.netbeans.api.java.classpath.ClassPath} of the following ClassPath types: -

      -
    • ClassPath.SOURCE - the classpath contains the source roots of the project
    • -
    • ClassPath.BOOT - the classpath contains the jdk runtime libraries
    • -
    • ClassPath.COMPILE - the classpath contains the project compile libraries (compile classpath)
    • -
    -it may also return a ClassPath of type ClassPath.EXEC pointing to the build output folder. -
    -For build output the ClassPathProvider has to return a ClassPath of the following -types: -
      -
    • ClassPath.BOOT - the classpath contains the jdk runtime libraries
    • -
    • ClassPath.COMPILE - the classpath contains the project compile libraries (compile classpath)
    • -
    • ClassPath.EXEC - the classpath contains the build output folder
    • -
    -

    - -

    {@link org.netbeans.spi.java.classpath.ClassPathFactory} may be used to -create new {@link org.netbeans.api.java.classpath.ClassPath} instances.

    - - - diff --git a/api.java/src/org/netbeans/spi/java/classpath/support/ClassPathSupport.java b/api.java/src/org/netbeans/spi/java/classpath/support/ClassPathSupport.java deleted file mode 100644 --- a/api.java/src/org/netbeans/spi/java/classpath/support/ClassPathSupport.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ -package org.netbeans.spi.java.classpath.support; - -import java.io.File; -import org.netbeans.spi.java.classpath.PathResourceImplementation; -import org.netbeans.spi.java.classpath.ClassPathImplementation; -import org.netbeans.spi.java.classpath.ClassPathFactory; -import org.netbeans.modules.java.classpath.*; -import org.netbeans.api.java.classpath.ClassPath; -import org.openide.ErrorManager; -import org.openide.filesystems.FileObject; - -import java.net.URL; -import java.util.List; -import java.util.ArrayList; -import org.openide.filesystems.FileStateInvalidException; -import org.openide.filesystems.FileUtil; - -/** - * Convenience factory for creating classpaths of common sorts. - * @since org.netbeans.api.java/1 1.4 - */ -public class ClassPathSupport { - - private ClassPathSupport () { - } - - - /** Creates leaf PathResourceImplementation. - * The created PathResourceImplementation has exactly one immutable root. - * @param url the root of the resource. The URL must refer to folder. In the case of archive file - * the jar protocol URL must be used. - * @return PathResourceImplementation - */ - public static PathResourceImplementation createResource (URL url) { - if (url == null) { - throw new NullPointerException("Cannot pass null URL to ClassPathSupport.createResource"); // NOI18N - } - // FU.iAF is a bit slow, so don't call it except when assertions are on: - boolean assertions = false; - assert assertions = true; - if (assertions && FileUtil.isArchiveFile(url)) { - throw new IllegalArgumentException("File URL pointing to " + // NOI18N - "JAR is not valid classpath entry. Use jar: URL. Was: "+url); // NOI18N - } - if (!url.toExternalForm().endsWith("/")) { // NOI18N - throw new IllegalArgumentException("URL must be a folder URL (append '/' if necessary): " + url); // NOI18N - } - return new SimplePathResourceImplementation (url); - } - - - /** - * Create ClassPathImplementation for the given list of - * {@link PathResourceImplementation} entries. - * @param entries list of {@link PathResourceImplementation} instances; - * cannot be null; can be empty - * @return SPI classpath - */ - public static ClassPathImplementation createClassPathImplementation(List< ? extends PathResourceImplementation> entries) { - if (entries == null) { - throw new NullPointerException("Cannot pass null entries"); // NOI18N - } - return new SimpleClassPathImplementation(entries); - } - - - /** - * Create ClassPath for the given list of - * {@link PathResourceImplementation} entries. - * @param entries list of {@link PathResourceImplementation} instances; - * cannot be null; can be empty - * @return API classpath - */ - public static ClassPath createClassPath(List entries) { - if (entries == null) { - throw new NullPointerException("Cannot pass null entries"); // NOI18N - } - return ClassPathFactory.createClassPath(createClassPathImplementation(entries)); - } - - - /** - * Create ClassPath for the given array of class path roots - * @param roots array of fileobjects which must correspond to directory. - * In the case of archive file, the FileObject representing the root of the - * archive must be used. Cannot be null; can be empty array; array can contain nulls. - * @return API classpath - */ - public static ClassPath createClassPath(FileObject... roots) { - assert roots != null; - List l = new ArrayList (); - for (FileObject root : roots) { - if (root == null) { - continue; - } - try { - URL u = root.getURL(); - l.add(createResource(u)); - } catch (FileStateInvalidException e) { - ErrorManager.getDefault().notify (e); - } - } - return createClassPath (l); - } - - - /** - * Create ClassPath for the given array of class path roots - * @param roots array of URLs which must correspond to directory. - * In the case of archive file, the jar protocol URL must be used. - * Cannot be null; can be empty array; array can contain nulls. - * @return API classpath - */ - public static ClassPath createClassPath(URL... roots) { - assert roots != null; - List l = new ArrayList (); - for (URL root : roots) { - if (root == null) - continue; - l.add (createResource(root)); - } - return createClassPath(l); - } - - /** - * Convenience method to create a classpath object from a conventional string representation. - * @param jvmPath a JVM-style classpath (folder or archive paths separated by {@link File#pathSeparator}) - * @return a corresponding classpath object - * @throws IllegalArgumentException in case a path entry looks to be invalid - * @since org.netbeans.api.java/1 1.15 - * @see FileUtil#urlForArchiveOrDir - * @see ClassPath#toJVMPath - */ - public static ClassPath createClassPath(String jvmPath) throws IllegalArgumentException { - List l = new ArrayList(); - for (String piece : jvmPath.split(File.pathSeparator)) { - File f = FileUtil.normalizeFile(new File(piece)); - URL u = FileUtil.urlForArchiveOrDir(f); - if (u == null) { - throw new IllegalArgumentException("Path entry looks to be invalid: " + piece); // NOI18N - } - l.add(createResource(u)); - } - return createClassPath(l); - } - - /** - * Creates read only proxy ClassPathImplementation for given delegates. - * The order of resources is given by the order of the delegates - * @param delegates ClassPathImplementations to delegate to. - * @return SPI classpath - */ - public static ClassPathImplementation createProxyClassPathImplementation(ClassPathImplementation... delegates) { - return new ProxyClassPathImplementation (delegates); - } - - - /** - * Creates read only proxy ClassPath for given delegates. - * The order of resources is given by the order of the delegates - * @param delegates ClassPaths to delegate to. - * @return API classpath - */ - public static ClassPath createProxyClassPath(ClassPath... delegates) { - assert delegates != null; - ClassPathImplementation[] impls = new ClassPathImplementation [delegates.length]; - for (int i = 0; i < delegates.length; i++) { - impls[i] = ClassPathAccessor.DEFAULT.getClassPathImpl (delegates[i]); - } - return ClassPathFactory.createClassPath (createProxyClassPathImplementation(impls)); - } - -} diff --git a/api.java/src/org/netbeans/spi/java/classpath/support/CompositePathResourceBase.java b/api.java/src/org/netbeans/spi/java/classpath/support/CompositePathResourceBase.java deleted file mode 100644 --- a/api.java/src/org/netbeans/spi/java/classpath/support/CompositePathResourceBase.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ -package org.netbeans.spi.java.classpath.support; - -import org.netbeans.spi.java.classpath.PathResourceImplementation; -import org.netbeans.spi.java.classpath.ClassPathImplementation; - -import java.net.URL; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeEvent; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Arrays; - -/** - * This class provides a base class for PathResource implementations - * @since org.netbeans.api.java/1 1.4 - */ -public abstract class CompositePathResourceBase implements PathResourceImplementation { - - private URL[] roots; - private ClassPathImplementation model; - private ArrayList pListeners; - - /** - * Returns the roots of the PathResource - * @return URL[] - */ - public final URL[] getRoots() { - if (this.roots == null) { - synchronized (this) { - if (this.roots == null) { - initContent (); - List result = new ArrayList (); - for (PathResourceImplementation pri : this.model.getResources()) { - result.addAll (Arrays.asList(pri.getRoots())); - } - this.roots = result.toArray (new URL [result.size()]); - } - } - } - return this.roots; - } - - - /** - * Returns the ClassPathImplementation representing the content of this PathResourceImplementation - * @return ClassPathImplementation - */ - public final ClassPathImplementation getContent() { - initContent (); - return this.model; - } - - /** - * Adds property change listener. - * The listener is notified when the roots of the PathResource are changed. - * @param listener - */ - public synchronized final void addPropertyChangeListener(PropertyChangeListener listener) { - if (this.pListeners == null) - this.pListeners = new ArrayList (); - this.pListeners.add (listener); - } - - /** - * Removes PropertyChangeListener - * @param listener - */ - public synchronized final void removePropertyChangeListener(PropertyChangeListener listener) { - if (this.pListeners == null) - return; - this.pListeners.remove (listener); - } - - /** - * Fires PropertyChangeEvent - * @param propName name of property - * @param oldValue old property value or null - * @param newValue new property value or null - */ - protected final void firePropertyChange (String propName, Object oldValue, Object newValue) { - PropertyChangeListener[] _listeners; - synchronized (this) { - if (this.pListeners == null) - return; - _listeners = this.pListeners.toArray(new PropertyChangeListener[this.pListeners.size()]); - } - PropertyChangeEvent event = new PropertyChangeEvent (this, propName, oldValue, newValue); - for (PropertyChangeListener l : _listeners) { - l.propertyChange (event); - } - } - - /** Creates the array of the roots of PathResource. - * Most PathResource (directory, jar) have single root, - * but the PathResource can have more than one root to - * represent more complex resources like libraries. - * The returned value is cached. - * @return ClassPathImplementation - */ - protected abstract ClassPathImplementation createContent (); - - - private synchronized void initContent () { - if (this.model == null) { - ClassPathImplementation cp = createContent (); - assert cp != null; - cp.addPropertyChangeListener (new PropertyChangeListener () { - public void propertyChange (PropertyChangeEvent event) { - roots = null; - firePropertyChange (PROP_ROOTS, null,null); - } - }); - this.model = cp; - } - } -} diff --git a/api.java/src/org/netbeans/spi/java/classpath/support/PathResourceBase.java b/api.java/src/org/netbeans/spi/java/classpath/support/PathResourceBase.java deleted file mode 100644 --- a/api.java/src/org/netbeans/spi/java/classpath/support/PathResourceBase.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ -package org.netbeans.spi.java.classpath.support; - - -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeEvent; -import java.util.ArrayList; -import java.util.Iterator; -import org.netbeans.spi.java.classpath.PathResourceImplementation; - -/** - * This class provides a base class for PathResource implementations - * @since org.netbeans.api.java/1 1.4 - */ -public abstract class PathResourceBase implements PathResourceImplementation { - - private ArrayList pListeners; - - - /** - * Adds property change listener. - * The listener is notified when the roots of the PathResource are changed. - * @param listener - */ - public synchronized final void addPropertyChangeListener(PropertyChangeListener listener) { - if (this.pListeners == null) - this.pListeners = new ArrayList (); - this.pListeners.add (listener); - } - - /** - * Removes PropertyChangeListener - * @param listener - */ - public synchronized final void removePropertyChangeListener(PropertyChangeListener listener) { - if (this.pListeners == null) - return; - this.pListeners.remove (listener); - } - - /** - * Fires PropertyChangeEvent - * @param propName name of property - * @param oldValue old property value or null - * @param newValue new property value or null - */ - protected final void firePropertyChange (String propName, Object oldValue, Object newValue) { - PropertyChangeListener[] _listeners; - synchronized (this) { - if (this.pListeners == null) - return; - _listeners = this.pListeners.toArray(new PropertyChangeListener[this.pListeners.size()]); - } - PropertyChangeEvent event = new PropertyChangeEvent (this, propName, oldValue, newValue); - for (PropertyChangeListener l : _listeners) { - l.propertyChange (event); - } - } -} diff --git a/api.java/src/org/netbeans/spi/java/classpath/support/package.html b/api.java/src/org/netbeans/spi/java/classpath/support/package.html deleted file mode 100644 --- a/api.java/src/org/netbeans/spi/java/classpath/support/package.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - -Convenience classes to make it easier to create classpaths. - -

    {@link org.netbeans.spi.java.classpath.support.ClassPathSupport} provides -various ways to create {@link org.netbeans.api.java.classpath.ClassPath} objects -beyond what the plain SPI provides.

    - -

    {@link org.netbeans.spi.java.classpath.support.PathResourceBase} and -{@link org.netbeans.spi.java.classpath.support.CompositePathResourceBase} can be -used to define parts of a classpath in a controlled way.

    - - - diff --git a/api.java/src/org/netbeans/spi/java/queries/support/SourceForBinaryQueryImpl2Base.java b/api.java/src/org/netbeans/spi/java/queries/support/SourceForBinaryQueryImpl2Base.java deleted file mode 100644 --- a/api.java/src/org/netbeans/spi/java/queries/support/SourceForBinaryQueryImpl2Base.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - * - * Contributor(s): - * - * Portions Copyrighted 2008 Sun Microsystems, Inc. - */ - -package org.netbeans.spi.java.queries.support; - -import org.netbeans.api.java.queries.SourceForBinaryQuery; -import org.netbeans.modules.java.queries.SFBQImpl2Result; -import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2; -import org.openide.util.Parameters; - -/** - * Base class for {@link SourceForBinaryQueryImplementation2} which need to delegate - * to other {@link SourceForBinaryQueryImplementation}. - * @since 1.16 - * @author Tomas Zezula - */ -public abstract class SourceForBinaryQueryImpl2Base implements SourceForBinaryQueryImplementation2 { - - /** - * Creates a wrapper for {@link SourceForBinaryQuery.Result}. This method - * should be used by delegating {@link SourceForBinaryQueryImplementation2} - * which need to delegate to {@link SourceForBinaryQueryImplementation}. - * @param result returned by {@link SourceForBinaryQueryImplementation}, - * When result is already instanceof {@link SourceForBinaryQueryImplementation2.Result} - * it's returned without wrapping. - * @return a {@link SourceForBinaryQueryImplementation2.Result}. - */ - protected final Result asResult (SourceForBinaryQuery.Result result) { - Parameters.notNull("result", result); //NOI18N - if (result instanceof Result) { - return (Result) result; - } - else { - return new SFBQImpl2Result(result); - } - } -} diff --git a/api.java/test/unit/src/org/netbeans/api/java/classpath/ClassPathTest.java b/api.java/test/unit/src/org/netbeans/api/java/classpath/ClassPathTest.java deleted file mode 100644 --- a/api.java/test/unit/src/org/netbeans/api/java/classpath/ClassPathTest.java +++ /dev/null @@ -1,701 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ - -package org.netbeans.api.java.classpath; - -import java.io.File; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.io.FileOutputStream; -import java.lang.ref.Reference; -import java.lang.ref.WeakReference; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.SortedSet; -import java.util.StringTokenizer; -import java.util.TreeSet; -import java.util.jar.JarOutputStream; -import java.util.logging.Level; -import java.util.zip.ZipEntry; -import org.netbeans.junit.Log; -import org.netbeans.junit.NbTestCase; -import org.netbeans.spi.java.classpath.support.ClassPathSupport; -import org.netbeans.spi.java.classpath.ClassPathImplementation; -import org.netbeans.spi.java.classpath.ClassPathFactory; -import org.netbeans.spi.java.classpath.FilteringPathResourceImplementation; -import org.netbeans.spi.java.classpath.PathResourceImplementation; -import org.openide.filesystems.FileObject; -import org.openide.filesystems.FileUtil; - -public class ClassPathTest extends NbTestCase { - - public ClassPathTest(String testName) { - super(testName); - } - - protected @Override void setUp() throws Exception { - super.setUp(); - clearWorkDir(); - } - - private File getBaseDir() throws Exception { - return FileUtil.normalizeFile(getWorkDir()); - } - - /** - * Tests ClassPath.getResourceName (); - */ - public void testGetResourceName() throws Exception { - File f = getBaseDir(); - f = new File(f.getPath()+"/w.e.i.r.d/f o l d e r"); - f.mkdirs(); - File f2 = new File(f, "org/netbeans/test"); - f2.mkdirs(); - File f3 = new File(f2, "Main.java"); - f3.createNewFile(); - - FileObject cpRoot = FileUtil.toFileObject(f); - FileObject cpItem = FileUtil.toFileObject(f2); - FileObject clazz = FileUtil.toFileObject(f3); - ClassPath cp = ClassPathSupport.createClassPath(new FileObject[]{cpRoot}); - String pkg = cp.getResourceName(cpItem); - assertEquals("org/netbeans/test", pkg); - - pkg = cp.getResourceName(cpItem, '.', true); - assertEquals("org.netbeans.test", pkg); - - pkg = cp.getResourceName(cpItem, '.', false); - assertEquals("org.netbeans.test", pkg); - - pkg = cp.getResourceName(cpItem, '#', true); - assertEquals("org#netbeans#test", pkg); - - pkg = cp.getResourceName(cpItem, '#', false); - assertEquals("org#netbeans#test", pkg); - - pkg = cp.getResourceName(clazz); - assertEquals("org/netbeans/test/Main.java", pkg); - - pkg = cp.getResourceName(clazz, '.', true); - assertEquals("org.netbeans.test.Main.java", pkg); - - pkg = cp.getResourceName(clazz, '.', false); - assertEquals("org.netbeans.test.Main", pkg); - - pkg = cp.getResourceName(clazz, '@', true); - assertEquals("org@netbeans@test@Main.java", pkg); - - pkg = cp.getResourceName(clazz, '@', false); - assertEquals("org@netbeans@test@Main", pkg); - } - - /** - * Tests ClassPath.findAllResources(), ClassPath.findResoruce(), - * ClassPath.contains (), ClassPath.findOwnerRoot(), - * ClassPath.isResourceVisible () - */ - public void testGetResource () throws Exception { - File root_1 = new File (getBaseDir(),"root_1"); - root_1.mkdir(); - File root_2 = new File (getBaseDir(),"root_2"); - root_2.mkdir(); - FileObject[] roots = new FileObject [] { - FileUtil.toFileObject(root_1), - FileUtil.toFileObject(root_2), - }; - - FileObject tmp = roots[0].createFolder("org"); - tmp = tmp.createFolder("me"); - FileObject testFo_1 = tmp.createData("Foo","txt"); - tmp = roots[1].createFolder("org"); - tmp = tmp.createFolder("me"); - FileObject testFo_2 = tmp.createData("Foo","txt"); - ClassPath cp = ClassPathSupport.createClassPath(roots); - - //findResource - assertTrue(cp.findResource ("org/me/Foo.txt")==testFo_1); - assertTrue (cp.findResource("org/me/None.txt")==null); - - //findAllResources - List res = cp.findAllResources ("org/me/Foo.txt"); - assertTrue (res.size() == 2); - assertTrue (res.contains(testFo_1)); - assertTrue (res.contains(testFo_2)); - - //contains - assertTrue (cp.contains (testFo_1)); - assertTrue (cp.contains (testFo_2)); - assertFalse (cp.contains (roots[0].getParent())); - - //findOwnerRoot - assertTrue (cp.findOwnerRoot(testFo_1)==roots[0]); - assertTrue (cp.findOwnerRoot(testFo_2)==roots[1]); - - /* - //isResourceVisible - assertTrue (cp.isResourceVisible(testFo_1)); - assertFalse (cp.isResourceVisible(testFo_2)); - */ - - cp = null; - roots[0].delete(); - roots[1].delete(); - } - - /** - * Test ClassPath.getRoots(), ClassPath.addPropertyChangeListener (), - * ClassPath.entries () and classpath SPI. - */ - public void testListening() throws Exception { - // XXX unreliable, would be improved by usage of TestFileUtils methods: - - File root_1 = new File (getBaseDir(),"root_1"); - root_1.mkdir(); - File root_2 = new File (getBaseDir(),"root_2"); - root_2.mkdir(); - File root_3 = new File (getBaseDir(),"root_3.jar"); - JarOutputStream out = new JarOutputStream ( new FileOutputStream (root_3)); - try { - out.putNextEntry(new ZipEntry("test.txt")); - out.write ("test".getBytes()); - } finally { - out.close (); - } - assertNotNull("Cannot find file",FileUtil.toFileObject(root_1)); - assertNotNull("Cannot find file",FileUtil.toFileObject(root_2)); - assertNotNull("Cannot find file",FileUtil.toFileObject(root_3)); - TestClassPathImplementation impl = new TestClassPathImplementation(); - ClassPath cp = ClassPathFactory.createClassPath (impl); - impl.addResource(root_1.toURI().toURL()); - cp.addPropertyChangeListener (impl); - impl.addResource (root_2.toURI().toURL()); - impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS); - assertTrue (cp.getRoots().length==2); - impl.removeResource (root_2.toURI().toURL()); - impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS); - assertTrue (cp.getRoots().length==1); - FileObject fo = cp.getRoots()[0]; - FileObject parentFolder = fo.getParent(); - fo.delete(); - impl.assertEvents(ClassPath.PROP_ROOTS); - assertTrue (cp.getRoots().length==0); - parentFolder.createFolder("root_1"); - assertTrue (cp.getRoots().length==1); - impl.assertEvents(ClassPath.PROP_ROOTS); - FileObject archiveFile = FileUtil.toFileObject(root_3); - impl.addResource(FileUtil.getArchiveRoot(archiveFile.getURL())); - assertEquals (cp.getRoots().length,2); - impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS); - root_3.delete(); - root_3 = new File (getBaseDir(),"root_3.jar"); - Thread.sleep(1000); - out = new JarOutputStream ( new FileOutputStream (root_3)); - try { - out.putNextEntry(new ZipEntry("test2.txt")); - out.write ("test2".getBytes()); - } finally { - out.close (); - } - archiveFile.refresh(); - impl.assertEvents(ClassPath.PROP_ROOTS); - root_1.delete(); - root_2.delete(); - root_3.delete(); - cp = null; - } - - public void testListening2() throws Exception { - // Checks that changes in PathResourceImplementation.PROP_ROOTS matter. - class FiringPRI implements PathResourceImplementation { - private URL[] roots = new URL[0]; - public URL[] getRoots() { - return roots; - } - void changeRoots(URL[] nue) { - roots = nue; - pcs.firePropertyChange(PROP_ROOTS, null, null); - } - public ClassPathImplementation getContent() { - return null; - } - PropertyChangeSupport pcs = new PropertyChangeSupport(this); - public void addPropertyChangeListener(PropertyChangeListener listener) { - pcs.addPropertyChangeListener(listener); - } - public void removePropertyChangeListener(PropertyChangeListener listener) { - pcs.removePropertyChangeListener(listener); - } - } - FiringPRI pri = new FiringPRI(); - TestClassPathImplementation impl = new TestClassPathImplementation(); - impl.addResource(pri); - ClassPath cp = ClassPathFactory.createClassPath(impl); - assertEquals(Collections.emptyList(), Arrays.asList(cp.getRoots())); - cp.addPropertyChangeListener(impl); - File d = new File(getBaseDir(), "d"); - d.mkdir(); - pri.changeRoots(new URL[] {d.toURI().toURL()}); - impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS); - assertEquals(Collections.singletonList(FileUtil.toFileObject(d)), Arrays.asList(cp.getRoots())); - } - - public void testChangesAcknowledgedWithoutListener() throws Exception { - // Discovered in #72573. - clearWorkDir(); - File root = new File(getWorkDir(), "root"); - URL rootU = root.toURI().toURL(); - if (!rootU.toExternalForm().endsWith("/")) { - rootU = new URL(rootU.toExternalForm() + "/"); - } - ClassPath cp = ClassPathSupport.createClassPath(new URL[] {rootU}); - assertEquals("nothing there yet", null, cp.findResource("f")); - FileObject f = FileUtil.createData(FileUtil.toFileObject(getWorkDir()), "root/f"); - assertEquals("found new file", f, cp.findResource("f")); - f.delete(); - assertEquals("again empty", null, cp.findResource("f")); - } - - static final class TestClassPathImplementation implements ClassPathImplementation, PropertyChangeListener { - - private final PropertyChangeSupport support = new PropertyChangeSupport (this); - private final List resources = new ArrayList (); - private final SortedSet events = new TreeSet(); - - public synchronized void addResource (URL resource) { - PathResourceImplementation pr = ClassPathSupport.createResource (resource); - addResource(pr); - } - - public synchronized void addResource(PathResourceImplementation pr) { - this.resources.add (pr); - this.support.firePropertyChange (ClassPathImplementation.PROP_RESOURCES,null,null); - } - - public synchronized void removeResource (URL resource) { - for (Iterator it = this.resources.iterator(); it.hasNext();) { - PathResourceImplementation pr = (PathResourceImplementation) it.next (); - if (Arrays.asList(pr.getRoots()).contains (resource)) { - this.resources.remove (pr); - this.support.firePropertyChange (ClassPathImplementation.PROP_RESOURCES,null,null); - break; - } - } - } - - public synchronized List getResources() { - return this.resources; - } - - public void addPropertyChangeListener(PropertyChangeListener listener) { - this.support.addPropertyChangeListener (listener); - } - - public void removePropertyChangeListener(PropertyChangeListener listener) { - this.support.removePropertyChangeListener (listener); - } - - public void propertyChange (PropertyChangeEvent event) { - events.add(event.getPropertyName()); - } - - void assertEvents(String... events) { - assertEquals(new TreeSet(Arrays.asList(events)), this.events); - this.events.clear(); - } - } - - public void testFilteredClassPaths() throws Exception { - FileObject bd = FileUtil.toFileObject(getBaseDir()); - FileObject u1fo = bd.createFolder("u1"); - FileObject u2fo = bd.createFolder("u2"); - final URL u1 = u1fo.getURL(); - final URL u2 = u2fo.getURL(); - class FPRI implements FilteringPathResourceImplementation { - private int modulus = 2; - public void changeIncludes(int modulus) { - this.modulus = modulus; - pcs.firePropertyChange(PROP_INCLUDES, null, null); - } - public URL[] getRoots() { - return new URL[] {u1, u2}; - } - public boolean includes(URL root, String resource) { - int offset; - if (root.equals(u1)) { - offset = 0; - } else if (root.equals(u2)) { - offset = 1; - } else { - throw new IllegalArgumentException(root.toString()); - } - return (offset + resource.length()) % modulus == 0; - } - public ClassPathImplementation getContent() { - return null; - } - private PropertyChangeSupport pcs = new PropertyChangeSupport(this); - public void addPropertyChangeListener(PropertyChangeListener listener) { - pcs.addPropertyChangeListener(listener); - } - public void removePropertyChangeListener(PropertyChangeListener listener) { - pcs.removePropertyChangeListener(listener); - } - } - FPRI pr = new FPRI(); - TestClassPathImplementation impl = new TestClassPathImplementation(); - impl.addResource(pr); - ClassPath cp = ClassPathFactory.createClassPath(impl); - FileObject xx1 = u1fo.createData("xx"); - FileObject xxx1 = u1fo.createData("xxx"); - FileObject xy1 = FileUtil.createData(u1fo, "x/y"); - FileObject x_1 = u1fo.createData("x "); - String cau = "\u010Dau"; - FileObject cau1 = u1fo.createData(cau); - FileObject folder = u1fo.createFolder("folder"); - FileObject foldr = u1fo.createFolder("foldr"); - FileObject xx2 = u2fo.createData("xx"); - FileObject xxx2 = u2fo.createData("xxx"); - FileObject xy2 = FileUtil.createData(u2fo, "x/y"); - FileObject x_2 = u2fo.createData("x "); - FileObject cau2 = u2fo.createData(cau); - assertEquals(Arrays.asList(u1fo, u2fo), Arrays.asList(cp.getRoots())); - assertTrue(cp.contains(xx1)); - assertTrue(cp.contains(x_1)); - assertFalse(cp.contains(xxx1)); - assertFalse(cp.contains(cau1)); - assertFalse(cp.contains(xy1)); - assertFalse(cp.contains(xx2)); - assertFalse(cp.contains(x_2)); - assertTrue(cp.contains(xxx2)); - assertTrue(cp.contains(cau2)); - assertTrue(cp.contains(xy2)); - assertFalse(cp.contains(folder)); - assertTrue(cp.contains(foldr)); - assertEquals(xx1, cp.findResource("xx")); - assertEquals(x_1, cp.findResource("x ")); - assertEquals(xxx2, cp.findResource("xxx")); - assertEquals(cau2, cp.findResource(cau)); - assertEquals(xy2, cp.findResource("x/y")); - assertEquals(null, cp.findResource("folder")); - assertEquals(foldr, cp.findResource("foldr")); - assertEquals(Collections.singletonList(xx1), cp.findAllResources("xx")); - assertEquals(Collections.singletonList(x_1), cp.findAllResources("x ")); - assertEquals(Collections.singletonList(xxx2), cp.findAllResources("xxx")); - assertEquals(Collections.singletonList(cau2), cp.findAllResources(cau)); - assertEquals(Collections.singletonList(xy2), cp.findAllResources("x/y")); - assertEquals(Collections.emptyList(), cp.findAllResources("folder")); - assertEquals(Collections.singletonList(foldr), cp.findAllResources("foldr")); - assertEquals("xx", cp.getResourceName(xx1)); - assertEquals("x ", cp.getResourceName(x_1)); - assertEquals("xxx", cp.getResourceName(xxx1)); - assertEquals(cau, cp.getResourceName(cau1)); - assertEquals("x/y", cp.getResourceName(xy1)); - assertEquals("folder", cp.getResourceName(folder)); - assertEquals("foldr", cp.getResourceName(foldr)); - assertEquals(u1fo, cp.findOwnerRoot(xx1)); - assertEquals(u1fo, cp.findOwnerRoot(x_1)); - assertEquals(u1fo, cp.findOwnerRoot(xxx1)); - assertEquals(u1fo, cp.findOwnerRoot(cau1)); - assertEquals(u1fo, cp.findOwnerRoot(xy1)); - assertEquals(u1fo, cp.findOwnerRoot(folder)); - assertEquals(u1fo, cp.findOwnerRoot(foldr)); - assertTrue(cp.isResourceVisible(xx1)); - assertTrue(cp.isResourceVisible(x_1)); - assertFalse(cp.isResourceVisible(xxx1)); - assertFalse(cp.isResourceVisible(cau1)); - assertFalse(cp.isResourceVisible(xy1)); - assertFalse(cp.isResourceVisible(folder)); - assertTrue(cp.isResourceVisible(foldr)); - ClassPath.Entry e1 = cp.entries().get(0); - assertTrue(e1.includes("xx")); - assertTrue(e1.includes("x ")); - assertFalse(e1.includes("xxx")); - assertFalse(e1.includes(cau)); - assertFalse(e1.includes("x/y")); - assertFalse(e1.includes("folder/")); - assertTrue(e1.includes("foldr/")); - assertTrue(e1.includes(xx1)); - assertTrue(e1.includes(x_1)); - assertFalse(e1.includes(xxx1)); - assertFalse(e1.includes(cau1)); - assertFalse(e1.includes(xy1)); - assertFalse(e1.includes(folder)); - assertTrue(e1.includes(foldr)); - try { - e1.includes(xx2); - fail(); - } catch (IllegalArgumentException iae) {} - assertTrue(e1.includes(xx1.getURL())); - assertTrue(e1.includes(x_1.getURL())); - assertFalse(e1.includes(xxx1.getURL())); - assertFalse(e1.includes(cau1.getURL())); - assertFalse(e1.includes(xy1.getURL())); - assertFalse(e1.includes(folder.getURL())); - assertTrue(e1.includes(foldr.getURL())); - try { - e1.includes(xx2.getURL()); - fail(); - } catch (IllegalArgumentException iae) {} - cp.addPropertyChangeListener(impl); - pr.changeIncludes(3); - impl.assertEvents(ClassPath.PROP_INCLUDES); - assertFalse(cp.contains(xx1)); - assertFalse(cp.contains(x_1)); - assertTrue(cp.contains(xxx1)); - assertTrue(cp.contains(cau1)); - assertTrue(cp.contains(xy1)); - assertTrue(cp.contains(xx2)); - assertTrue(cp.contains(x_2)); - assertFalse(cp.contains(xxx2)); - assertFalse(cp.contains(cau2)); - assertFalse(cp.contains(xy2)); - assertEquals(xx2, cp.findResource("xx")); - assertEquals(x_2, cp.findResource("x ")); - assertEquals(xxx1, cp.findResource("xxx")); - assertEquals(cau1, cp.findResource(cau)); - assertEquals(xy1, cp.findResource("x/y")); - e1 = cp.entries().get(0); - assertFalse(e1.includes("xx")); - assertFalse(e1.includes("x ")); - assertTrue(e1.includes("xxx")); - assertTrue(e1.includes(cau)); - assertTrue(e1.includes("x/y")); - assertFalse(e1.includes(xx1)); - assertFalse(e1.includes(x_1)); - assertTrue(e1.includes(xxx1)); - assertTrue(e1.includes(cau1)); - assertTrue(e1.includes(xy1)); - assertFalse(e1.includes(xx1.getURL())); - assertFalse(e1.includes(x_1.getURL())); - assertTrue(e1.includes(xxx1.getURL())); - assertTrue(e1.includes(cau1.getURL())); - assertTrue(e1.includes(xy1.getURL())); - } - - public void testFpriChangeFiring() throws Exception { - class FPRI implements FilteringPathResourceImplementation { - URL root; - PropertyChangeSupport pcs = new PropertyChangeSupport(this); - FPRI(URL root) { - this.root = root; - } - public boolean includes(URL root, String resource) { - return true; - } - public URL[] getRoots() { - return new URL[] {root}; - } - public ClassPathImplementation getContent() { - return null; - } - public void addPropertyChangeListener(PropertyChangeListener listener) { - pcs.addPropertyChangeListener(listener); - } - public void removePropertyChangeListener(PropertyChangeListener listener) { - pcs.removePropertyChangeListener(listener); - } - void fire(Object propid) { - PropertyChangeEvent e = new PropertyChangeEvent(this, FilteringPathResourceImplementation.PROP_INCLUDES, null, null); - e.setPropagationId(propid); - pcs.firePropertyChange(e); - } - } - FPRI fpri1 = new FPRI(new File(getWorkDir(), "src1").toURI().toURL()); - FPRI fpri2 = new FPRI(new File(getWorkDir(), "src2").toURI().toURL()); - class L implements PropertyChangeListener { - int cnt; - public void propertyChange(PropertyChangeEvent e) { - if (ClassPath.PROP_INCLUDES.equals(e.getPropertyName())) { - cnt++; - } - } - } - ClassPath cp = ClassPathSupport.createClassPath(Arrays.asList(fpri1, fpri2)); - L l = new L(); - cp.addPropertyChangeListener(l); - //No events fired before cp.entries() called - fpri1.fire(null); - assertEquals(0, l.cnt); - cp.entries(); - fpri1.fire(null); - assertEquals(1, l.cnt); - fpri2.fire(null); - assertEquals(2, l.cnt); - fpri1.fire("hello"); - assertEquals(3, l.cnt); - fpri2.fire("goodbye"); - assertEquals(4, l.cnt); - fpri1.fire("fixed"); - assertEquals(5, l.cnt); - fpri2.fire("fixed"); - assertEquals(5, l.cnt); - fpri1.fire("new"); - assertEquals(6, l.cnt); - } - - public void testLeakingClassPath() throws Exception { - ClassPath cp = ClassPathSupport.createClassPath(new URL("file:///a/"), new URL("file:///b/")); - ClassPath proxyCP = ClassPathSupport.createProxyClassPath(cp); - Reference proxy = new WeakReference(proxyCP); - - proxyCP.entries(); - - proxyCP = null; - - assertGC("the proxy classpath needs to GCable", proxy); - } - - public void testGetClassLoaderPerf () throws Exception { - final String bootPathProp = System.getProperty("sun.boot.class.path"); //NOI18N - List roots = new ArrayList (); - StringTokenizer tk = new StringTokenizer (bootPathProp,File.pathSeparator); - if (tk.hasMoreTokens()) { - final String path = tk.nextToken(); - final File f = FileUtil.normalizeFile(new File (path)); - if (f.canRead()) { - roots.add(f.toURI().toURL()); - } - } - final ClassLoader bootLoader = new URLClassLoader(roots.toArray(new URL[roots.size()]), null); - - final String classPathProp = System.getProperty("java.class.path"); //NOI18N - roots = new ArrayList (); - List roots2 = new ArrayList(); - tk = new StringTokenizer (classPathProp,File.pathSeparator); - while (tk.hasMoreTokens()) { - final String path = tk.nextToken(); - final File f = FileUtil.normalizeFile(new File (path)); - if (!f.canRead()) { - continue; - } - URL url = f.toURI().toURL(); - roots2.add(url); - if (FileUtil.isArchiveFile(url)) { - url = FileUtil.getArchiveRoot(url); - } - roots.add(url); - } - - final ClassPath cp = ClassPathSupport.createClassPath(roots.toArray(new URL[roots.size()])); -// final ClassLoader loader = ClassLoaderSupport.create(cp,bootLoader); -// final ClassLoader loader = new URLClassLoader(roots.toArray(new URL[roots.size()]),bootLoader); - final ClassLoader loader = new URLClassLoader(roots2.toArray(new URL[roots2.size()]),bootLoader); - - final Set classNames = getClassNames (cp); - int noLoaded = 0; - int noFailed = 0; - long st = System.currentTimeMillis(); - for (String className : classNames) { - try { - final Class c = loader.loadClass(className); - noLoaded++; - } catch (ClassNotFoundException e) { - noFailed++; - } - catch (NoClassDefFoundError e) { - noFailed++; - } - } - long et = System.currentTimeMillis(); - System.out.println("Loaded: " + noLoaded + " in: " + (et-st)+"ms"); - } - - private Set getClassNames (final ClassPath cp) { - Set classNames = new HashSet (); - for (FileObject root : cp.getRoots()) { - Enumeration fos = root.getChildren(true); - while (fos.hasMoreElements()) { - FileObject fo = fos.nextElement(); - if (isImportant (fo)) { - classNames.add(cp.getResourceName(fo, '.', false)); - } - } - } - return classNames; - } - - private boolean isImportant (final FileObject fo) { - if (fo.isFolder()) { - return false; - } - if (!"class".equals(fo.getExt())) { //NOI18N - return false; - } - return !fo.getName().contains("$"); //NOI18N - - } - - public void testJVMPathConversion() throws Exception { - String root = getWorkDir().toURI().toString(); - ClassPath cp = ClassPathSupport.createClassPath( - new URL(root + "folder/"), - new URL("jar:" + root + "file.zip!/"), - new URL("jar:" + root + "file.zip!/subdir/")); - assertEquals(massagePath("/folder:/file.zip"), cp.toString(ClassPath.PathConversionMode.SKIP)); - assertEquals(massagePath("/folder:/file.zip:") + "jar:" + root + "file.zip!/subdir/", cp.toString(ClassPath.PathConversionMode.PRINT)); - try { - cp.toString(ClassPath.PathConversionMode.FAIL); - fail(); - } catch (IllegalArgumentException x) {/* OK */} - CharSequence warnings = Log.enable(ClassPath.class.getName(), Level.WARNING); - assertEquals(massagePath("/folder:/file.zip"), cp.toString(ClassPath.PathConversionMode.WARN)); - assertTrue(warnings.toString(), warnings.toString().contains("subdir")); - - cp = ClassPathSupport.createClassPath( - new URL(root + "folder/"), - new URL("jar:" + root + "file.zip!/")); - assertEquals(cp.toString(), ClassPathSupport.createClassPath(cp.toString()).toString()); - // XXX could also test IAE (tricky - need to have a URLMapper in Lookup, etc.) - } - private String massagePath(String path) throws Exception { - return path.replace('/', File.separatorChar).replace(':', File.pathSeparatorChar).replace("", getWorkDir().getAbsolutePath()); - } - -} diff --git a/api.java/test/unit/src/org/netbeans/api/java/classpath/GlobalPathRegistryTest.java b/api.java/test/unit/src/org/netbeans/api/java/classpath/GlobalPathRegistryTest.java deleted file mode 100644 --- a/api.java/test/unit/src/org/netbeans/api/java/classpath/GlobalPathRegistryTest.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ - -package org.netbeans.api.java.classpath; - -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; -import java.util.Map; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import org.netbeans.api.java.queries.SourceForBinaryQuery; -import org.netbeans.junit.MockServices; -import org.netbeans.junit.NbTestCase; -import org.netbeans.spi.java.classpath.support.ClassPathSupport; -import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation; -import org.openide.filesystems.FileObject; -import org.netbeans.spi.java.classpath.ClassPathFactory; -import org.netbeans.spi.java.classpath.ClassPathImplementation; -import org.netbeans.spi.java.classpath.FilteringPathResourceImplementation; -import org.netbeans.spi.java.classpath.support.PathResourceBase; -import org.openide.filesystems.FileStateInvalidException; -import org.openide.filesystems.FileUtil; -import org.openide.util.ChangeSupport; -import org.openide.util.Lookup; - -/** - * Test functionality of GlobalPathRegistry. - * @author Jesse Glick - */ -public class GlobalPathRegistryTest extends NbTestCase { - - public GlobalPathRegistryTest(String name) { - super(name); - MockServices.setServices(SFBQImpl.class, DeadLockSFBQImpl.class); - } - - private GlobalPathRegistry r; - private FileObject root; - private ClassPath cp1, cp2, cp3, cp4, cp5; - protected void setUp() throws Exception { - super.setUp(); - r = GlobalPathRegistry.getDefault(); - r.clear(); - clearWorkDir(); - root = FileUtil.toFileObject(getWorkDir()); - cp1 = ClassPathSupport.createClassPath(new FileObject[] {root.createFolder("1")}); - cp2 = ClassPathSupport.createClassPath(new FileObject[] {root.createFolder("2")}); - cp3 = ClassPathSupport.createClassPath(new FileObject[] {root.createFolder("3")}); - cp4 = ClassPathSupport.createClassPath(new FileObject[] {root.createFolder("4")}); - cp5 = ClassPathSupport.createClassPath(new FileObject[] {root.createFolder("5")}); - } - - public void testBasicOperation() throws Exception { - assertEquals("initially no paths of type a", Collections.emptySet(), r.getPaths("a")); - r.register("a", new ClassPath[] {cp1, cp2}); - assertEquals("added some paths of type a", new HashSet(Arrays.asList(new ClassPath[] {cp1, cp2})), r.getPaths("a")); - r.register("a", new ClassPath[0]); - assertEquals("did not add any new paths to a", new HashSet(Arrays.asList(new ClassPath[] {cp1, cp2})), r.getPaths("a")); - assertEquals("initially no paths of type b", Collections.emptySet(), r.getPaths("b")); - r.register("b", new ClassPath[] {cp3, cp4, cp5}); - assertEquals("added some paths of type b", new HashSet(Arrays.asList(new ClassPath[] {cp3, cp4, cp5})), r.getPaths("b")); - r.unregister("a", new ClassPath[] {cp1}); - assertEquals("only one path left of type a", Collections.singleton(cp2), r.getPaths("a")); - r.register("a", new ClassPath[] {cp2, cp3}); - assertEquals("only one new path added of type a", new HashSet(Arrays.asList(new ClassPath[] {cp2, cp3})), r.getPaths("a")); - r.unregister("a", new ClassPath[] {cp2}); - assertEquals("still have extra cp2 in a", new HashSet(Arrays.asList(new ClassPath[] {cp2, cp3})), r.getPaths("a")); - r.unregister("a", new ClassPath[] {cp2}); - assertEquals("last cp2 removed from a", Collections.singleton(cp3), r.getPaths("a")); - r.unregister("a", new ClassPath[] {cp3}); - assertEquals("a now empty", Collections.emptySet(), r.getPaths("a")); - r.unregister("a", new ClassPath[0]); - assertEquals("a still empty", Collections.emptySet(), r.getPaths("a")); - try { - r.unregister("a", new ClassPath[] {cp3}); - fail("should not have been permitted to unregister a nonexistent entry"); - } catch (IllegalArgumentException x) { - // Good. - } - } - - public void testListening() throws Exception { - assertEquals("initially no paths of type b", Collections.emptySet(), r.getPaths("b")); - L l = new L(); - r.addGlobalPathRegistryListener(l); - r.register("b", new ClassPath[] {cp1, cp2}); - GlobalPathRegistryEvent e = l.event(); - assertNotNull("got an event", e); - assertTrue("was an addition", l.added()); - assertEquals("right registry", r, e.getRegistry()); - assertEquals("right ID", "b", e.getId()); - assertEquals("right changed paths", new HashSet(Arrays.asList(new ClassPath[] {cp1, cp2})), e.getChangedPaths()); - r.register("b", new ClassPath[] {cp2, cp3}); - e = l.event(); - assertNotNull("got an event", e); - assertTrue("was an addition", l.added()); - assertEquals("right changed paths", Collections.singleton(cp3), e.getChangedPaths()); - r.register("b", new ClassPath[] {cp3}); - e = l.event(); - assertNull("no event for adding a dupe", e); - r.unregister("b", new ClassPath[] {cp1, cp3, cp3}); - e = l.event(); - assertNotNull("got an event", e); - assertFalse("was a removal", l.added()); - assertEquals("right changed paths", new HashSet(Arrays.asList(new ClassPath[] {cp1, cp3})), e.getChangedPaths()); - r.unregister("b", new ClassPath[] {cp2}); - e = l.event(); - assertNull("no event for removing an extra", e); - r.unregister("b", new ClassPath[] {cp2}); - e = l.event(); - assertNotNull("now an event for removing the last copy", e); - assertFalse("was a removal", l.added()); - assertEquals("right changed paths", Collections.singleton(cp2), e.getChangedPaths()); - } - - - public void testGetSourceRoots () throws Exception { - SFBQImpl query = Lookup.getDefault().lookup(SFBQImpl.class); - assertNotNull ("SourceForBinaryQueryImplementation not found in lookup",query); - query.addPair(cp3.getRoots()[0].getURL(),new FileObject[0]); - ClassPathTest.TestClassPathImplementation cpChangingImpl = new ClassPathTest.TestClassPathImplementation(); - ClassPath cpChanging = ClassPathFactory.createClassPath(cpChangingImpl); - assertEquals("cpChangingImpl is empty", 0, cpChanging.getRoots().length); - r.register(ClassPath.SOURCE, new ClassPath[] {cp1, cp2, cpChanging}); - r.register (ClassPath.COMPILE, new ClassPath[] {cp3}); - Set result = r.getSourceRoots(); - assertEquals ("Wrong number of source roots",result.size(),cp1.getRoots().length + cp2.getRoots().length); - assertTrue ("Missing roots from cp1",result.containsAll (Arrays.asList(cp1.getRoots()))); - assertTrue ("Missing roots from cp2",result.containsAll (Arrays.asList(cp2.getRoots()))); - // simulate classpath change: - URL u = cp5.entries().get(0).getURL(); - cpChangingImpl.addResource(u); - assertEquals("cpChangingImpl is not empty", 1, cpChanging.getRoots().length); - result = r.getSourceRoots(); - assertEquals ("Wrong number of source roots",result.size(),cp1.getRoots().length + cp2.getRoots().length + cpChanging.getRoots().length); - assertTrue ("Missing roots from cp1",result.containsAll (Arrays.asList(cp1.getRoots()))); - assertTrue ("Missing roots from cp2",result.containsAll (Arrays.asList(cp2.getRoots()))); - cpChangingImpl.removeResource(u); - - query.addPair(cp3.getRoots()[0].getURL(),cp4.getRoots()); - result = r.getSourceRoots(); - assertEquals ("Wrong number of source roots",result.size(),cp1.getRoots().length + cp2.getRoots().length+cp4.getRoots().length); - assertTrue ("Missing roots from cp1",result.containsAll (Arrays.asList(cp1.getRoots()))); - assertTrue ("Missing roots from cp2",result.containsAll (Arrays.asList(cp2.getRoots()))); - assertTrue ("Missing roots from cp4",result.containsAll (Arrays.asList(cp4.getRoots()))); - } - - /** - * Tests issue: #60976:Deadlock between JavaFastOpen$Evaluator and AntProjectHelper$something - */ - public void testGetSourceRootsDeadLock () throws Exception { - DeadLockSFBQImpl query = Lookup.getDefault().lookup(DeadLockSFBQImpl.class); - assertNotNull ("SourceForBinaryQueryImplementation not found in lookup",query); - r.register (ClassPath.COMPILE, new ClassPath[] {cp1}); - try { - query.setSynchronizedJob ( - new Runnable () { - public void run () { - r.register(ClassPath.COMPILE, new ClassPath[] {cp2}); - } - } - ); - r.getSourceRoots(); - } finally { - query.setSynchronizedJob (null); - } - } - - public void testFindResource() throws Exception { - final FileObject src1 = root.createFolder("src1"); - FileObject src1included = FileUtil.createData(src1, "included/file"); - FileUtil.createData(src1, "excluded/file1"); - FileUtil.createData(src1, "excluded/file2"); - FileObject src2 = root.createFolder("src2"); - FileObject src2included = FileUtil.createData(src2, "included/file"); - FileObject src2excluded1 = FileUtil.createData(src2, "excluded/file1"); - class PRI extends PathResourceBase implements FilteringPathResourceImplementation { - public URL[] getRoots() { - try { - return new URL[] {src1.getURL()}; - } catch (FileStateInvalidException x) { - throw new AssertionError(x); - } - } - public boolean includes(URL root, String resource) { - return resource.startsWith("incl"); - } - public ClassPathImplementation getContent() { - return null; - } - } - r.register(ClassPath.SOURCE, new ClassPath[] { - ClassPathSupport.createClassPath(Collections.singletonList(new PRI())), - ClassPathSupport.createClassPath(new FileObject[] {src2}) - }); - assertTrue(Arrays.asList(src1included, src2included).contains(r.findResource("included/file"))); - assertEquals(src2excluded1, r.findResource("excluded/file1")); - assertEquals(null, r.findResource("excluded/file2")); - assertEquals(null, r.findResource("nonexistent")); - } - - public void testMemoryLeak124055 () throws Exception { - final GlobalPathRegistry reg = GlobalPathRegistry.getDefault(); - final Set src = reg.getPaths(ClassPath.SOURCE); - final Set boot = reg.getPaths(ClassPath.BOOT); - final Set compile = reg.getPaths(ClassPath.COMPILE); - assertTrue(src.isEmpty()); - assertTrue(boot.isEmpty()); - assertTrue(compile.isEmpty()); - assertTrue(reg.getSourceRoots().isEmpty()); - r.register(ClassPath.COMPILE, new ClassPath[] {cp3}); - SFBQImpl query = Lookup.getDefault().lookup(SFBQImpl.class); - query.addPair(cp3.getRoots()[0].getURL(),cp4.getRoots()); - //There should be one translated source root - assertEquals(1, reg.getSourceRoots().size()); - assertEquals(1, reg.getResults().size()); - r.unregister(ClassPath.COMPILE, new ClassPath[] {cp3}); - //There shouldn't be registered source root - assertTrue(reg.getSourceRoots().isEmpty()); - assertTrue(reg.getResults().isEmpty()); - } - - private static final class L implements GlobalPathRegistryListener { - - private GlobalPathRegistryEvent e; - private boolean added; - - public L() {} - - public synchronized GlobalPathRegistryEvent event() { - GlobalPathRegistryEvent _e = e; - e = null; - return _e; - } - - public boolean added() { - return added; - } - - public synchronized void pathsAdded(GlobalPathRegistryEvent e) { - assertNull("checked for last event", this.e); - this.e = e; - added = true; - } - - public synchronized void pathsRemoved(GlobalPathRegistryEvent e) { - assertNull("checked for last event", this.e); - this.e = e; - added = false; - } - - } - - - public static class SFBQImpl implements SourceForBinaryQueryImplementation { - - private Map pairs = new HashMap (); - - void addPair (URL binaryRoot, FileObject[] sourceRoots) { - assert binaryRoot != null && sourceRoots != null; - Result r = (Result) this.pairs.get (binaryRoot); - if (r == null) { - r = new Result (sourceRoots); - this.pairs.put (binaryRoot, r); - } - else { - r.setSources(sourceRoots); - } - } - - public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) { - Result result = (Result) this.pairs.get (binaryRoot); - return result; - } - - - private static class Result implements SourceForBinaryQuery.Result { - - private FileObject[] sources; - private final ChangeSupport changeSupport = new ChangeSupport(this); - - public Result (FileObject[] sources) { - this.sources = sources; - } - - - void setSources (FileObject[] sources) { - this.sources = sources; - this.changeSupport.fireChange (); - } - - public void addChangeListener(javax.swing.event.ChangeListener l) { - changeSupport.addChangeListener (l); - } - - public FileObject[] getRoots() { - return this.sources; - } - - public void removeChangeListener(javax.swing.event.ChangeListener l) { - changeSupport.removeChangeListener (l); - } - - } - - } - - public static class DeadLockSFBQImpl extends Thread implements SourceForBinaryQueryImplementation { - - private Runnable r; - - public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) { - if (this.r != null) { - synchronized (this) { - this.start(); - try { - this.wait (); - } catch (InterruptedException ie) { - ie.printStackTrace(); - } - } - } - return null; - } - - public synchronized void run () { - r.run(); - this.notify(); - } - - public void setSynchronizedJob (Runnable r) { - this.r = r; - } - - } - -} diff --git a/api.java/test/unit/src/org/netbeans/modules/java/classpath/ProxyClassPathImplementationTest.java b/api.java/test/unit/src/org/netbeans/modules/java/classpath/ProxyClassPathImplementationTest.java deleted file mode 100644 --- a/api.java/test/unit/src/org/netbeans/modules/java/classpath/ProxyClassPathImplementationTest.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - */ -package org.netbeans.modules.java.classpath; - - -import java.net.URL; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.locks.ReentrantLock; -import junit.framework.TestCase; -import junit.framework.*; -import org.netbeans.api.java.classpath.ClassPath; -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.PathResourceImplementation; -import java.util.List; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Collections; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeEvent; -import org.netbeans.spi.java.classpath.support.ClassPathSupport; -import org.openide.util.WeakListeners; - -/** - * - * @author tom - */ -public class ProxyClassPathImplementationTest extends NbTestCase { - - public ProxyClassPathImplementationTest(String testName) { - super(testName); - } - - public void testResources () throws Exception { - final URL url1 = new URL ("file:///tmp/a/"); - final URL url2 = new URL ("file:///tmp/b/"); - final URL url3 = new URL ("file:///tmp/b/"); - - final ClassPath cp1 = ClassPathSupport.createClassPath(new URL[] {url1, url2}); - final ClassPath cp2 = ClassPathSupport.createClassPath(new URL[] {url3}); - final ClassPath prxCp = ClassPathSupport.createProxyClassPath(new ClassPath[] {cp1,cp2}); - List entries = prxCp.entries(); - assertEquals(3,entries.size()); - assertEquals(url1,entries.get(0).getURL()); - assertEquals(url2,entries.get(1).getURL()); - assertEquals(url3,entries.get(2).getURL()); - } - - public void testDeadLock() throws Exception{ - List resources = Collections.emptyList(); - final ReentrantLock lock = new ReentrantLock (false); - final CountDownLatch signal = new CountDownLatch (1); - final ClassPath cp = ClassPathFactory.createClassPath(ClassPathSupport.createProxyClassPathImplementation(new ClassPathImplementation[] {new LockClassPathImplementation (resources,lock, signal)})); - lock.lock(); - final ExecutorService es = Executors.newSingleThreadExecutor(); - try { - es.submit(new Runnable () { - public void run () { - cp.entries(); - } - }); - signal.await(); - cp.entries(); - } finally { - es.shutdownNow(); - } - } - - - private class LockClassPathImplementation implements ClassPathImplementation { - - private List resources; - private ReentrantLock lock; - private CountDownLatch signal; - - public LockClassPathImplementation (final List resources, final ReentrantLock lock, final CountDownLatch signal) { - this.resources = resources; - this.lock = lock; - this.signal = signal; - } - - public List getResources() { - this.signal.countDown(); - this.lock.lock(); - return this.resources; - } - - public void addPropertyChangeListener(PropertyChangeListener listener) { - } - - public void removePropertyChangeListener(PropertyChangeListener listener) { - } - - } - - -} diff --git a/nbbuild/cluster.properties b/nbbuild/cluster.properties --- a/nbbuild/cluster.properties +++ b/nbbuild/cluster.properties @@ -228,6 +228,7 @@ nb.cluster.ide.depends=nb.cluster.platform nb.cluster.ide=\ api.debugger,\ + api.java.classpath,\ api.xml,\ classfile,\ core.ide,\ diff --git a/nbbuild/javadoctools/links.xml b/nbbuild/javadoctools/links.xml --- a/nbbuild/javadoctools/links.xml +++ b/nbbuild/javadoctools/links.xml @@ -165,3 +165,4 @@ + diff --git a/nbbuild/javadoctools/properties.xml b/nbbuild/javadoctools/properties.xml --- a/nbbuild/javadoctools/properties.xml +++ b/nbbuild/javadoctools/properties.xml @@ -163,3 +163,4 @@ + diff --git a/nbbuild/javadoctools/replaces.xml b/nbbuild/javadoctools/replaces.xml --- a/nbbuild/javadoctools/replaces.xml +++ b/nbbuild/javadoctools/replaces.xml @@ -163,3 +163,4 @@ +