Created
May 13, 2015 19:11
-
-
Save dclucas/63abdb4356cba33b68f7 to your computer and use it in GitHub Desktop.
This file contains 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
// ---------------------------------------------- | |
// Builder implementation and supporting classes. | |
// ---------------------------------------------- | |
import groovy.transform.* | |
@Canonical | |
class Definition { | |
Map<String, Schema> schemas = [:] | |
def methodMissing(String name, args) { | |
println "Definition.MethodMissing: $name" | |
def schema = new Schema() | |
schemas[name] = schema | |
Definition.runClosure(args[0], schema, this) | |
schemas | |
} | |
static def runClosure(Closure cl, Object delegate, Object owner) { | |
println "Definition.runClosure" | |
def code = cl.rehydrate(delegate, owner, owner) | |
code.resolveStrategy = Closure.DELEGATE_ONLY | |
code() | |
} | |
static def setProperty(Object obj, String property, Object value, boolean throwOnMiss = true) { | |
if (obj.hasProperty(property)) { | |
obj[property] = value | |
return true | |
} | |
if (throwOnMiss) { | |
throw new MissingPropertyException(property, obj.class) | |
} | |
} | |
} | |
@Canonical | |
class Path { | |
Map<String, PathSpec> paths = [:] | |
def methodMissing(String name, args) { | |
println "Path.MethodMissing: $name" | |
def spec = new PathSpec() | |
paths[name] = spec | |
Definition.runClosure(args[0], spec, this) | |
paths | |
} | |
} | |
@Canonical | |
class PathSpec { | |
private PathSpec parent | |
PathSpec(parent = null) { | |
this.parent = parent | |
} | |
Map<String, PathSpec> children = [:] | |
VerbSpec get, post, patch, delete | |
def methodMissing(String name, args) { | |
println "PathSpec.MethodMissing: $name" | |
if (name.startsWith('/')) { | |
def innerSpec = new PathSpec(this) | |
Definition.runClosure(args[0], innerSpec, this) | |
children[name] = innerSpec | |
return innerSpec | |
} | |
def verb = new VerbSpec(args[0]) | |
Definition.setProperty(this, name, verb) | |
verb | |
} | |
} | |
@Canonical | |
class VerbSpec { | |
Closure run | |
VerbSpec document | |
VerbSpec(Closure cl) { | |
run = cl | |
} | |
def methodMissing(String name, args) { | |
println "VerbSpec.MethodMissing: $name" | |
Definition.setProperty(this, name, new VerbSpec(args[0])) | |
} | |
} | |
@Canonical | |
class Schema { | |
PropertyList properties = new PropertyList() | |
List<String> required = [] | |
def methodMissing(String name, args) { | |
println "Schema.methodMissing $name" | |
switch (name) { | |
case "properties": | |
Definition.runClosure(args[0], properties, this); | |
break; | |
case "required": | |
this.required = args | |
} | |
} | |
} | |
@Canonical | |
class PropertyList extends HashMap<String, Property> { | |
def methodMissing(String name, args) { | |
println "PropertyList.methodMissing $name" | |
def prop = new Property() | |
Definition.runClosure(args[0], prop, this) | |
this[name] = prop | |
} | |
} | |
@Canonical | |
class Property { | |
String type | |
String description | |
def methodMissing(String name, args) { | |
println "Property.methodMissing $name" | |
Definition.setProperty(this, name, args[0]) | |
} | |
} | |
def d = new Definition().Comment { | |
properties { | |
id { | |
type 'Integer' | |
description 'The comment id' | |
} | |
name { | |
type 'String' | |
description 'The comment name' | |
} | |
} | |
required 'id', 'name' | |
} | |
assert d.Comment.properties.size() == 2 | |
assert d.Comment.properties.id.type == 'Integer' | |
println d | |
def p = new Path()."/comments" { | |
get { req, res -> | |
"comments.GET" | |
} | |
post { req, res -> | |
"comments.POST" | |
}.document { docs -> | |
docs.description = "Description for comments.POST" | |
docs | |
} | |
"/:id" { | |
get {req, res -> "comments/:id.GET"} | |
patch {req, res -> "comments/:id.PATCH"} | |
.document { docs -> docs.operationId = "commentUpdate"; docs } | |
delete {req, res -> "comments/:id.DELETE"} | |
} | |
} | |
assert p."/comments" | |
assert p."/comments".get.run(null, null) == "comments.GET" | |
assert p."/comments".post.run(null, null) == "comments.POST" | |
assert p."/comments".post.document.run([ summary: "Summary for comments.POST"]) == | |
[ summary: "Summary for comments.POST", description: "Description for comments.POST"] | |
assert p."/comments".children."/:id".get.run(null, null) == "comments/:id.GET" | |
assert p."/comments".children."/:id".patch.document.run([:]) == [ operationId: "commentUpdate" ] | |
println p | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment