Created
December 15, 2014 17:43
-
-
Save mgosk/120dc39569e44ef9214b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pacakge xxx | |
import java.lang.reflect.Modifier | |
import com.iterators.model.db.user.User | |
import com.iterators.services.AuthenticationService | |
import shapeless.{HList, HNil, ::} | |
import spray.http.StatusCodes._ | |
import spray.routing._ | |
import scala.reflect.ClassTag | |
import scala.util.control.NonFatal | |
import scalaz.Alpha.T | |
import reflect._ | |
import scala.reflect.runtime.{currentMirror => cm} | |
import scala.reflect.runtime.universe._ | |
import scala.reflect._ | |
trait ParamsExtractorDirectives extends HttpService { | |
def extractParams[A <: Product]()(implicit T:ClassTag[A]): Directive1[A] = new Directive1[A] { | |
override def happly(inner: (::[A, HNil]) => Route): Route = | |
ctx => {inner(createInstance[A] :: HNil)(ctx) | |
} | |
} | |
def createInstance[A]()(implicit T: ClassTag[A]): A = { | |
val claas = cm classSymbol T.runtimeClass | |
val modul = claas.companionSymbol.asModule | |
val im = cm reflect (cm reflectModule modul).instance | |
default[A](im, "apply") | |
} | |
def default[A](im: InstanceMirror, name: String): A = { | |
val at = newTermName(name) | |
val ts = im.symbol.typeSignature | |
val method = (ts member at).asMethod | |
// either defarg or default val for type of p | |
def valueFor(p: Symbol, i: Int): Any = { | |
val defarg = ts member newTermName(s"$name$$default$$${ | |
i + 1 | |
}") | |
if (defarg != NoSymbol) { | |
println(s"default $defarg") | |
(im reflectMethod defarg.asMethod)() | |
} else { | |
println(s"def val for $p") | |
p.typeSignature match { | |
case t if t =:= typeOf[String] => null | |
case t if t =:= typeOf[Int] => 0 | |
case x => throw new IllegalArgumentException(x.toString) | |
} | |
} | |
} | |
val args = (for (ps <- method.paramss; | |
p <- ps) yield p).zipWithIndex map (p => valueFor(p._1, p._2)) | |
(im reflectMethod method)(args: _*).asInstanceOf[A] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment