Skip to content

Instantly share code, notes, and snippets.

@bdelacretaz
Created October 12, 2017 15:28
Show Gist options
  • Save bdelacretaz/52e9c89c7e8f6e3fb6f682a18e803315 to your computer and use it in GitHub Desktop.
Save bdelacretaz/52e9c89c7e8f6e3fb6f682a18e803315 to your computer and use it in GitHub Desktop.
Groovy DSL example
import groovy.xml.MarkupBuilder
/* Simple Groovy DSL example
* slightly adapted from https://dzone.com/articles/groovy-dsl-simple-example
*/
class DslTest extends GroovyTestCase {
void testDslUsage_outputText() {
def memo = MemoDsl.make {
to "Nirav Assar"
from "Barack Obama"
body "How are things? We are doing well. Take care"
idea "The economy is key"
request "Please vote for me"
machin 12 + 42 + " oubien?"
for(int i=0 ; i < 5; i++) {
trukk i
}
}
memo.text
memo.xml
}
}
class Section {
String title
String body
}
class MemoDsl {
String toText
String fromText
String body
def sections = []
/**
* This method accepts a closure which is essentially the DSL. Delegate the closure methods to
* the DSL class so the calls can be processed
*/
def static MemoDsl make(closure) {
MemoDsl memoDsl = new MemoDsl()
// any method called in closure will be delegated to the memoDsl class
closure.delegate = memoDsl
closure()
return memoDsl
}
/**
* Store the parameter as a variable and use it later to output a memo
*/
def to(String toText) {
this.toText = toText
}
def from(String fromText) {
this.fromText = fromText
}
def body(String bodyText) {
this.body = bodyText
}
/**
* When a method is not recognized, assume it is a title for a new section. Create a simple
* object that contains the method name and the parameter which is the body.
*/
def methodMissing(String methodName, args) {
def section = new Section(title: methodName, body: args[0])
sections << section
}
/**
* 'get' methods get called from the dsl by convention. Due to groovy closure delegation,
* we had to place MarkUpBuilder and StringWrite code in a static method as the delegate of the closure
* did not have access to the system.out
*/
def getXml() {
doXml(this)
}
def getText() {
doText(this)
}
/**
* Use markupBuilder to create a customer xml output
*/
private static doXml(MemoDsl memoDsl) {
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.memo() {
to(memoDsl.toText)
from(memoDsl.fromText)
body(memoDsl.body)
// cycle through the stored section objects to create an xml tag
for (s in memoDsl.sections) {
"$s.title"(s.body)
}
}
println writer
}
/**
* Use markupBuilder to create an html xml output
*/
private static doText(MemoDsl memoDsl) {
String template = "Memo\nTo: ${memoDsl.toText}\nFrom: ${memoDsl.fromText}\n${memoDsl.body}\n"
def sectionStrings =""
for (s in memoDsl.sections) {
sectionStrings += s.title.toUpperCase() + "\t" + s.body + "\n"
}
template += sectionStrings
println template
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment