You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@toree.apache.org by lb...@apache.org on 2016/05/19 14:55:56 UTC

incubator-toree git commit: Updated loading of external plugins to check internal class information when recursing interfaces and super classes

Repository: incubator-toree
Updated Branches:
  refs/heads/master 4b2b2c7a5 -> cd36b1295


Updated loading of external plugins to check internal class information when recursing interfaces and super classes


Project: http://git-wip-us.apache.org/repos/asf/incubator-toree/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-toree/commit/cd36b129
Tree: http://git-wip-us.apache.org/repos/asf/incubator-toree/tree/cd36b129
Diff: http://git-wip-us.apache.org/repos/asf/incubator-toree/diff/cd36b129

Branch: refs/heads/master
Commit: cd36b1295b042c0abdf21b6495d3e077f7f9882e
Parents: 4b2b2c7
Author: Chip Senkbeil <ch...@gmail.com>
Authored: Mon May 16 12:04:22 2016 -0500
Committer: Chip Senkbeil <ch...@gmail.com>
Committed: Thu May 19 09:33:37 2016 -0500

----------------------------------------------------------------------
 .../apache/toree/plugins/PluginSearcher.scala   | 52 ++++++++++++++------
 1 file changed, 38 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-toree/blob/cd36b129/plugins/src/main/scala/org/apache/toree/plugins/PluginSearcher.scala
----------------------------------------------------------------------
diff --git a/plugins/src/main/scala/org/apache/toree/plugins/PluginSearcher.scala b/plugins/src/main/scala/org/apache/toree/plugins/PluginSearcher.scala
index 01afe11..b63545d 100644
--- a/plugins/src/main/scala/org/apache/toree/plugins/PluginSearcher.scala
+++ b/plugins/src/main/scala/org/apache/toree/plugins/PluginSearcher.scala
@@ -30,8 +30,12 @@ class PluginSearcher {
   /** Represents logger used by plugin searcher. */
   private val logger = LoggerFactory.getLogger(this.getClass)
 
+  /** Contains all internal class information for matching plugins. */
+  private lazy val internalClassInfo: Map[String, ClassInfo] =
+    loadClassMap(newClassFinder())
+
   /** Contains all internal plugins for the system. */
-  lazy val internal: Seq[ClassInfo] = findPluginClasses(newClassFinder()).toSeq
+  lazy val internal: Seq[ClassInfo] = findPluginClasses(internalClassInfo).toSeq
 
   /**
    * Searches in the provided paths (jars/zips/directories) for plugin classes.
@@ -40,7 +44,7 @@ class PluginSearcher {
    * @return An iterator over plugin class information
    */
   def search(paths: File*): Iterator[ClassInfo] = {
-    findPluginClasses(newClassFinder(paths))
+    findPluginClasses(loadClassMap(newClassFinder(paths)))
   }
 
   /**
@@ -60,27 +64,45 @@ class PluginSearcher {
   protected def newClassFinder(paths: Seq[File]): ClassFinder = ClassFinder(paths)
 
   /**
-   * Searches for classes implementing in the plugin interface, directly or
-   * indirectly.
+   * Loads all class information using the provided class finder.
    *
-   * @param classFinder The class finder from which to retrieve class information
-   * @return An iterator over plugin class information
+   * @param classFinder The class finder to use when loading class information
+   * @return The map of class names to class info
    */
-  private def findPluginClasses(classFinder: ClassFinder): Iterator[ClassInfo] = {
+  private def loadClassMap(classFinder: ClassFinder): Map[String, ClassInfo] = {
     val tryStream = Try(classFinder.getClasses())
     tryStream.failed.foreach(logger.error(
-      s"Failed to find plugins from classpath: ${classFinder.classpath.mkString(",")}",
+      s"Failed to load class info from classpath: ${classFinder.classpath.mkString(",")}",
       _: Throwable
     ))
     val stream = tryStream.getOrElse(Stream.empty)
-    val classMap = ClassFinder.classInfoMap(stream.toIterator)
-    concreteSubclasses(classOf[Plugin].getName, classMap)
+    ClassFinder.classInfoMap(stream.toIterator)
   }
 
-  /** Patched search that also traverses interfaces. */
+  /**
+   * Searches for classes implementing in the plugin interface, directly or
+   * indirectly.
+   *
+   * @param classMap The map of class information to search for plugins
+   * @return An iterator over plugin class information
+   */
+  private def findPluginClasses(classMap: Map[String, ClassInfo]): Iterator[ClassInfo] = {
+    concreteSubclasses(classOf[Plugin].getName, classMap, internalClassInfo)
+  }
+
+  /**
+   * Patched search that also traverses interfaces.
+   *
+   * @param ancestor The fully-qualified name of the class whose children to
+   *                 find
+   * @param classes The collection of classes to search
+   * @param extraClasses Additional classes to use when traversing superclasses
+   *                     and interfaces in the classes collection
+   */
   private def concreteSubclasses(
     ancestor: String,
-    classes: Map[String, ClassInfo]
+    classes: Map[String, ClassInfo],
+    extraClasses: Map[String, ClassInfo]
   ): Iterator[ClassInfo] = {
     @tailrec def classMatches(
       classesToCheck: Seq[ClassInfo]
@@ -90,8 +112,10 @@ class PluginSearcher {
       else if (classesToCheck.exists(_.superClassName == ancestor)) true
       else if (classesToCheck.exists(_ implements ancestor)) true
       else {
-        val superClasses = classesToCheck.map(_.superClassName).flatMap(classes.get)
-        val interfaces = classesToCheck.flatMap(_.interfaces).flatMap(classes.get)
+        val superClasses = classesToCheck.map(_.superClassName)
+          .flatMap(n => classes.get(n).orElse(extraClasses.get(n)))
+        val interfaces = classesToCheck.flatMap(_.interfaces)
+          .flatMap(i => classes.get(i).orElse(extraClasses.get(i)))
         classMatches(superClasses ++ interfaces)
       }
     }