0

I have several classes which extends a trait. I created a factory method that uses pattern matching in order to instantiate the relevant class.

The problem is that whenever I create a new class that extend this trait I need to add it to the factory method manually. is there an option to create the list of classes dynamically from all the classes available?

Thanks

some code examples:

current implementation :

object Test {
  trait Parent
  object Parent{
    def apply(classType:String): Parent = classType match {
      case "A" => new A
      case "B" => new B
      case "C" => new C

    }
  }
  class A extends Parent
  class B extends Parent
  class C extends Parent
}

wanted behaviour:

object Test {
  trait Parent
  object Parent{
    def apply(classType:String): Parent = SomeFunction(ClassType)

    }
  }
  class A extends Parent
  class B extends Parent
  class C extends Parent
}
EECOLOR
  • 11,184
  • 3
  • 41
  • 75
Lior Baber
  • 852
  • 3
  • 11
  • 25

1 Answers1

3

Using reflection get all the classes that extend this trait

get relevant classes and add them to list.

Alternatively you can create a Map which can help locate classes by some key

Code

package demo


trait Animal {

}

class Dog extends Animal

class Cat extends Animal

library used org.clapper" %% "classutil" % "1.0.11"

import org.clapper.classutil.{ClassFinder, ClassInfo}

object Main {
  def main(args: Array[String]): Unit = {
    val finder  = ClassFinder()
    val classes = ClassFinder.classInfoMap(finder.getClasses().iterator)
    val impl    = find("demo.Animal", classes)
    impl.foreach(println)
  }
  def find(ancestor: String, classes: Map[String, ClassInfo]): List[ClassInfo] =
    classes.get(ancestor).fold(List.empty[ClassInfo]) { ancestorInfo =>
      val ancestorName = ancestorInfo.name

      def compare(info: ClassInfo): Boolean =
        info.name == ancestorName ||
          (info.superClassName :: info.interfaces).exists {
            n => classes.get(n).exists(compare)
          }

      val it = classes.valuesIterator
      it.filter { info => info.isConcrete && compare(info) } .toList
    }
}

output

demo.Dog
demo.Cat

note that most of the code is taken from this post and changed to suite current purpose Get all the classes that implments a trait in Scala using reflection

Community
  • 1
  • 1
Nagarjuna Pamu
  • 14,737
  • 3
  • 22
  • 40
  • it failed on the following exception: `class org.clapper.classutil.asm.ASMEmptyVisitor has interface org.objectweb.asm.ClassVisitor as super class` – Lior Baber Sep 01 '16 at 05:46