/** Scans the classpath for META-INF/services/com.clevercloud.bianca.BiancaModule */ private void initStaticFunctions() { Thread thread = Thread.currentThread(); ClassLoader oldLoader = thread.getContextClassLoader(); try { setContextClassLoader(_loader); String biancaModule = "META-INF/services/com.clevercloud.bianca.BiancaModule"; Enumeration<URL> urls = _loader.getResources(biancaModule); HashSet<URL> urlSet = new HashSet<URL>(); // gets rid of duplicate entries found by different classloaders while (urls.hasMoreElements()) { URL url = urls.nextElement(); if (!hasServiceModule(url)) { addServiceModule(url); urlSet.add(url); } } for (URL url : urlSet) { InputStream is = null; ReadStream rs = null; try { is = url.openStream(); rs = new ReadStream(new VfsStream(is, null)); parseServicesModule(rs); } catch (Throwable e) { log.log(Level.FINE, e.toString(), e); } finally { if (rs != null) { rs.close(); } if (is != null) { is.close(); } } } } catch (Exception e) { log.log(Level.FINE, e.toString(), e); } finally { setContextClassLoader(oldLoader); } }
/** Parses the services file, looking for PHP services. */ private void parseClassServicesModule(ReadStream in) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, ConfigException, NoSuchMethodException, InvocationTargetException { ClassLoader loader = Thread.currentThread().getContextClassLoader(); String line; while ((line = in.readLine()) != null) { int p = line.indexOf('#'); if (p >= 0) { line = line.substring(0, p); } line = line.trim(); if (line.length() == 0) { continue; } String[] args = line.split(" "); String className = args[0]; Class cl; try { cl = Class.forName(className, false, loader); String phpClassName = null; String extension = null; String definedBy = null; for (int i = 1; i < args.length; i++) { if ("as".equals(args[i])) { i++; if (i >= args.length) { throw new IOException( L.l( "expecting Bianca class name after '{0}' " + "in definition for class {1}", "as", className)); } phpClassName = args[i]; } else if ("provides".equals(args[i])) { i++; if (i >= args.length) { throw new IOException( L.l( "expecting name of extension after '{0}' " + "in definition for class {1}", "extension", className)); } extension = args[i]; } else if ("definedBy".equals(args[i])) { i++; if (i >= args.length) { throw new IOException( L.l( "expecting name of class implementing JavaClassDef after '{0}' " + "in definition for class {1}", "definedBy", className)); } definedBy = args[i]; } else { throw new IOException( L.l("unknown token '{0}' in definition for class {1} ", args[i], className)); } } if (phpClassName == null) { phpClassName = className.substring(className.lastIndexOf('.') + 1); } Class javaClassDefClass; if (definedBy != null) { javaClassDefClass = Class.forName(definedBy, false, loader); } else { javaClassDefClass = null; } introspectJavaClass(phpClassName, cl, extension, javaClassDefClass); } catch (Exception e) { log.log(Level.FINE, "Failed loading {0}\n{1}", new Object[] {className, e.toString()}); log.log(Level.FINE, e.toString(), e); } } }