private List<LazyHostPlugin> update( LogSource logger, final List<LazyHostPlugin> updateCache, final AtomicLong lastFolderModification) throws Exception { final List<LazyHostPlugin> retList = new ArrayList<LazyHostPlugin>(); for (PluginInfo<PluginForHost> pluginInfo : scan(logger, "jd/plugins/hoster", updateCache, lastFolderModification)) { if (pluginInfo.getLazyPlugin() != null) { final LazyHostPlugin plugin = (LazyHostPlugin) pluginInfo.getLazyPlugin(); retList.add(plugin); // logger.finer("@HostPlugin ok(cached):" + plugin.getClassName() + " " + // plugin.getDisplayName() + " " + // plugin.getVersion()); } else { final String simpleName = new String(pluginInfo.getClazz().getSimpleName()); final HostPlugin a = pluginInfo.getClazz().getAnnotation(HostPlugin.class); if (a != null) { try { final long revision = pluginInfo.getLazyPluginClass().getRevision(); String[] names = a.names(); String[] patterns = a.urls(); int[] flags = a.flags(); if (names.length == 0) { /* create multiple hoster plugins from one source */ patterns = (String[]) pluginInfo .getClazz() .getDeclaredMethod("getAnnotationUrls", new Class[] {}) .invoke(null, new Object[] {}); names = (String[]) pluginInfo .getClazz() .getDeclaredMethod("getAnnotationNames", new Class[] {}) .invoke(null, new Object[] {}); flags = (int[]) pluginInfo .getClazz() .getDeclaredMethod("getAnnotationFlags", new Class[] {}) .invoke(null, new Object[] {}); } if (patterns.length != names.length) { // throw new WTFException("names.length != patterns.length"); } if (flags.length != names.length && a.interfaceVersion() == 2) { /* interfaceVersion 2 is for Stable/Nightly */ logger.log( (new WTFException( "PLUGIN STABLE ISSUE!! names.length(" + names.length + ")!= flags.length(" + flags.length + ")->" + simpleName))); } if (names.length == 0) { // throw new WTFException("names.length=0"); } final PluginClassLoaderChild classLoader = (PluginClassLoaderChild) pluginInfo.getClazz().getClassLoader(); /* during init we dont want dummy libs being created */ classLoader.setCreateDummyLibs(false); for (int i = 0; i < names.length; i++) { LazyHostPlugin lazyHostPlugin = null; try { lazyHostPlugin = new LazyHostPlugin( pluginInfo.getLazyPluginClass(), new String(patterns[i]), new String(names[i]), pluginInfo.getClazz(), classLoader); if (list != null) { final LazyHostPlugin previousLazyHostPlugin = list.get(lazyHostPlugin.getDisplayName()); if (previousLazyHostPlugin != null) { lazyHostPlugin.setPluginUsage(previousLazyHostPlugin.getPluginUsage()); } } try { /* check for stable compatibility */ classLoader.setPluginClass(pluginInfo.getClazz().getName()); classLoader.setCheckStableCompatibility( pluginInfo.getLazyPluginClass().getInterfaceVersion() == 2); final PluginForHost plg = lazyHostPlugin.newInstance(classLoader); /* set configinterface */ final Class<? extends ConfigInterface> configInterface = plg.getConfigInterface(); if (configInterface != null) { lazyHostPlugin.setConfigInterface(new String(configInterface.getName())); } else { lazyHostPlugin.setConfigInterface(null); } /* set premium */ if (plg.isPremiumEnabled()) { lazyHostPlugin.setPremium(true); /* set premiumUrl */ final String purl = plg.getBuyPremiumUrl(); if (purl != null) { lazyHostPlugin.setPremiumUrl(new String(purl)); } } else { lazyHostPlugin.setPremium(false); } /* set hasConfig */ lazyHostPlugin.setHasConfig(plg.hasConfig()); try { lazyHostPlugin.setHasAllowHandle(PluginForHost.implementsAllowHandle(plg)); } catch (Throwable e) { logger.log(e); lazyHostPlugin.setHasAllowHandle(false); } try { lazyHostPlugin.setHasRewrite(PluginForHost.implementsRewriteHost(plg)); } catch (Throwable e) { logger.log(e); lazyHostPlugin.setHasRewrite(false); } } catch (Throwable e) { if (e instanceof UpdateRequiredClassNotFoundException) { logger.log(e); logger.finest( "@HostPlugin incomplete:" + simpleName + " " + new String(names[i]) + " " + e.getMessage() + " " + revision); } else { throw e; } } if (lazyHostPlugin != null) { retList.add(lazyHostPlugin); // logger.finer("@HostPlugin ok:" + simpleName + " " + new String(names[i]) + " " // + revision); } } catch (Throwable e) { logger.log(e); logger.severe( "@HostPlugin failed:" + simpleName + " " + new String(names[i]) + " " + revision); } finally { /* now the pluginClassLoad may create dummy libraries */ if (lazyHostPlugin != null) { lazyHostPlugin.setClassLoader(null); lazyHostPlugin.setPluginClass(null); } } } } catch (final Throwable e) { logger.severe("@HostPlugin failed:" + simpleName); logger.log(e); } } else { logger.severe("@HostPlugin missing:" + simpleName); } } } return retList; }
@Override protected long[] getInfos(Class<PluginForHost> clazz) { final HostPlugin infos = clazz.getAnnotation(HostPlugin.class); return new long[] {infos.interfaceVersion(), Formatter.getRevision(infos.revision())}; }