Example #1
0
  protected List<PluginInfo<T>> scan(
      LogSource logger,
      String hosterpath,
      final List<? extends LazyPlugin<T>> pluginCache,
      final AtomicLong lastFolderModification)
      throws Exception {
    DirectoryStream<Path> stream = null;
    final ArrayList<PluginInfo<T>> ret = new ArrayList<PluginInfo<T>>();
    final long timeStamp = System.currentTimeMillis();
    try {
      long lastModified = lastFolderModification != null ? lastFolderModification.get() : -1;
      final Path folder =
          Application.getRootByClass(jd.SecondLevelLaunch.class, hosterpath).toPath();
      final long lastFolderModified =
          Files.readAttributes(folder, BasicFileAttributes.class).lastModifiedTime().toMillis();
      if (lastModified > 0
          && lastFolderModified == lastModified
          && pluginCache != null
          && pluginCache.size() > 0) {
        for (final LazyPlugin<T> lazyPlugin : pluginCache) {
          final PluginInfo<T> pluginInfo = new PluginInfo<T>(lazyPlugin.getLazyPluginClass(), null);
          pluginInfo.setLazyPlugin(lazyPlugin);
          ret.add(pluginInfo);
        }
        return ret;
      }
      PluginClassLoaderChild cl = null;
      MessageDigest md = null;
      final String pkg = hosterpath.replace("/", ".");
      final byte[] mdCache = new byte[32767];
      final HashMap<String, List<LazyPlugin<T>>> lazyPluginClassMap;
      if (pluginCache != null && pluginCache.size() > 0) {
        lazyPluginClassMap = new HashMap<String, List<LazyPlugin<T>>>();
        for (final LazyPlugin<T> lazyPlugin : pluginCache) {
          List<LazyPlugin<T>> list =
              lazyPluginClassMap.get(lazyPlugin.getLazyPluginClass().getClassName());
          if (list == null) {
            list = new ArrayList<LazyPlugin<T>>();
            lazyPluginClassMap.put(lazyPlugin.getLazyPluginClass().getClassName(), list);
          }
          list.add(lazyPlugin);
        }
      } else {
        lazyPluginClassMap = null;
      }
      if (lastFolderModification != null) {
        lastFolderModification.set(lastFolderModified);
      }
      stream = Files.newDirectoryStream(folder, "*.class");
      for (final Path path : stream) {
        try {
          final String pathFileName = path.getFileName().toString();
          final String className = pathFileName.substring(0, pathFileName.length() - 6);
          if (className.indexOf("$") < 0 && !PluginController.IGNORELIST.contains(className)) {
            byte[] sha256 = null;
            final BasicFileAttributes pathAttr =
                Files.readAttributes(path, BasicFileAttributes.class);
            if (lazyPluginClassMap != null) {
              final List<LazyPlugin<T>> lazyPlugins = lazyPluginClassMap.get(className);
              if (lazyPlugins != null && lazyPlugins.size() > 0) {
                final LazyPluginClass lazyPluginClass = lazyPlugins.get(0).getLazyPluginClass();
                if (lazyPluginClass != null
                    && (lazyPluginClass.getLastModified() == pathAttr.lastModifiedTime().toMillis()
                        || ((md = MessageDigest.getInstance("SHA-256")) != null
                            && (sha256 =
                                    PluginController.getFileHashBytes(path.toFile(), md, mdCache))
                                != null
                            && Arrays.equals(sha256, lazyPluginClass.getSha256())))) {
                  for (final LazyPlugin<T> lazyPlugin : lazyPlugins) {
                    // logger.finer("Cached: " + className + "|" + lazyPlugin.getDisplayName() + "|"
                    // +
                    // lazyPluginClass.getRevision());
                    final PluginInfo<T> pluginInfo = new PluginInfo<T>(lazyPluginClass, null);
                    pluginInfo.setLazyPlugin(lazyPlugin);
                    ret.add(pluginInfo);
                  }
                  continue;
                }
              }
            }
            Class<T> pluginClass = null;
            long[] infos = null;
            try {
              if (cl == null) {
                cl = PluginClassLoader.getInstance().getChild();
              }
              if (md == null) {
                md = MessageDigest.getInstance("SHA-256");
              }
              pluginClass = (Class<T>) cl.loadClass(pkg + "." + className);
              if (!Modifier.isAbstract(pluginClass.getModifiers())
                  && Plugin.class.isAssignableFrom(pluginClass)) {
                infos = getPluginController().getInfos(pluginClass);
                if (infos == null) {
                  continue;
                }
              } else {
                continue;
              }
            } catch (final Throwable e) {
              logger.finer("Failed: " + className);
              logger.log(e);
              continue;
            }
            if (sha256 == null) {
              sha256 = PluginController.getFileHashBytes(path.toFile(), md, mdCache);
            }
            //
            final LazyPluginClass lazyPluginClass =
                new LazyPluginClass(
                    className,
                    sha256,
                    pathAttr.lastModifiedTime().toMillis(),
                    (int) infos[0],
                    infos[1]);
            final PluginInfo<T> pluginInfo = new PluginInfo<T>(lazyPluginClass, pluginClass);
            // logger.finer("Scaned: " + className + "|" + lazyPluginClass.getRevision());
            ret.add(pluginInfo);
          }

        } catch (Throwable e) {
          logger.finer("Failed: " + path);
          logger.log(e);
        }
      }
      return ret;
    } finally {
      logger.info(
          "@PluginController(NIO): scan took "
              + (System.currentTimeMillis() - timeStamp)
              + "ms for "
              + ret.size());
      if (stream != null) {
        stream.close();
      }
    }
  }