Index: core/settings/nbproject/project.xml =================================================================== RCS file: /shared/data/ccvs/repository/core/settings/nbproject/project.xml,v retrieving revision 1.16 retrieving revision 1.16.10.1 diff -u -r1.16 -r1.16.10.1 --- core/settings/nbproject/project.xml 3 Nov 2006 13:30:16 -0000 1.16 +++ core/settings/nbproject/project.xml 26 Mar 2007 12:00:15 -0000 1.16.10.1 @@ -75,7 +75,7 @@ - 7.3 + @@ -87,45 +87,50 @@ - - - unit - - org.netbeans.modules.settings - - - - - org.openide.actions - - - - org.netbeans.core.startup - - - - - org.netbeans.core.ui - - - - - org.openide.text - - - - org.netbeans.modules.progress.ui - - - - org.netbeans.modules.editor.mimelookup.impl - - - - - - qa-functional - + + + unit + + org.netbeans.core.startup + + + + + org.netbeans.core.ui + + + + + org.netbeans.modules.editor.mimelookup.impl + + + + + org.netbeans.modules.progress.ui + + + + org.netbeans.modules.settings + + + + + org.openide.actions + + + + org.openide.text + + + + org.openide.util + + + + + + qa-functional + org.netbeans.spi.settings Index: core/settings/src/META-INF/services/org.netbeans.modules.openide.util.NamedServicesProvider =================================================================== RCS file: core/settings/src/META-INF/services/org.netbeans.modules.openide.util.NamedServicesProvider diff -N core/settings/src/META-INF/services/org.netbeans.modules.openide.util.NamedServicesProvider --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core/settings/src/META-INF/services/org.netbeans.modules.openide.util.NamedServicesProvider 26 Mar 2007 12:00:16 -0000 1.1.2.1 @@ -0,0 +1,4 @@ +org.netbeans.modules.settings.RecognizeInstanceObjects +#position=200 +#-org.netbeans.modules.startup.layers.RecognizeInstanceFiles + Index: core/settings/src/org/netbeans/modules/settings/RecognizeInstanceObjects.java =================================================================== RCS file: core/settings/src/org/netbeans/modules/settings/RecognizeInstanceObjects.java diff -N core/settings/src/org/netbeans/modules/settings/RecognizeInstanceObjects.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core/settings/src/org/netbeans/modules/settings/RecognizeInstanceObjects.java 26 Mar 2007 12:00:14 -0000 1.1.2.1 @@ -0,0 +1,91 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (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.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. + * + * Portions Copyrighted 2007 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.settings; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.logging.Logger; +import org.netbeans.modules.openide.util.NamedServicesProvider; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.filesystems.FileUtil; +import org.openide.filesystems.Repository; +import org.openide.loaders.DataFolder; +import org.openide.loaders.FolderLookup; +import org.openide.util.Lookup; +import org.openide.util.LookupEvent; +import org.openide.util.LookupListener; +import org.openide.util.WeakListeners; +import org.openide.util.lookup.Lookups; +import org.openide.util.lookup.ProxyLookup; + +/** Use FolderLookup to find out intances of named services. + * + * @author Jaroslav Tulach + */ +public final class RecognizeInstanceObjects extends NamedServicesProvider { + private static final Logger LOG = Logger.getLogger(RecognizeInstanceObjects.class.getName()); + + + public Lookup create(String path) { + return new OverObjects(path); + } + + + private static final class OverObjects extends ProxyLookup + implements LookupListener { + private static Lookup.Result CL = Lookup.getDefault().lookupResult(ClassLoader.class); + + private final String path; + + public OverObjects(String path) { + super(delegates(path)); + this.path = path; + CL.addLookupListener(WeakListeners.create(LookupListener.class, this, CL)); + } + + @SuppressWarnings("deprecation") + private static Lookup[] delegates(String path) { + Collection allCL = CL.allInstances(); + ClassLoader ccl = Thread.currentThread().getContextClassLoader(); + if (ccl != null) { + allCL = Collections.singleton(ccl); + } else { + if (allCL.isEmpty()) { + allCL = Collections.singleton(RecognizeInstanceObjects.class.getClassLoader()); + } + } + try { + FileObject fo = FileUtil.createFolder(Repository.getDefault().getDefaultFileSystem().getRoot(), path); + FolderLookup l = new FolderLookup(DataFolder.findFolder(fo)); + return new Lookup[] { l.getLookup(), Lookups.metaInfServices(allCL.iterator().next(), "META-INF/namedservices/" + path) }; // NOI18N + } catch (IOException ex) { + return new Lookup[] { Lookups.metaInfServices(allCL.iterator().next(), "META-INF/namedservices/" + path) }; // NOI18N + } + + } + + public void resultChanged(LookupEvent ev) { + setLookups(delegates(path)); + } + } // end of OverObjects +} Index: core/settings/test/unit/src/org/netbeans/modules/settings/RecognizeInstanceObjectsTest.java =================================================================== RCS file: core/settings/test/unit/src/org/netbeans/modules/settings/RecognizeInstanceObjectsTest.java diff -N core/settings/test/unit/src/org/netbeans/modules/settings/RecognizeInstanceObjectsTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core/settings/test/unit/src/org/netbeans/modules/settings/RecognizeInstanceObjectsTest.java 26 Mar 2007 12:00:12 -0000 1.1.2.1 @@ -0,0 +1,32 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (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.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * 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. + */ + +package org.netbeans.modules.settings; + +import org.netbeans.core.startup.layers.NamedFSServicesLookupTest; + + +/** Test finding services from manifest and .instance files using FolderLookup. + * @author Jaroslav Tulach + */ +public class RecognizeInstanceObjectsTest extends NamedFSServicesLookupTest{ + public RecognizeInstanceObjectsTest(String name) { + super(name); + } +} Index: core/startup/nbproject/project.xml =================================================================== RCS file: /shared/data/ccvs/repository/core/startup/nbproject/project.xml,v retrieving revision 1.12 retrieving revision 1.12.14.1 diff -u -r1.12 -r1.12.14.1 --- core/startup/nbproject/project.xml 11 Oct 2006 13:05:57 -0000 1.12 +++ core/startup/nbproject/project.xml 26 Mar 2007 12:00:12 -0000 1.12.14.1 @@ -70,6 +70,11 @@ + + org.openide.util + + + qa-functional Index: core/startup/src/META-INF/services/org.netbeans.modules.openide.util.NamedServicesProvider =================================================================== RCS file: core/startup/src/META-INF/services/org.netbeans.modules.openide.util.NamedServicesProvider diff -N core/startup/src/META-INF/services/org.netbeans.modules.openide.util.NamedServicesProvider --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core/startup/src/META-INF/services/org.netbeans.modules.openide.util.NamedServicesProvider 26 Mar 2007 12:00:14 -0000 1.1.2.1 @@ -0,0 +1,2 @@ +org.netbeans.core.startup.layers.RecognizeInstanceFiles +#position=500 Index: core/startup/src/org/netbeans/core/startup/layers/RecognizeInstanceFiles.java =================================================================== RCS file: core/startup/src/org/netbeans/core/startup/layers/RecognizeInstanceFiles.java diff -N core/startup/src/org/netbeans/core/startup/layers/RecognizeInstanceFiles.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core/startup/src/org/netbeans/core/startup/layers/RecognizeInstanceFiles.java 26 Mar 2007 12:00:16 -0000 1.1.2.1 @@ -0,0 +1,265 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (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.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. + * + * Portions Copyrighted 2007 Sun Microsystems, Inc. + */ + +package org.netbeans.core.startup.layers; + +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.netbeans.modules.openide.util.NamedServicesProvider; +import org.openide.filesystems.FileAttributeEvent; +import org.openide.filesystems.FileChangeListener; +import org.openide.filesystems.FileEvent; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileRenameEvent; +import org.openide.filesystems.FileStateInvalidException; +import org.openide.filesystems.FileSystem; +import org.openide.filesystems.FileUtil; +import org.openide.filesystems.FileUtil; +import org.openide.filesystems.Repository; +import org.openide.util.Lookup; +import org.openide.util.Utilities; +import org.openide.util.lookup.AbstractLookup; +import org.openide.util.lookup.Lookups; +import org.openide.util.lookup.ProxyLookup; + +/** Interface for core/startup to provide lookup overt system filesystem. + * + * @author Jaroslav Tulach + */ +public final class RecognizeInstanceFiles extends NamedServicesProvider { + private static final Logger LOG = Logger.getLogger(RecognizeInstanceFiles.class.getName()); + + + public Lookup create(String path) { + return new OverFiles(path); + } + + + private static final class OverFiles extends ProxyLookup + implements FileChangeListener { + private final String path; + private final FileChangeListener weakL; + private final AbstractLookup.Content content; + private final AbstractLookup lkp; + + public OverFiles(String path) { + this(path, new ArrayList(), new AbstractLookup.Content()); + } + + private OverFiles(String path, List items, AbstractLookup.Content cnt) { + this(path, items, new AbstractLookup(cnt), cnt); + } + + private OverFiles(String path, List items, AbstractLookup lkp, AbstractLookup.Content cnt) { + super(computeDelegates(path, items, lkp)); + this.path = path; + this.lkp = lkp; + this.content = cnt; + this.content.setPairs(items); + + FileSystem fs = Repository.getDefault().getDefaultFileSystem(); + this.weakL = FileUtil.weakFileChangeListener(this, fs); + fs.addFileChangeListener(weakL); + } + + private void refresh() { + List items = new ArrayList(); + Lookup[] delegates = computeDelegates(path, items, lkp); + + this.content.setPairs(items); + this.setLookups(delegates); + } + + private static Lookup[] computeDelegates(String p, List items, Lookup lkp) { + FileObject fo = Repository.getDefault().getDefaultFileSystem().findResource(p); + List delegates = new LinkedList(); + delegates.add(lkp); + if (fo != null) { + for (FileObject f : fo.getChildren()) { + if (f.isFolder()) { + delegates.add(new OverFiles(f.getPath())); + } else { + items.add(new FOItem(f)); + } + } + + } + delegates.add( + Lookups.metaInfServices(Thread.currentThread().getContextClassLoader(), "META-INF/namedservices/" + p) // NOI18N + ); + return delegates.toArray(new Lookup[0]); + } + + public void fileFolderCreated(FileEvent fe) { + refresh(); + } + + public void fileDataCreated(FileEvent fe) { + refresh(); + } + + public void fileChanged(FileEvent fe) { + refresh(); + } + + public void fileDeleted(FileEvent fe) { + refresh(); + } + + public void fileRenamed(FileRenameEvent fe) { + refresh(); + } + + public void fileAttributeChanged(FileAttributeEvent fe) { + refresh(); + } + } // end of OverFiles + + + private static final class FOItem extends AbstractLookup.Pair { + private static Reference EMPTY = new WeakReference(null); + private FileObject fo; + private Reference ref = EMPTY; + + public FOItem(FileObject fo) { + this.fo = fo; + } + + protected boolean instanceOf(Class c) { + Object r = ref.get(); + if (r != null) { + return c.isInstance(r); + } else { + return c.isAssignableFrom(getType()); + } + } + + protected boolean creatorOf(Object obj) { + return ref.get() == obj; + } + + public synchronized Object getInstance() { + Object r = ref.get(); + if (r == null) { + r = fo.getAttribute("instanceCreate"); + if (r != null) { + ref = new WeakReference(r); + } + } + return r; + } + + public Class getType() { + ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class); + if (l == null) { + l = FOItem.class.getClassLoader(); + } + try { + return Class.forName(getClassName(fo), false, l); + } catch (ClassNotFoundException ex) { + LOG.log(Level.INFO, ex.getMessage(), ex); + return Object.class; + } + } + + public String getId() { + return fo.getPath(); + } + + public String getDisplayName() { + String n = fo.getName(); + try { + n = fo.getFileSystem().getStatus().annotateName(n, Collections.singleton(fo)); + } catch (FileStateInvalidException ex) { + LOG.log(Level.WARNING, ex.getMessage(), ex); + } + return n; + } + + /** get class name from specified file object*/ + private static String getClassName(FileObject fo) { + // first of all try "instanceClass" property of the primary file + Object attr = fo.getAttribute ("instanceClass"); + if (attr instanceof String) { + return Utilities.translate((String) attr); + } else if (attr != null) { + LOG.warning( + "instanceClass was a " + attr.getClass().getName()); // NOI18N + } + + attr = fo.getAttribute("instanceCreate"); + if (attr != null) { + return attr.getClass().getName(); + } + + // otherwise extract the name from the filename + String name = fo.getName (); + + int first = name.indexOf('[') + 1; + if (first != 0) { + LOG.log(Level.WARNING, "Cannot understand {0}", fo); + } + + int last = name.indexOf (']'); + if (last < 0) { + last = name.length (); + } + + // take only a part of the string + if (first < last) { + name = name.substring (first, last); + } + + name = name.replace ('-', '.'); + name = Utilities.translate(name); + + //System.out.println ("Original: " + getPrimaryFile ().getName () + " new one: " + name); // NOI18N + return name; + } + + public boolean equals(Object obj) { + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final FOItem other = (FOItem) obj; + + if (this.fo != other.fo && + (this.fo == null || !this.fo.equals(other.fo))) + return false; + return true; + } + + public int hashCode() { + int hash = 3; + + hash = 11 * hash + (this.fo != null ? this.fo.hashCode() + : 0); + return hash; + } + + } // end of FOItem +} Index: core/startup/test/unit/src/org/netbeans/core/startup/layers/NamedFSServicesLookupTest.java =================================================================== RCS file: core/startup/test/unit/src/org/netbeans/core/startup/layers/NamedFSServicesLookupTest.java diff -N core/startup/test/unit/src/org/netbeans/core/startup/layers/NamedFSServicesLookupTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core/startup/test/unit/src/org/netbeans/core/startup/layers/NamedFSServicesLookupTest.java 26 Mar 2007 12:00:11 -0000 1.1.2.1 @@ -0,0 +1,71 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (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.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * 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. + */ + +package org.netbeans.core.startup.layers; + +import org.netbeans.core.startup.MainLookup; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.filesystems.Repository; +import org.openide.modules.ModuleInfo; +import org.openide.util.Lookup; +import org.openide.util.lookup.Lookups; +import org.openide.util.lookup.NamedServicesLookupTest; + + +/** Test finding services from manifest and .instance files. + * @author Jaroslav Tulach + */ +public class NamedFSServicesLookupTest extends NamedServicesLookupTest{ + private FileObject root; + + public NamedFSServicesLookupTest(String name) { + super(name); + } + + @Override + protected void setUp() throws Exception { + Lookup.getDefault().lookup(ModuleInfo.class); + assertEquals(MainLookup.class, Lookup.getDefault().getClass()); + + root = Repository.getDefault().getDefaultFileSystem().getRoot(); + + super.setUp(); + } + + public void testLoadFromTheSFS() throws Exception { + doLoad("inst/sub"); + } + public void testLoadFromSubdirTheSFS() throws Exception { + doLoad("inst"); + } + + private void doLoad(String lkpName) throws Exception { + FileObject inst = FileUtil.createData(root, "inst/sub/X.instance"); + inst.setAttribute("instanceCreate", Long.valueOf(1000)); + + Lookup l = Lookups.namedServices(lkpName); + Long lng = l.lookup(Long.class); + assertNotNull("A value found", lng); + + inst.delete(); + + assertNull("Now it is null", l.lookup(Long.class)); + } +} Index: openide/loaders/src/org/openide/loaders/FolderLookup.java =================================================================== RCS file: /shared/data/ccvs/repository/openide/loaders/src/org/openide/loaders/FolderLookup.java,v retrieving revision 1.22 retrieving revision 1.22.8.1 diff -u -r1.22 -r1.22.8.1 --- openide/loaders/src/org/openide/loaders/FolderLookup.java 13 Jan 2007 14:49:19 -0000 1.22 +++ openide/loaders/src/org/openide/loaders/FolderLookup.java 26 Mar 2007 12:00:17 -0000 1.22.8.1 @@ -38,7 +38,9 @@ * in the lookup system easily. * @author Jaroslav Tulach * @since 1.11 + * @deprecated use {@link Lookup#namedService} instead. */ +@Deprecated public class FolderLookup extends FolderInstance { /** Lock for initiliazation of lookup. */ Index: openide/util/nbproject/project.properties =================================================================== RCS file: /shared/data/ccvs/repository/openide/util/nbproject/project.properties,v retrieving revision 1.25 retrieving revision 1.25.10.1 diff -u -r1.25 -r1.25.10.1 --- openide/util/nbproject/project.properties 11 Jan 2007 14:08:22 -0000 1.25 +++ openide/util/nbproject/project.properties 26 Mar 2007 12:00:10 -0000 1.25.10.1 @@ -19,7 +19,7 @@ javac.source=1.5 module.jar.dir=lib -spec.version.base=7.7.0 +spec.version.base=7.8.0 # For XMLSerializer, needed for XMLUtil.write to work w/ namespaces under JDK 1.4: Index: openide/util/src/org/netbeans/modules/openide/util/NamedServicesProvider.java =================================================================== RCS file: openide/util/src/org/netbeans/modules/openide/util/NamedServicesProvider.java diff -N openide/util/src/org/netbeans/modules/openide/util/NamedServicesProvider.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openide/util/src/org/netbeans/modules/openide/util/NamedServicesProvider.java 26 Mar 2007 12:00:15 -0000 1.1.2.1 @@ -0,0 +1,69 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (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.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. + * + * Portions Copyrighted 2006 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.openide.util; + +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.Map; +import org.openide.util.Lookup; +import org.openide.util.Lookup; +import org.openide.util.lookup.Lookups; + +/** Interface for core/startup to provide lookup overt system filesystem. + * + * @author Jaroslav Tulach + */ +public abstract class NamedServicesProvider { + private static volatile Map> map = new HashMap>(); + + + public abstract Lookup create(String path); + + public static synchronized Lookup find(String path) { + if (!path.endsWith("/")) { + path = path + "/"; + } + + Reference ref = map.get(path); + Lookup lkp = ref == null ? null : ref.get(); + if (lkp != null) { + return lkp; + } + NamedServicesProvider prov = Lookup.getDefault().lookup(NamedServicesProvider.class); + if (prov != null) { + lkp = prov.create(path); + } else { + ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class); + if (l == null) { + l = Thread.currentThread().getContextClassLoader(); + if (l == null) { + l = NamedServicesProvider.class.getClassLoader(); + } + } + lkp = Lookups.metaInfServices(l, "META-INF/namedservices/" + path); + } + + map.put(path, new WeakReference(lkp)); + return lkp; + } + +} Index: openide/util/src/org/openide/util/lookup/Lookups.java =================================================================== RCS file: /shared/data/ccvs/repository/openide/util/src/org/openide/util/lookup/Lookups.java,v retrieving revision 1.7 retrieving revision 1.7.12.1 diff -u -r1.7 -r1.7.12.1 --- openide/util/src/org/openide/util/lookup/Lookups.java 1 Nov 2006 11:16:42 -0000 1.7 +++ openide/util/src/org/openide/util/lookup/Lookups.java 26 Mar 2007 12:00:11 -0000 1.7.12.1 @@ -21,6 +21,7 @@ import java.util.Arrays; import java.util.Collections; +import org.netbeans.modules.openide.util.NamedServicesProvider; import org.openide.util.Lookup; /** @@ -134,9 +135,38 @@ * @since 3.35 */ public static Lookup metaInfServices(ClassLoader classLoader) { - return new MetaInfServicesLookup(classLoader); + return new MetaInfServicesLookup(classLoader, "META-INF/services/"); // NOI18N } + /** Returns a lookup that behaves exactly as the one + * created metaInfServices(ClassLoader) except that + * it does not read data from META-INF/services, but instead + * from the specified prefix. + * @param classLoader class loader to use for loading + * @param prefix prefix to prepend to the class name when searching + * @since JST-PENDING + */ + public static Lookup metaInfServices(ClassLoader classLoader, String prefix) { + return new MetaInfServicesLookup(classLoader, prefix); + } + + /** Creates a named lookup. It is a lookup identified by a + * given path. Two lookups with the same path are going to have + * the same content. It is expected that each named lookup + * will contain a superset of what would lookup created by + * metaInfServices(theRightLoader, "META-INF/namedservices/" + path) + * contain. However various environments can add their own + * extensions to its content. For example when running inside NetBeans Runtime + * Container, the content of system file system under the given + * path is also present in the returned lookup. + * + * @param path the path identifying the lookup, for example Databases/, etc. + * @since JST-PENDING + */ + public static Lookup namedServices(String path) { + return NamedServicesProvider.find(path); + } + /** Creates a lookup that wraps another one and filters out instances * of specified classes. If you have a lookup and * you want to remove all instances of ActionMap you can use: Index: openide/util/src/org/openide/util/lookup/MetaInfServicesLookup.java =================================================================== RCS file: /shared/data/ccvs/repository/openide/util/src/org/openide/util/lookup/MetaInfServicesLookup.java,v retrieving revision 1.6 retrieving revision 1.6.14.1 diff -u -r1.6 -r1.6.14.1 --- openide/util/src/org/openide/util/lookup/MetaInfServicesLookup.java 3 Oct 2006 23:28:43 -0000 1.6 +++ openide/util/src/org/openide/util/lookup/MetaInfServicesLookup.java 26 Mar 2007 12:00:11 -0000 1.6.14.1 @@ -68,18 +68,14 @@ /** class loader to use */ private final ClassLoader loader; - - /** Create a lookup reading from the classpath. - * That is, the same classloader as this class itself. - */ - public MetaInfServicesLookup() { - this(MetaInfServicesLookup.class.getClassLoader()); - } + /** prefix to prepend */ + private final String prefix; /** Create a lookup reading from a specified classloader. */ - public MetaInfServicesLookup(ClassLoader loader) { + public MetaInfServicesLookup(ClassLoader loader, String prefix) { this.loader = loader; + this.prefix = prefix; LOGGER.log(Level.FINE, "Created: {0}", this); } @@ -123,7 +119,7 @@ LOGGER.log(Level.FINER, "Searching for " + clazz.getName() + " in " + clazz.getClassLoader() + " from " + this); } - String res = "META-INF/services/" + clazz.getName(); // NOI18N + String res = prefix + clazz.getName(); // NOI18N Enumeration en; try { Index: openide/util/test/unit/src/org/openide/util/lookup/MetaInfServicesLookupTest.java =================================================================== RCS file: /shared/data/ccvs/repository/openide/util/test/unit/src/org/openide/util/lookup/MetaInfServicesLookupTest.java,v retrieving revision 1.3 retrieving revision 1.3.10.1 diff -u -r1.3 -r1.3.10.1 --- openide/util/test/unit/src/org/openide/util/lookup/MetaInfServicesLookupTest.java 1 Jan 2007 13:24:33 -0000 1.3 +++ openide/util/test/unit/src/org/openide/util/lookup/MetaInfServicesLookupTest.java 26 Mar 2007 12:00:13 -0000 1.3.10.1 @@ -24,12 +24,17 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +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.Collections; import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.Set; import java.util.TreeSet; @@ -44,26 +49,41 @@ import org.openide.util.LookupEvent; import org.openide.util.LookupListener; import org.openide.util.RequestProcessor; +import org.openide.util.WeakSet; /** Test finding services from manifest. * @author Jesse Glick */ public class MetaInfServicesLookupTest extends NbTestCase { private Logger LOG; + private Map lookups = new HashMap(); public MetaInfServicesLookupTest(String name) { super(name); LOG = Logger.getLogger("Test." + name); } - private String prefix() { + protected String prefix() { return "META-INF/services/"; } + protected Lookup createLookup(ClassLoader c) { + return Lookups.metaInfServices(c); + } + protected Level logLevel() { return Level.INFO; } + private Lookup getTestedLookup(ClassLoader c) { + Lookup l = lookups.get(c); + if (l == null) { + l = createLookup(c); + lookups.put(c, l); + } + return l; + } + private URL findJar(String n) throws IOException { LOG.info("Looking for " + n); File jarDir = new File(getWorkDir(), "jars"); @@ -154,8 +174,21 @@ }, c0); } + protected void tearDown() throws Exception { + Set> weak = new HashSet>(); + for (Lookup l : lookups.values()) { + weak.add(new WeakReference(l)); + } + + lookups = null; + + for(Reference ref : weak) { + assertGC("Lookup can disappear", ref); + } + } + public void testBasicUsage() throws Exception { - Lookup l = Lookups.metaInfServices(c2); + Lookup l = getTestedLookup(c2); Class xface = c1.loadClass("org.foo.Interface"); List results = new ArrayList(l.lookup(new Lookup.Template(xface)).allInstances()); assertEquals(2, results.size()); @@ -169,11 +202,11 @@ public void testLoaderSkew() throws Exception { Class xface1 = c1.loadClass("org.foo.Interface"); - Lookup l3 = Lookups.metaInfServices(c3); + Lookup l3 = getTestedLookup(c3); // If we cannot load Interface, there should be no impls of course... quietly! assertEquals(Collections.EMPTY_LIST, new ArrayList(l3.lookup(new Lookup.Template(xface1)).allInstances())); - Lookup l4 = Lookups.metaInfServices(c4); + Lookup l4 = getTestedLookup(c4); // If we can load Interface but it is the wrong one, ignore it. assertEquals(Collections.EMPTY_LIST, new ArrayList(l4.lookup(new Lookup.Template(xface1)).allInstances())); @@ -183,18 +216,18 @@ } public void testStability() throws Exception { - Lookup l = Lookups.metaInfServices(c2); + Lookup l = getTestedLookup(c2); Class xface = c1.loadClass("org.foo.Interface"); Object first = l.lookup(new Lookup.Template(xface)).allInstances().iterator().next(); - l = Lookups.metaInfServices(c2a); + l = getTestedLookup(c2a); Object second = l.lookup(new Lookup.Template(xface)).allInstances().iterator().next(); assertEquals(first, second); } public void testMaskingOfResources() throws Exception { - Lookup l1 = Lookups.metaInfServices(c1); - Lookup l2 = Lookups.metaInfServices(c2); - Lookup l4 = Lookups.metaInfServices(c4); + Lookup l1 = getTestedLookup(c1); + Lookup l2 = getTestedLookup(c2); + Lookup l4 = getTestedLookup(c4); assertNotNull("services1.jar defines a class that implements runnable", l1.lookup(Runnable.class)); assertNull("services2.jar does not defines a class that implements runnable", l2.lookup(Runnable.class)); @@ -202,12 +235,12 @@ } public void testOrdering() throws Exception { - Lookup l = Lookups.metaInfServices(c1); + Lookup l = getTestedLookup(c1); Class xface = c1.loadClass("java.util.Comparator"); List results = new ArrayList(l.lookup(new Lookup.Template(xface)).allInstances()); assertEquals(1, results.size()); - l = Lookups.metaInfServices(c2); + l = getTestedLookup(c2); xface = c2.loadClass("java.util.Comparator"); results = new ArrayList(l.lookup(new Lookup.Template(xface)).allInstances()); assertEquals(2, results.size()); @@ -216,7 +249,7 @@ assertEquals("org.foo.impl.Comparator1", results.get(1).getClass().getName()); // test that items without position are always at the end - l = Lookups.metaInfServices(c2); + l = getTestedLookup(c2); xface = c2.loadClass("java.util.Iterator"); results = new ArrayList(l.lookup(new Lookup.Template(xface)).allInstances()); assertEquals(2, results.size()); @@ -251,7 +284,7 @@ } } Loader loader = new Loader(); - Lookup l = Lookups.metaInfServices(loader); + Lookup l = getTestedLookup(loader); Object no = l.lookup(String.class); assertNull("Not found of course", no); @@ -259,7 +292,7 @@ } public void testListenersAreNotifiedWithoutHoldingALockIssue36035() throws Exception { - final Lookup l = Lookups.metaInfServices(c2); + final Lookup l = getTestedLookup(c2); final Class xface = c1.loadClass("org.foo.Interface"); final Lookup.Result res = l.lookup(new Lookup.Template(Object.class)); Index: openide/util/test/unit/src/org/openide/util/lookup/NamedServicesLookupTest.java =================================================================== RCS file: openide/util/test/unit/src/org/openide/util/lookup/NamedServicesLookupTest.java diff -N openide/util/test/unit/src/org/openide/util/lookup/NamedServicesLookupTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openide/util/test/unit/src/org/openide/util/lookup/NamedServicesLookupTest.java 26 Mar 2007 12:00:13 -0000 1.1.2.1 @@ -0,0 +1,70 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (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.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * 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. + */ + +package org.openide.util.lookup; + +import org.openide.util.Lookup; + + +/** Test finding services from manifest. + * @author Jaroslav Tulach + */ +public class NamedServicesLookupTest extends MetaInfServicesLookupTest { + public NamedServicesLookupTest(String name) { + super(name); + } + + protected String prefix() { + return "META-INF/namedservices/sub/path/"; + } + + protected Lookup createLookup(ClassLoader c) { + ClassLoader prev = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(c); + Lookup l = Lookups.namedServices("sub/path"); + Thread.currentThread().setContextClassLoader(prev); + return l; + } + + // + // this is not much inheriting test, as we mask most of the tested methods + // anyway, but the infrastructure to generate the JAR files is useful + // + + public void testLoaderSkew() throws Exception { + } + + public void testStability() throws Exception { + } + + public void testMaskingOfResources() throws Exception { + } + + public void testOrdering() throws Exception { + } + + public void testNoCallToGetResourceForObjectIssue65124() throws Exception { + } + + public void testListenersAreNotifiedWithoutHoldingALockIssue36035() throws Exception { + } + + + +} Index: openide/util/test/unit/src/org/openide/util/lookup/PrefixServicesLookupTest.java =================================================================== RCS file: openide/util/test/unit/src/org/openide/util/lookup/PrefixServicesLookupTest.java diff -N openide/util/test/unit/src/org/openide/util/lookup/PrefixServicesLookupTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openide/util/test/unit/src/org/openide/util/lookup/PrefixServicesLookupTest.java 26 Mar 2007 12:00:13 -0000 1.1.2.1 @@ -0,0 +1,41 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (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.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * 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. + */ + +package org.openide.util.lookup; + +import org.openide.util.Lookup; + + +/** Test finding services from manifest. + * @author Jaroslav Tulach + */ +public class PrefixServicesLookupTest extends MetaInfServicesLookupTest { + public PrefixServicesLookupTest(String name) { + super(name); + } + + protected String prefix() { + return "META-INF/netbeans/prefix/services/test/"; + } + + protected Lookup createLookup(ClassLoader c) { + return Lookups.metaInfServices(c, prefix()); + } + +}