wvlet.airframe.surface.reflect.package.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of airframe-surface_2.13.0-RC2 Show documentation
Show all versions of airframe-surface_2.13.0-RC2 Show documentation
A library for extracting object structure surface
The newest version!
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package wvlet.airframe.surface
import java.{lang => jl}
import wvlet.log.LogSupport
import scala.reflect.ClassTag
import scala.util.Try
/**
*
*/
package object reflect {
private[reflect] def findAnnotation[T <: jl.annotation.Annotation: ClassTag](
annot: Array[jl.annotation.Annotation]): Option[T] = {
val c = implicitly[ClassTag[T]]
annot
.collectFirst {
case x if (c.runtimeClass isAssignableFrom x.annotationType) => x
}
.asInstanceOf[Option[T]]
}
implicit class ToRuntimeSurface(s: Surface) {
def findAnnotationOf[T <: jl.annotation.Annotation: ClassTag]: Option[T] = {
val annot = s.rawType.getDeclaredAnnotations
findAnnotation[T](annot)
}
}
implicit class ToRuntimeSurfaceParameter(p: Parameter) {
def annotations: Array[Array[jl.annotation.Annotation]] = {
p match {
case mp: MethodParameter =>
Try {
if (mp.method.name == "") {
// constructor
mp.method.owner.getDeclaredConstructor(mp.method.paramTypes: _*).getParameterAnnotations
} else {
mp.method.owner.getDeclaredMethod(mp.method.name, mp.method.paramTypes: _*).getParameterAnnotations
}
}.getOrElse(Array.empty)
case other =>
Array.empty
}
}
def findAnnotationOf[T <: jl.annotation.Annotation: ClassTag]: Option[T] = {
val annots = annotations
if (p.index < annots.length) {
findAnnotation[T](annots(p.index))
} else {
None
}
}
}
implicit class ToRuntimeMethodSurface(m: MethodSurface) {
def annotations: Array[jl.annotation.Annotation] = {
Try {
val cl = m.owner.rawType
val mt = cl.getDeclaredMethod(m.name, m.args.map(_.surface.rawType): _*)
mt.getDeclaredAnnotations
}.getOrElse(Array.empty)
}
def findAnnotationOf[T <: jl.annotation.Annotation: ClassTag]: Option[T] = {
findAnnotation[T](annotations)
}
}
}