Skip to content

Commit

Permalink
Added support for Implicit model names from preset functions
Browse files Browse the repository at this point in the history
Updated annotations regexes to support special chars in assignments
  • Loading branch information
acunniffe committed Nov 1, 2018
1 parent 83dbb4c commit 881167b
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,30 +58,37 @@ object AnnotationParser {
val extracts = propertiesCapture.findAllIn(string).matchData.map {
i =>
Try {
val fullString = i.source

val key = i.group("key").trim
val name = i.group("name").trim
val transform = i.group("transformRef")
val askOption = Option(i.group("askJson"))

val value = if (transform != null) {

val namespace = i.group("namespace")
val packageName = i.group("packageName")
val version = Option(i.group("version")).getOrElse("latest")
val id = i.group("id")

require(!Set(namespace, packageName, version, id).contains(null))

val transformationRef = TransformationRef(Some(PackageRef(namespace + ":" + packageName, version)), id)

ExpressionValue(name, transformationRef, askOption)
} else {
StringValue(name)
val value: AnnotationValues = key match {
case "source" => {
transformationCapture.findFirstMatchIn(fullString).map { case m =>
val name = m.group("name").trim
val namespace = m.group("namespace")
val packageName = m.group("packageName")
val askOption = Option(m.group("askJson"))
val version = Option(m.group("version")).getOrElse("latest")
val id = m.group("id")

require(!Set(namespace, packageName, version, id).contains(null))

val transformationRef = TransformationRef(Some(PackageRef(namespace + ":" + packageName, version)), id)

ExpressionValue(name, transformationRef, askOption)
}.get
}
case "name" => StringValue(name)
case "tag" => StringValue(name)
case "filename" => StringValue(name)
}

(key, value)
}
}

extracts.collect {case Success(a) => a} .toMap
} else Map.empty
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ package object annotations {

//Regexes
def topLevelCapture = "^(\\s*([a-z]+)\\s*:\\s*[a-zA-z \\-\\>\\{\\}\\.\\d\\@\\/\\:\\'\\\"]+)(,\\s*([a-z]+)\\s*:\\s*[a-zA-z \\-\\>\\{\\}\\.\\d\\@\\/\\:\\'\\\"]+)*".r
def propertiesCapture = s"\\s*([a-z]+)\\s*:\\s*([a-zA-z ]+)(?:\\s*->\\s*($packages)\\s*(\\{.*\\}){0,1}){0,1}"
.r("key", "name", "transformRef", "namespace", "packageName", "version", "id", "askJson")
def propertiesCapture = s"\\s*([a-z]+)\\s*:\\s*([a-zA-z/\\-:> ]+)".r("key", "name")

def transformationCapture = s"\\s*([a-z]+)\\s*:\\s*([a-zA-z/\\?:-:?:> ]+)(?:\\s*->\\s*($packages)\\s*(\\{.*\\}){0,1}){0,1}"
.r("key", "name", "transformRef", "namespace", "packageName", "version", "id", "askJson")
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import scalax.collection.mutable.Graph
import com.opticdev.core.sourcegear.gears.helpers.RuleEvaluation.RawRuleWithEvaluation
import com.opticdev.core.sourcegear.gears.helpers.RuleEvaluation.VariableRuleWithEvaluation
import com.opticdev.core.sourcegear.variables.VariableManager
import com.opticdev.experimental_features.ImplicitObjectRefs

import scala.util.hashing.MurmurHash3
import com.opticdev.marvin.common.helpers.LineOperations
Expand Down Expand Up @@ -176,7 +177,7 @@ case class ParseAsModel(description: NodeDescription,
val (objectRefOption, sourceAnnotationOption, tagAnnotation) = {
val raw = AnnotationParser.contentsToCheck(matchResults.baseNode.get)
val annotations = AnnotationParser.extract(raw, schema)(sourceGearContext.parser)
( annotations.collectFirst { case na: NameAnnotation => na }.map(_.objectRef),
( annotations.collectFirst { case na: NameAnnotation => na.objectRef },
annotations.collectFirst { case sa: SourceAnnotation => sa },
annotations.collectFirst { case ta: TagAnnotation => ta },
)
Expand All @@ -192,7 +193,7 @@ case class ParseAsModel(description: NodeDescription,
containerMapping,
this,
variableMapping,
objectRefOption,
if (objectRefOption.isEmpty) ImplicitObjectRefs.objectRefForModelNode(schema, model) else objectRefOption, //override with implicit naming function
sourceAnnotationOption,
tagAnnotation,
internal)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.opticdev.experimental_features

import com.opticdev.common.{ObjectRef, SchemaRef}
import play.api.libs.json.{JsObject, JsString}

import scala.util.Try

object ImplicitObjectRefs {

val presets: Map[String, JsObject => Try[String]] = {

val endpointName = (value: JsObject) => Try {
val method = (value \ "method").get.as[JsString].value
val url = (value \ "url").get.as[JsString].value

s"""${method.toUpperCase} ${url}"""
}

Map(
"optic:rest/route" -> endpointName,
"apiatlas:schemas/endpoint" -> endpointName
)

}

def objectRefForModelNode(schemaRef: SchemaRef, value: JsObject) = {
val result = presets.get(schemaRef.internalFull).map(_(value))
if (result.isDefined && result.get.isSuccess) {
Some(ObjectRef(result.get.get))
} else {
None
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ class AnnotationParserSpec extends TestBase {
assert(map == Map("name" -> StringValue("Test Name")))
}

it("works for multiple keys") {
val map = AnnotationParser.extractRawAnnotationsFromLine("name: Test Name, source: Other")
assert(map == Map("name" -> StringValue("Test Name"), "source" -> StringValue("Other")))
it("works for single key with special chars") {
val map = AnnotationParser.extractRawAnnotationsFromLine("name: POST /test-route/:id")
assert(map == Map("name" -> StringValue("POST /test-route/:id")))
}

it("last assignment wins") {
val map = AnnotationParser.extractRawAnnotationsFromLine("name: Test Name, source: Other, name: second")
assert(map == Map("name" -> StringValue("second"), "source" -> StringValue("Other")))
val map = AnnotationParser.extractRawAnnotationsFromLine("name: Test Name, name: second")
assert(map == Map("name" -> StringValue("second")))
}

it("invalid annotation returns empty map") {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.opticdev.experimental_features

import com.opticdev.common.{ObjectRef, SchemaRef}
import org.scalatest.FunSpec
import play.api.libs.json.{JsObject, JsString}

class ImplicitObjectRefsSpec extends FunSpec {

it("will provide a default name for endpoints") {

val result = ImplicitObjectRefs.objectRefForModelNode(SchemaRef.fromString("optic:[email protected]/route").get, JsObject(Seq(
"url" -> JsString("/hello-world"),
"method" -> JsString("post")
)))

assert(result.contains(ObjectRef("POST /hello-world")))

}

it("will return an empty option if a naming function isn't specified") {

val result = ImplicitObjectRefs.objectRefForModelNode(SchemaRef.fromString("optic:[email protected]/otherpackage").get, JsObject.empty)

assert(result.isEmpty)

}

}

0 comments on commit 881167b

Please sign in to comment.