1 19 20 package org.openide.util.lookup; 21 22 import java.io.File ; 23 import java.io.FileOutputStream ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.io.InputStreamReader ; 27 import java.net.URL ; 28 import java.net.URLClassLoader ; 29 import java.util.ArrayList ; 30 import java.util.Collections ; 31 import java.util.Enumeration ; 32 import java.util.List ; 33 import java.util.Set ; 34 import java.util.Set ; 35 import java.util.TreeSet ; 36 import java.util.jar.JarEntry ; 37 import java.util.jar.JarOutputStream ; 38 import java.util.logging.Level ; 39 import java.util.logging.Logger ; 40 import java.util.regex.Matcher ; 41 import java.util.regex.Pattern ; 42 import org.netbeans.junit.NbTestCase; 43 import org.openide.util.Lookup; 44 import org.openide.util.LookupEvent; 45 import org.openide.util.LookupListener; 46 import org.openide.util.RequestProcessor; 47 48 51 public class MetaInfServicesLookupTest extends NbTestCase { 52 private Logger LOG; 53 54 public MetaInfServicesLookupTest(String name) { 55 super(name); 56 LOG = Logger.getLogger("Test." + name); 57 } 58 59 private String prefix() { 60 return "META-INF/services/"; 61 } 62 63 protected Level logLevel() { 64 return Level.INFO; 65 } 66 67 private URL findJar(String n) throws IOException { 68 LOG.info("Looking for " + n); 69 File jarDir = new File (getWorkDir(), "jars"); 70 jarDir.mkdirs(); 71 File jar = new File (jarDir, n); 72 if (jar.exists()) { 73 return jar.toURI().toURL(); 74 } 75 76 LOG.info("generating " + jar); 77 78 URL data = MetaInfServicesLookupTest.class.getResource(n.replaceAll("\\.jar", "\\.txt")); 79 assertNotNull("Data found", data); 80 StringBuffer sb = new StringBuffer (); 81 InputStreamReader r = new InputStreamReader (data.openStream()); 82 for(;;) { 83 int ch = r.read(); 84 if (ch == -1) { 85 break; 86 } 87 sb.append((char)ch); 88 } 89 90 JarOutputStream os = new JarOutputStream (new FileOutputStream (jar)); 91 92 Pattern p = Pattern.compile(":([^:]+):([^:]*)", Pattern.MULTILINE | Pattern.DOTALL); 93 Matcher m = p.matcher(sb); 94 Pattern foobar = Pattern.compile("^(org\\.(foo|bar)\\..*)$", Pattern.MULTILINE); 95 Set <String > names = new TreeSet <String >(); 96 while (m.find()) { 97 assert m.groupCount() == 2; 98 String entryName = prefix() + m.group(1); 99 LOG.info("putting there entry: " + entryName); 100 os.putNextEntry(new JarEntry (entryName)); 101 os.write(m.group(2).getBytes()); 102 os.closeEntry(); 103 104 Matcher fb = foobar.matcher(m.group(2)); 105 while (fb.find()) { 106 String clazz = fb.group(1).replace('.', '/') + ".class"; 107 LOG.info("will copy " + clazz); 108 names.add(clazz); 109 } 110 } 111 112 for (String copy : names) { 113 os.putNextEntry(new JarEntry (copy)); 114 LOG.info("copying " + copy); 115 InputStream from = MetaInfServicesLookupTest.class.getResourceAsStream("/" + copy); 116 assertNotNull(copy, from); 117 for (;;) { 118 int ch = from.read(); 119 if (ch == -1) { 120 break; 121 } 122 os.write(ch); 123 } 124 from.close(); 125 os.closeEntry();; 126 } 127 os.close(); 128 LOG.info("done " + jar); 129 return jar.toURI().toURL(); 130 } 131 132 ClassLoader c1, c2, c2a, c3, c4; 133 134 protected void setUp() throws Exception { 135 clearWorkDir(); 136 ClassLoader app = getClass().getClassLoader().getParent(); 137 ClassLoader c0 = app; 138 139 c1 = new URLClassLoader (new URL [] { 140 findJar("services-jar-1.jar"), 141 }, c0); 142 c2 = new URLClassLoader (new URL [] { 143 findJar("services-jar-2.jar"), 144 }, c1); 145 c2a = new URLClassLoader (new URL [] { 146 findJar("services-jar-2.jar"), 147 }, c1); 148 c3 = new URLClassLoader (new URL [] { findJar("services-jar-2.jar") }, 149 c0 150 ); 151 c4 = new URLClassLoader (new URL [] { 152 findJar("services-jar-1.jar"), 153 findJar("services-jar-2.jar"), 154 }, c0); 155 } 156 157 public void testBasicUsage() throws Exception { 158 Lookup l = Lookups.metaInfServices(c2); 159 Class xface = c1.loadClass("org.foo.Interface"); 160 List results = new ArrayList (l.lookup(new Lookup.Template(xface)).allInstances()); 161 assertEquals(2, results.size()); 162 assertEquals("org.foo.impl.Implementation1", results.get(0).getClass().getName()); 164 assertEquals("org.bar.Implementation2", results.get(1).getClass().getName()); 165 List results2 = new ArrayList (l.lookup(new Lookup.Template(xface)).allInstances()); 167 assertEquals(results, results2); 168 } 169 170 public void testLoaderSkew() throws Exception { 171 Class xface1 = c1.loadClass("org.foo.Interface"); 172 Lookup l3 = Lookups.metaInfServices(c3); 173 assertEquals(Collections.EMPTY_LIST, 175 new ArrayList (l3.lookup(new Lookup.Template(xface1)).allInstances())); 176 Lookup l4 = Lookups.metaInfServices(c4); 177 assertEquals(Collections.EMPTY_LIST, 179 new ArrayList (l4.lookup(new Lookup.Template(xface1)).allInstances())); 180 Class xface4 = c4.loadClass("org.foo.Interface"); 182 assertEquals(2, l4.lookup(new Lookup.Template(xface4)).allInstances().size()); 183 } 184 185 public void testStability() throws Exception { 186 Lookup l = Lookups.metaInfServices(c2); 187 Class xface = c1.loadClass("org.foo.Interface"); 188 Object first = l.lookup(new Lookup.Template(xface)).allInstances().iterator().next(); 189 l = Lookups.metaInfServices(c2a); 190 Object second = l.lookup(new Lookup.Template(xface)).allInstances().iterator().next(); 191 assertEquals(first, second); 192 } 193 194 public void testMaskingOfResources() throws Exception { 195 Lookup l1 = Lookups.metaInfServices(c1); 196 Lookup l2 = Lookups.metaInfServices(c2); 197 Lookup l4 = Lookups.metaInfServices(c4); 198 199 assertNotNull("services1.jar defines a class that implements runnable", l1.lookup(Runnable .class)); 200 assertNull("services2.jar does not defines a class that implements runnable", l2.lookup(Runnable .class)); 201 assertNull("services1.jar defines Runnable, but services2.jar masks it out", l4.lookup(Runnable .class)); 202 } 203 204 public void testOrdering() throws Exception { 205 Lookup l = Lookups.metaInfServices(c1); 206 Class xface = c1.loadClass("java.util.Comparator"); 207 List results = new ArrayList (l.lookup(new Lookup.Template(xface)).allInstances()); 208 assertEquals(1, results.size()); 209 210 l = Lookups.metaInfServices(c2); 211 xface = c2.loadClass("java.util.Comparator"); 212 results = new ArrayList (l.lookup(new Lookup.Template(xface)).allInstances()); 213 assertEquals(2, results.size()); 214 assertEquals("org.bar.Comparator2", results.get(0).getClass().getName()); 216 assertEquals("org.foo.impl.Comparator1", results.get(1).getClass().getName()); 217 218 l = Lookups.metaInfServices(c2); 220 xface = c2.loadClass("java.util.Iterator"); 221 results = new ArrayList (l.lookup(new Lookup.Template(xface)).allInstances()); 222 assertEquals(2, results.size()); 223 assertEquals("org.bar.Iterator2", results.get(0).getClass().getName()); 225 assertEquals("org.foo.impl.Iterator1", results.get(1).getClass().getName()); 226 } 227 228 public void testNoCallToGetResourceForObjectIssue65124() throws Exception { 229 class Loader extends ClassLoader { 230 private int counter; 231 232 protected URL findResource(String name) { 233 if (name.equals("META-INF/services/java.lang.Object")) { 234 counter++; 235 } 236 237 URL retValue; 238 239 retValue = super.findResource(name); 240 return retValue; 241 } 242 243 protected Enumeration findResources(String name) throws IOException { 244 if (name.equals("META-INF/services/java.lang.Object")) { 245 counter++; 246 } 247 Enumeration retValue; 248 249 retValue = super.findResources(name); 250 return retValue; 251 } 252 } 253 Loader loader = new Loader (); 254 Lookup l = Lookups.metaInfServices(loader); 255 256 Object no = l.lookup(String .class); 257 assertNull("Not found of course", no); 258 assertEquals("No lookup of Object", 0, loader.counter); 259 } 260 261 public void testListenersAreNotifiedWithoutHoldingALockIssue36035() throws Exception { 262 final Lookup l = Lookups.metaInfServices(c2); 263 final Class xface = c1.loadClass("org.foo.Interface"); 264 final Lookup.Result res = l.lookup(new Lookup.Template(Object .class)); 265 266 class L implements LookupListener, Runnable { 267 private Thread toInterrupt; 268 269 public void run() { 270 assertNotNull("Possible to query lookup", l.lookup(xface)); 271 assertEquals("and there are two items", 2, res.allInstances().size()); 272 toInterrupt.interrupt(); 273 } 274 275 public synchronized void resultChanged(LookupEvent ev) { 276 toInterrupt = Thread.currentThread(); 277 RequestProcessor.getDefault().post(this); 278 try { 279 wait(3000); 280 fail("Should be interrupted - means it was not possible to finish query in run() method"); 281 } catch (InterruptedException ex) { 282 } 284 } 285 } 286 L listener = new L (); 287 288 res.addLookupListener(listener); 289 assertEquals("Nothing yet", 0, res.allInstances().size()); 290 291 assertNotNull("Interface found", l.lookup(xface)); 292 assertNotNull("Listener notified", listener.toInterrupt); 293 294 assertEquals("Now two", 2, res.allInstances().size()); 295 } 296 } 297 | Popular Tags |