所以我目前有以下内容:
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
}
}
}
}
}
在def annotations()
中,我可以从ApiModel
类注释中获取所有描述字段。在properties
中,我想从ApiModelProperty
抓取字段。
在SBT控制台中,如果我向下钻取,我可以清楚地看到我想要的注释:
...
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()
中所做的那样。我想我真的不需要实例,我只需要value
。我该怎么做呢?我在使用Scala 2.11.8。
答案 0 :(得分: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 - 此博客文章使用了一些弃用的调用,我在Scala 2.11的答案中更新了
Accessing an Annotation Value in Scala的答案/评论也证明是有帮助的。