|
Groovy example source code file (Gep3OrderDslTest.groovy)
The Groovy Gep3OrderDslTest.groovy source codepackage gls.syntax import org.codehaus.groovy.control.CompilerConfiguration /** * @author Guillaume Laforge */ class Gep3OrderDslTest extends GroovyTestCase { @Override protected void setUp() { super.setUp() // syntax for 200.shares Integer.metaClass.getShares = { -> delegate } } @Override protected void tearDown() { // remove the getShares method by restoring the original metaclass for Integer Integer.metaClass = null super.tearDown() } void testDsl() { // use the script binding for silent sentence words like "to", "the" def binding = new CustomBinding() def config = new CompilerConfiguration() config.scriptBaseClass = OrderDslBaseScriptClass.name def shell = new GroovyShell(this.class.classLoader, binding, config) def script = shell.parse(''' order to buy 200.shares of GOOG { limitPrice 500 allOrNone false at the value of { qty * unitPrice - 100 } } order to sell 150.shares of VMW { limitPrice 80 allOrNone true at the value of { qty * unitPrice } } ''') script.run() List<Order> orders = script.getAllOrders() assert orders.size() == 2 assert orders[0].action == Action.Buy assert orders[0].allOrNone == false assert orders[0].limitPrice == 500 assert orders[0].quantity == 200 assert orders[0].security.name == 'GOOG' assert orders[1].action == Action.Sell assert orders[1].allOrNone == true assert orders[1].limitPrice == 80 assert orders[1].quantity == 150 assert orders[1].security.name == 'VMW' } } abstract class OrderDslBaseScriptClass extends Script { List<Order> allOrders = [] /** Script helper method for "GOOG {}", "VMW {}", etc. */ def methodMissing(String name, args) { new SecurityAndCharacteristics( security: new Security(name: name), characteristics: args[0] ) } /** Script helper method to make "order to" silent by just creating our current order */ def order(to) { def o = new Order() allOrders << o return o } } enum Action { Buy, Sell } class Order { Security security Integer quantity, limitPrice boolean allOrNone Closure valueCalculation Action action def buy(Integer quantity) { this.quantity = quantity this.action = Action.Buy return this } def sell(Integer quantity) { this.quantity = quantity this.action = Action.Sell return this } def limitPrice(Integer limit) { this.limitPrice = limit } def allOrNone(boolean allOrNone) { this.allOrNone = allOrNone } def at(Closure characteristicsClosure) { return this } def value(Closure valueCalculation) { this.valueCalculation = valueCalculation } /** Characteristics of the order: "of GOOG {...}" */ def of(SecurityAndCharacteristics secAndCharact) { security = secAndCharact.security Closure c = secAndCharact.characteristics.clone() c.resolveStrategy = Closure.DELEGATE_FIRST c.delegate = this c() return this } /** Valuation closure: "of { qty, unitPrice -> ... }" */ def of(Closure valueCalculation) { // in order to be able to define closures like { qty * unitPrice } // without having to explicitely pass the parameters to the closure // we can wrap the closure inside another one // and that closure sets a delegate to the qty and unitPrice variables def wrapped = { qty, unitPrice -> Closure cloned = valueCalculation.clone() cloned.resolveStrategy = Closure.DELEGATE_FIRST cloned.delegate = [qty: qty, unitPrice: unitPrice] cloned() } return wrapped } String toString() { "$action $quantity shares of $security.name at limit price of $limitPrice" } } class Security { String name } class SecurityAndCharacteristics { Security security Closure characteristics } class CustomBinding extends Binding { def getVariable(String word) { // return System.out when the script requests to write to 'out' if (word == "out") System.out // don't thrown an exception and return null // when a silent sentence word is used, // like "to" and "the" in our DSL null } } Other Groovy examples (source code examples)Here is a short list of links related to this Groovy Gep3OrderDslTest.groovy source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.