2015-12-30 21 views
8

Voglio elencare tutte le classi di casi che implementano un particolare tratto. Attualmente sto usando Clapper ClassUtil per farlo. Sono in grado di ottenere le classi di casi che implementano direttamente un tratto. Tuttavia, non sono in grado di ottenere le altre classi che non implementano direttamente il tratto. Come posso ottenere tutte le classi che implementano direttamente o indirettamente un tratto. ?Ottieni tutte le classi che implementano un tratto in Scala utilizzando la riflessione

val finder = ClassFinder() 
finder.getClasses().filter(_.isConcrete).filter(_.implements("com.myapp.MyTrait")) 

Scala Versione: 2.11

Clapper Classe Versione Util: 1.0.6

C'è un altro modo per ottenere queste informazioni? Qualcuno può indicarmi la giusta direzione? Ho provato a utilizzare scala.reflect ma non sono riuscito a capire come ottenere le informazioni.

EDIT: 

tratti e gli usi di esempio:

trait BaseEntity 
trait NamedEntity{ val name:String} 
trait MasterDataEntity extends NamedEntity 

case class Department(id:Long, override val name:String) extends MasterDataEntity 
case class Employee(id:Long, name:String) extends BaseEntity 
case class User(id:Long, override val name:String) extends NamedEntity 

Ora, se io do il tratto come NamedEntity, dovrei essere in grado di ottenere sia Department e User dal momento che entrambi sono direttamente o indirettamente, attuando NamedEntity. Con il metodo implements, darà solo Utente. Ho anche provato usando il metodo interfaces, che fornirà anche solo le super classi dirette.

+0

Potresti definire tre tratti/classi e la loro relazione per dimostrare il problema? –

+0

Ho aggiunto i tratti del campione e gli usi della classe di casi. –

risposta

4

Guardando allo source code, il problema sembra essere che non segue la gerarchia delle interfacce. Se lo fai, trovi tutte le istanze:

package foo 

import java.io.File 

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

object Main extends App { 
    val jar  = new File("target/scala-2.11/class_test_2.11-0.1.0.jar") 
    val finder = ClassFinder(jar :: Nil) 
    val classes = ClassFinder.classInfoMap(finder.getClasses().iterator) 
    val impl = find("foo.NamedEntity", 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 
    } 
} 
+0

Grazie mille, questo l'ha risolto .. :) –

Problemi correlati