Last active
September 4, 2020 03:17
-
-
Save christoph-daehne/a7b60503799c64f6afbf to your computer and use it in GitHub Desktop.
Groovy DSL examples, see https://sandstorm.de/de/blog/post/how-to-create-a-dsl-with-groovy.html
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
// our configuration model | |
class BouquetConfiguration extends ArrayList<String> { | |
int howMany(String flower) { | |
return this.count { it == flower } | |
} | |
String toString() { | |
return "Bouquet: " + this.toString() | |
} | |
} | |
// our DSL keyword | |
class BouquetConfigurationDsl { | |
private final BouquetConfiguration bouquet | |
BouquetConfigurationDsl(BouquetConfiguration bouquet) { | |
this.bouquet = bouquet | |
} | |
void flower(String flower) { | |
bouquet << flower | |
} | |
} | |
class Bouquet { | |
static BouquetConfiguration create( | |
@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = BouquetConfigurationDsl) Closure script | |
) { | |
def bouquet = new BouquetConfiguration() | |
script.resolveStrategy = Closure.DELEGATE_ONLY | |
script.delegate = new BouquetConfigurationDsl(bouquet) | |
script() | |
return bouquet | |
} | |
} | |
def bouquet = Bouquet.create { | |
flower "cornflower" | |
flower "cornflower" | |
flower "poppy" | |
flower "calendula" | |
} | |
println bouquet |
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
// our configuration model | |
class BouquetConfiguration { | |
private final List<String> flowers = [] | |
// method for use at runtime | |
int howMany(String flower) { | |
return flowers.count { it == flower } | |
} | |
// DSL keyword for use at DSL execution | |
void flower(String flower) { | |
flowers << flower | |
} | |
String toString() { | |
return "Bouquet: " + flowers.toString() | |
} | |
} | |
class Bouquet { | |
static BouquetConfiguration create( | |
@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = BouquetConfiguration) Closure script | |
) { | |
def bouquet = new BouquetConfiguration() | |
script.resolveStrategy = Closure.DELEGATE_ONLY | |
script.delegate = bouquet | |
script() | |
return bouquet | |
} | |
} | |
def bouquet = Bouquet.create { | |
flower "cornflower" | |
flower "cornflower" | |
flower "poppy" | |
flower "calendula" | |
} | |
println bouquet |
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
class BouquetConfiguration extends ArrayList<String> { | |
int howMany(String flower) { | |
return this.count { it == flower } | |
} | |
String toString() { | |
return "Bouquet: " + this.toString() | |
} | |
} | |
class FloristConfiguration { | |
final Map<String, BouquetConfiguration> catalog = [:] | |
String toString() { | |
return "Florist: " + catalog.toString() | |
} | |
} | |
class BouquetConfigurationDsl { | |
private final BouquetConfiguration bouquet | |
BouquetConfigurationDsl(BouquetConfiguration bouquet) { | |
this.bouquet = bouquet | |
} | |
void flower(String flower) { | |
bouquet << flower | |
} | |
} | |
class FloristConfigurationDsl { | |
private final FloristConfiguration florist | |
FloristConfigurationDsl(FloristConfiguration florist) { | |
this.florist = florist | |
} | |
BouquetConfiguration bouquet( | |
String name, | |
@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = BouquetConfigurationDsl) Closure script | |
) { | |
def bouquet = florist.catalog[name] | |
if (bouquet == null) { | |
bouquet = florist.catalog[name] = new BouquetConfiguration() | |
} | |
script.resolveStrategy = Closure.DELEGATE_ONLY | |
script.delegate = new BouquetConfigurationDsl(bouquet) | |
script() | |
return bouquet | |
} | |
} | |
class Florist { | |
static FloristConfiguration create( | |
@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = FloristConfigurationDsl) Closure script | |
) { | |
def florist = new FloristConfiguration() | |
script.resolveStrategy = Closure.DELEGATE_ONLY | |
script.delegate = new FloristConfigurationDsl(florist) | |
script() | |
return florist | |
} | |
} | |
def florist = Florist.create { | |
bouquet "meadow", { | |
flower "cornflower" | |
flower "cornflower" | |
flower "poppy" | |
flower "calendula" | |
} | |
bouquet "roses", { | |
flower "rose" | |
flower "rose" | |
flower "rose" | |
flower "rose" | |
} | |
// add another calendula to existing bouquet | |
bouquet "meadow", { | |
flower "calendula" | |
} | |
} | |
println florist |
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
class HelloWorldService { | |
// this function becomes a keyword in our DSL | |
void printHelloWorld() { | |
println("Hello World") | |
} | |
} | |
class HelloWorldScript { | |
static void execute(Closure script) { | |
// here we wire the colure with the service | |
script.delegate = new HelloWorldService() | |
// i explain this line in a later example ;) | |
script.resolveStrategy = Closure.DELEGATE_ONLY | |
// the closure is executed in the context of its delegate | |
script() | |
} | |
} | |
HelloWorldScript.execute { | |
printHelloWorld() | |
for(def i = 0; i < 10; i++) { | |
printHelloWorld() | |
} | |
} |
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
class HelloWorldService { | |
void printHelloWorld() { | |
println("Hello World") | |
} | |
} | |
class HelloWorldScript { | |
// by annotating the parameter we gain syntax highlighting and auto-completion | |
static void execute(@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = HelloWorldService) Closure script) { | |
script.resolveStrategy = Closure.DELEGATE_ONLY | |
script.delegate = new HelloWorldService() | |
script() | |
} | |
} | |
HelloWorldScript.execute { | |
printHelloWorld() | |
for(def i = 0; i < 10; i++) { | |
printHelloWorld() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment