2017-03-02 2 views
0

からプロパティを取得するためにScalaのリフレクションを使用してください:は、どのように私は、メソッドのアノテーション

def annotations()
import com.wordnik.swagger.annotations.ApiModel 
import reflect.runtime.universe._ 

case class Model(
        name: String, 
        qualifiedType: String, 
        properties: Map[String, ModelProperty], 
        description: Option[String] = None) 

case class ModelProperty(
          `type`: String, 
          qualifiedType: String, 
          description: Option[String] = None, 
          items: Option[ModelRef] = None) 

case class ModelRef(
        `type`: String, 
        ref: Option[String] = None, 
        qualifiedType: Option[String] = None) 


class ModelHelper { 

    def apply(models: Seq[Class[_]]) : Seq[Model] = { 
    models.map(m => 
     Model(m.getSimpleName, m.getName, null, annotations(m)) 
    ) 
    } 

    private def annotations(c : Class[_]) : Option[String] = 
    c.getAnnotations.toSeq.map { 
     case api : ApiModel => api.description 
    }.headOption 

    private def getType[T](clazz: Class[T]): Type = { 
    val r = runtimeMirror(clazz.getClassLoader) 
    r.classSymbol(clazz).toType 
    } 

    private def properties(c : Class[_]) = { 
    getType(c).members.view.filter{!_.isMethod}.map { m => 
     m.annotations.map { a => 
     if(a.tree.tpe =:= typeOf[ApiModelProperty]) { 
      a.tree.tpe.??? //<--stuck here 
     } 
     } 
    } 
    } 
} 

、私はApiModelクラスのアノテーションからすべての説明フィールドをつかむことができます。 propertiesには、ApiModelPropertyのフィールドを取得したいと考えています。私はドリルダウンした場合にSBTコンソールで

は、私が欲しいの注釈をはっきり見ることができます:私は実際にその特定の注釈のインスタンスを取得するに一致するかわからないんだけど..but

... 
scala> t.members.view.filter{!_.isMethod}map{ m => { m.annotations }}).head.head.tree 
q: reflect.runtime.universe.Tree = new com.wordnik.swagger.annotations.ApiModelProperty @scala.annotation.meta.field(value = "A list of errors on the asset in five different containers.") 

私が上記のannotations()で行ったように。私は本当にインスタンスpersayを必要としないと思います、私はちょうどvalueを取得する必要があります。それをどうやってやりますか?私はScala 2.11.8です。

答えて

0

私は解決策を見つけ出しました。

private def properties(c: Class[_]): Map[String, ModelProperty] = { 
    getType(c).members.view.filter {!_.isMethod}.map { m => 
     m.name.toString -> ModelProperty(
     toUsefulType(m.typeSignature.toString), 
     m.typeSignature.toString, 
     m.annotations.find { a => 
      a.tree.tpe =:= typeOf[com.wordnik.swagger.annotations.ApiModelProperty] || 
      a.tree.tpe =:= typeOf[io.swagger.annotations.ApiModelProperty] }.flatMap { b => 
      b.tree.children.flatMap { c => 
       c.collect { 
       case Literal(Constant(value)) => value 
       } 
      }.headOption 
      }.getOrElse("").toString 
    ) 
    }.toMap 
    } 

参考文献:

Veeb's Brain Dump: Reflecting Annotations in Scala 2.10 - このブログの記事はAccessing an Annotation Value in Scalaのための回答/コメントも役立つ証明Scalaの2.11のために、私は私の答えに更新され、いくつかの非推奨の呼び出し

を使用しています。