# This patch file was generated by NetBeans IDE # Following Index: paths are relative to: /doma/jarda/netbeans-src/openide/util # This patch can be applied using context Tools: Patch action on respective folder. # It uses platform neutral UTF-8 encoding and \n newlines. # Above lines and this line are ignored by the patching process. Index: src/org/openide/util/lookup/MetaInfServicesLookup.java *** /doma/jarda/netbeans-src/openide/util/src/org/openide/util/lookup/MetaInfServicesLookup.java Base (1.6) --- /doma/jarda/netbeans-src/openide/util/src/org/openide/util/lookup/MetaInfServicesLookup.java Locally Modified (Based On 1.6) *************** *** 68,88 **** /** 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()); - } - /** Create a lookup reading from a specified classloader. */ ! public MetaInfServicesLookup(ClassLoader loader) { this.loader = loader; LOGGER.log(Level.FINE, "Created: {0}", this); --- 68,81 ---- /** class loader to use */ private final ClassLoader loader; + /** prefix to prepend */ + private final String prefix; /** Create a lookup reading from a specified classloader. */ ! public MetaInfServicesLookup(ClassLoader loader, String prefix) { this.loader = loader; + this.prefix = prefix; LOGGER.log(Level.FINE, "Created: {0}", this); } *************** *** 123,129 **** LOGGER.log(Level.FINER, "Searching for " + clazz.getName() + " in " + clazz.getClassLoader() + " from " + this); } ! String res = "META-INF/services/" + clazz.getName(); // NOI18N Enumeration en; try { --- 119,125 ---- LOGGER.log(Level.FINER, "Searching for " + clazz.getName() + " in " + clazz.getClassLoader() + " from " + this); } ! String res = prefix + clazz.getName(); // NOI18N Enumeration en; try { Index: src/org/netbeans/modules/openide/util/NamedServicesProvider.java *** /doma/jarda/netbeans-src/openide/util/src/org/netbeans/modules/openide/util/NamedServicesProvider.java No Base Revision --- /doma/jarda/netbeans-src/openide/util/src/org/netbeans/modules/openide/util/NamedServicesProvider.java Locally New *************** *** 1,0 **** --- 1,66 ---- + /* + * 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 = NamedServicesProvider.class.getClassLoader(); + } + lkp = Lookups.metaInfServices(l, "META-INF/namedservices/" + path); + } + + map.put(path, new WeakReference(lkp)); + return lkp; + } + + } Index: src/org/openide/util/lookup/Lookups.java *** /doma/jarda/netbeans-src/openide/util/src/org/openide/util/lookup/Lookups.java Base (1.7) --- /doma/jarda/netbeans-src/openide/util/src/org/openide/util/lookup/Lookups.java Locally Modified (Based On 1.7) *************** *** 21,26 **** --- 21,27 ---- import java.util.Arrays; import java.util.Collections; + import org.netbeans.modules.openide.util.NamedServicesProvider; import org.openide.util.Lookup; /** *************** *** 134,145 **** * @since 3.35 */ public static Lookup metaInfServices(ClassLoader classLoader) { ! return new MetaInfServicesLookup(classLoader); } /** Creates a lookup that wraps another one and filters out instances * of specified classes. If you have a lookup and --- 135,172 ---- * @since 3.35 */ public static Lookup metaInfServices(ClassLoader 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: test/unit/src/org/openide/util/lookup/MetaInfServicesLookupTest.java *** /doma/jarda/netbeans-src/openide/util/test/unit/src/org/openide/util/lookup/MetaInfServicesLookupTest.java Base (1.3) --- /doma/jarda/netbeans-src/openide/util/test/unit/src/org/openide/util/lookup/MetaInfServicesLookupTest.java Locally Modified (Based On 1.3) *************** *** 24,35 **** --- 24,40 ---- 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,55 **** --- 49,62 ---- 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); *************** *** 56,72 **** LOG = Logger.getLogger("Test." + name); } ! private String prefix() { return "META-INF/services/"; } protected Level logLevel() { return Level.INFO; } private URL findJar(String n) throws IOException { LOG.info("Looking for " + n); --- 63,89 ---- LOG = Logger.getLogger("Test." + name); } ! 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,161 **** }, c0); } public void testBasicUsage() throws Exception { ! Lookup l = Lookups.metaInfServices(c2); Class xface = c1.loadClass("org.foo.Interface"); List results = new ArrayList(l.lookup(new Lookup.Template(xface)).allInstances()); assertEquals(2, results.size()); --- 174,194 ---- }, 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 = 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,179 **** public void testLoaderSkew() throws Exception { Class xface1 = c1.loadClass("org.foo.Interface"); ! Lookup l3 = Lookups.metaInfServices(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); // 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())); --- 202,212 ---- public void testLoaderSkew() throws Exception { Class xface1 = c1.loadClass("org.foo.Interface"); ! 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 = 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,200 **** } public void testStability() throws Exception { ! Lookup l = Lookups.metaInfServices(c2); Class xface = c1.loadClass("org.foo.Interface"); Object first = l.lookup(new Lookup.Template(xface)).allInstances().iterator().next(); ! l = Lookups.metaInfServices(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); 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)); --- 216,233 ---- } public void testStability() throws Exception { ! Lookup l = getTestedLookup(c2); Class xface = c1.loadClass("org.foo.Interface"); Object first = l.lookup(new Lookup.Template(xface)).allInstances().iterator().next(); ! l = getTestedLookup(c2a); Object second = l.lookup(new Lookup.Template(xface)).allInstances().iterator().next(); assertEquals(first, second); } public void testMaskingOfResources() throws Exception { ! 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,213 **** } public void testOrdering() throws Exception { ! Lookup l = Lookups.metaInfServices(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); xface = c2.loadClass("java.util.Comparator"); results = new ArrayList(l.lookup(new Lookup.Template(xface)).allInstances()); assertEquals(2, results.size()); --- 235,246 ---- } public void testOrdering() throws Exception { ! 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 = getTestedLookup(c2); xface = c2.loadClass("java.util.Comparator"); results = new ArrayList(l.lookup(new Lookup.Template(xface)).allInstances()); assertEquals(2, results.size()); *************** *** 216,222 **** assertEquals("org.foo.impl.Comparator1", results.get(1).getClass().getName()); // test that items without position are always at the end ! l = Lookups.metaInfServices(c2); xface = c2.loadClass("java.util.Iterator"); results = new ArrayList(l.lookup(new Lookup.Template(xface)).allInstances()); assertEquals(2, results.size()); --- 249,255 ---- assertEquals("org.foo.impl.Comparator1", results.get(1).getClass().getName()); // test that items without position are always at the end ! l = getTestedLookup(c2); xface = c2.loadClass("java.util.Iterator"); results = new ArrayList(l.lookup(new Lookup.Template(xface)).allInstances()); assertEquals(2, results.size()); *************** *** 251,257 **** } } Loader loader = new Loader(); ! Lookup l = Lookups.metaInfServices(loader); Object no = l.lookup(String.class); assertNull("Not found of course", no); --- 284,290 ---- } } Loader loader = new Loader(); ! Lookup l = getTestedLookup(loader); Object no = l.lookup(String.class); assertNull("Not found of course", no); *************** *** 259,265 **** } public void testListenersAreNotifiedWithoutHoldingALockIssue36035() throws Exception { ! final Lookup l = Lookups.metaInfServices(c2); final Class xface = c1.loadClass("org.foo.Interface"); final Lookup.Result res = l.lookup(new Lookup.Template(Object.class)); --- 292,298 ---- } public void testListenersAreNotifiedWithoutHoldingALockIssue36035() throws Exception { ! 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: test/unit/src/org/openide/util/lookup/PrefixServicesLookupTest.java *** /doma/jarda/netbeans-src/openide/util/test/unit/src/org/openide/util/lookup/PrefixServicesLookupTest.java No Base Revision --- /doma/jarda/netbeans-src/openide/util/test/unit/src/org/openide/util/lookup/PrefixServicesLookupTest.java Locally New *************** *** 1,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()); + } + + } Index: test/unit/src/org/openide/util/lookup/NamedServicesLookupTest.java *** /doma/jarda/netbeans-src/openide/util/test/unit/src/org/openide/util/lookup/NamedServicesLookupTest.java No Base Revision --- /doma/jarda/netbeans-src/openide/util/test/unit/src/org/openide/util/lookup/NamedServicesLookupTest.java Locally New *************** *** 1,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 { + } + + + + }