Repository: incubator-s2graph
Updated Branches:
  refs/heads/master 32eb344a7 -> 5706bbf1d


implement @trasform directive


Project: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/commit/2d37cf65
Tree: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/tree/2d37cf65
Diff: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/diff/2d37cf65

Branch: refs/heads/master
Commit: 2d37cf658f1860e39ab32d8c8d33c3a57933e829
Parents: 33e3d26
Author: daewon <[email protected]>
Authored: Wed May 30 16:21:04 2018 +0900
Committer: daewon <[email protected]>
Committed: Wed May 30 16:21:04 2018 +0900

----------------------------------------------------------------------
 build.sbt                                       |  4 +-
 s2core/build.sbt                                |  2 +-
 s2graphql/build.sbt                             |  4 +-
 .../apache/s2graph/graphql/GraphQLServer.scala  |  5 +-
 .../s2graph/graphql/middleware/Transform.scala  | 51 ++++++++++++++++++++
 .../s2graph/graphql/types/FieldResolver.scala   |  2 +-
 .../s2graph/graphql/types/S2Directive.scala     | 49 +++++++++++++++++++
 .../s2graph/graphql/types/SchemaDef.scala       | 12 +++--
 8 files changed, 120 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/2d37cf65/build.sbt
----------------------------------------------------------------------
diff --git a/build.sbt b/build.sbt
index 84d17d5..de7c02f 100755
--- a/build.sbt
+++ b/build.sbt
@@ -25,9 +25,9 @@ name := "s2graph"
 
 lazy val commonSettings = Seq(
   organization := "org.apache.s2graph",
-  scalaVersion := "2.11.7",
+  scalaVersion := "2.11.8",
   isSnapshot := version.value.endsWith("-SNAPSHOT"),
-  scalacOptions := Seq("-language:postfixOps", "-unchecked", "-deprecation", 
"-feature", "-Xlint", "-Xlint:-missing-interpolator"),
+  scalacOptions := Seq("-language:postfixOps", "-unchecked", "-deprecation", 
"-feature", "-Xlint", "-Xlint:-missing-interpolator", "-target:jvm-1.8"),
   javaOptions ++= 
collection.JavaConversions.propertiesAsScalaMap(System.getProperties).map { 
case (key, value) => "-D" + key + "=" + value }.toSeq,
   testOptions in Test += Tests.Argument("-oDF"),
   concurrentRestrictions in Global += Tags.limit(Tags.Test, 1),

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/2d37cf65/s2core/build.sbt
----------------------------------------------------------------------
diff --git a/s2core/build.sbt b/s2core/build.sbt
index cfc32d6..229bf41 100644
--- a/s2core/build.sbt
+++ b/s2core/build.sbt
@@ -47,7 +47,7 @@ libraryDependencies ++= Seq(
   "org.apache.tinkerpop" % "gremlin-test" % tinkerpopVersion % "test",
   "org.scalatest" %% "scalatest" % "2.2.4" % "test",
   "org.specs2" %% "specs2-core" % specs2Version % "test",
-  "org.apache.hadoop" % "hadoop-hdfs" % hadoopVersion ,
+  "org.apache.hadoop" % "hadoop-hdfs" % hadoopVersion,
   "org.apache.lucene" % "lucene-core" % "6.6.0",
   "org.apache.lucene" % "lucene-queryparser" % "6.6.0",
   "org.rocksdb" % "rocksdbjni" % rocksVersion,

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/2d37cf65/s2graphql/build.sbt
----------------------------------------------------------------------
diff --git a/s2graphql/build.sbt b/s2graphql/build.sbt
index a3fbec0..bc71f98 100644
--- a/s2graphql/build.sbt
+++ b/s2graphql/build.sbt
@@ -26,13 +26,15 @@ description := "GraphQL server with akka-http and sangria 
and s2graph"
 scalacOptions ++= Seq("-deprecation", "-feature")
 
 libraryDependencies ++= Seq(
+  "org.scala-lang" % "scala-compiler" % scalaVersion.value,
+  "org.scala-lang" % "scala-reflect" % scalaVersion.value,
+
   "org.sangria-graphql" %% "sangria" % "1.4.0",
   "org.sangria-graphql" %% "sangria-spray-json" % "1.0.0",
   "org.sangria-graphql" %% "sangria-play-json" % "1.0.1" % Test,
 
   "com.typesafe.akka" %% "akka-http" % "10.0.10",
   "com.typesafe.akka" %% "akka-http-spray-json" % "10.0.10",
-
   "com.typesafe.akka" %% "akka-slf4j" % "2.4.6",
 
   "org.scalatest" %% "scalatest" % "3.0.4" % Test

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/2d37cf65/s2graphql/src/main/scala/org/apache/s2graph/graphql/GraphQLServer.scala
----------------------------------------------------------------------
diff --git 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/GraphQLServer.scala 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/GraphQLServer.scala
index eee7c93..8ea4c89 100644
--- a/s2graphql/src/main/scala/org/apache/s2graph/graphql/GraphQLServer.scala
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/GraphQLServer.scala
@@ -115,6 +115,8 @@ object GraphQLServer {
     newSchema
   }
 
+  val transformMiddleWare = new 
org.apache.s2graph.graphql.middleware.Transform()
+
   private def executeGraphQLQuery(query: Document, op: Option[String], vars: 
JsObject)(implicit e: ExecutionContext) = {
     val cacheKey = className + "s2Schema"
     val s2schema = schemaCache.withCache(cacheKey, broadcast = 
false)(createNewSchema())
@@ -127,7 +129,8 @@ object GraphQLServer {
       s2Repository,
       variables = vars,
       operationName = op,
-      deferredResolver = resolver
+      deferredResolver = resolver,
+      middleware = List(transformMiddleWare)
     )
       .map((res: spray.json.JsValue) => OK -> res)
       .recover {

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/2d37cf65/s2graphql/src/main/scala/org/apache/s2graph/graphql/middleware/Transform.scala
----------------------------------------------------------------------
diff --git 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/middleware/Transform.scala
 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/middleware/Transform.scala
new file mode 100644
index 0000000..9aa86fb
--- /dev/null
+++ 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/middleware/Transform.scala
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.s2graph.graphql.middleware
+
+import org.apache.s2graph.graphql.types.S2Directive
+import sangria.ast.StringValue
+import sangria.execution.{Middleware, MiddlewareAfterField, 
MiddlewareQueryContext}
+import sangria.schema.Context
+
+case class Transform() extends Middleware[Any] with MiddlewareAfterField[Any] {
+  type QueryVal = Unit
+  type FieldVal = Unit
+
+  def beforeQuery(context: MiddlewareQueryContext[Any, _, _]) = ()
+
+  def afterQuery(queryVal: QueryVal, context: MiddlewareQueryContext[Any, _, 
_]) = ()
+
+  def beforeField(cache: QueryVal, mctx: MiddlewareQueryContext[Any, _, _], 
ctx: Context[Any, _]) = continue
+
+  def afterField(cache: QueryVal, fromCache: FieldVal, value: Any, mctx: 
MiddlewareQueryContext[Any, _, _], ctx: Context[Any, _]) = {
+
+    value match {
+      case s: String => {
+        val transformFuncOpt = 
ctx.astFields.headOption.flatMap(_.directives.find(_.name == 
S2Directive.Transform.name)).map { directive =>
+          directive.arguments.head.value.asInstanceOf[StringValue].value
+        }
+
+        transformFuncOpt.map(funcString => 
S2Directive.resolveTransform(funcString, s)).orElse(Option(s))
+      }
+
+      case _ ⇒ None
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/2d37cf65/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/FieldResolver.scala
----------------------------------------------------------------------
diff --git 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/FieldResolver.scala 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/FieldResolver.scala
index 478517f..a2b80da 100644
--- 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/FieldResolver.scala
+++ 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/FieldResolver.scala
@@ -28,7 +28,6 @@ import org.apache.s2graph.graphql.types.S2Type.EdgeQueryParam
 import sangria.schema._
 
 object FieldResolver {
-
   def graphElement[A](name: String, cType: String, c: Context[GraphRepository, 
Any]): A = {
     c.value match {
       case v: S2VertexLike => name match {
@@ -36,6 +35,7 @@ object FieldResolver {
         case _ =>
           val innerVal = v.propertyValue(name).get
           JSONParser.innerValToAny(innerVal, cType).asInstanceOf[A]
+
       }
       case e: S2EdgeLike => name match {
         case "timestamp" => e.ts.asInstanceOf[A]

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/2d37cf65/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Directive.scala
----------------------------------------------------------------------
diff --git 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Directive.scala 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Directive.scala
new file mode 100644
index 0000000..2eb5768
--- /dev/null
+++ 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Directive.scala
@@ -0,0 +1,49 @@
+package org.apache.s2graph.graphql.types
+
+import sangria.schema.{Argument, Directive, DirectiveLocation, StringType}
+
+object S2Directive {
+
+  object Eval {
+
+    import scala.collection._
+
+    val codeMap = mutable.Map.empty[String, () => Any]
+
+    def compileCode(code: String): () => Any = {
+      import scala.tools.reflect.ToolBox
+      val toolbox = reflect.runtime.currentMirror.mkToolBox()
+
+      toolbox.compile(toolbox.parse(code))
+    }
+
+    def getCompiledCode[T](code: String): T = {
+      val compiledCode = Eval.codeMap.getOrElseUpdate(code, 
Eval.compileCode(code))
+
+      compiledCode
+        .asInstanceOf[() => Any]
+        .apply()
+        .asInstanceOf[T]
+    }
+  }
+
+  type TransformFunc = String => String
+
+  val funcArg = Argument("func", StringType)
+
+  val Transform =
+    Directive("transform",
+      arguments = List(funcArg),
+      locations = Set(DirectiveLocation.Field),
+      shouldInclude = _ => true)
+
+  def resolveTransform(code: String, input: String): String = {
+    try {
+      val fn = Eval.getCompiledCode[TransformFunc](code)
+
+      fn.apply(input)
+    } catch {
+      case e: Exception => e.toString
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/2d37cf65/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SchemaDef.scala
----------------------------------------------------------------------
diff --git 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SchemaDef.scala 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SchemaDef.scala
index 27b0c50..7451023 100644
--- a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SchemaDef.scala
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SchemaDef.scala
@@ -20,8 +20,6 @@
 package org.apache.s2graph.graphql.types
 
 import org.apache.s2graph.graphql.repository.GraphRepository
-import org.apache.s2graph.graphql.types._
-
 
 /**
   * S2Graph GraphQL schema.
@@ -47,5 +45,13 @@ class SchemaDef(g: GraphRepository) {
     fields(s2Type.mutationFields ++ mutateManagementFields: _*)
   )
 
-  val S2GraphSchema = Schema(S2QueryType, Option(S2MutationType))
+  val directives = S2Directive.Transform :: BuiltinDirectives
+
+  private val s2Schema = Schema(
+    S2QueryType,
+    Option(S2MutationType),
+    directives = directives
+  )
+
+  val S2GraphSchema = s2Schema
 }

Reply via email to