Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Script your Java applications with Groovy

Script your Java applications with Groovy

Tips & Tricks for Groovy DSL development: ExtensionModule, CompilerConfiguration, ScriptBaseClass, ImportCustomizer, GroovyObjectSupport, DefaultTypeTransformation, DefaultGroovyMethods

Reinhard Pointner

October 14, 2016
Tweet

Other Decks in Programming

Transcript

  1. Outline • What is Groovy? Why Groovy? • Tips &

    Tricks for Groovy DSL development from Java • ExtensionModule • CompilerConfiguration • ScriptBaseClass • ImportCustomizer • GroovyObjectSupport • DefaultTypeTransformation • DefaultGroovyMethods
  2. Java VS Groovy Java Groovy Syntax Strict Lenient Code Verbose

    “Groovy 1-Liners” Strength Clean & Readable & Robust
 Code Developer Productivity Great for large products! Great for 3rd party scripts!
  3. ExtensionModule “Adding Properties and Methods” 1.pad 2 // 02 “台灣".pinyin

    // tái wān "Groovy".toUpperCase() // GROOVY "uname -m".execute().text // x86_64 ❶ Java API ❷ Groovy Default Methods ❸ My Default Methods
  4. ExtensionModule “Adding Properties and Methods” ❶ META-INF/services/org.codehaus.groovy.runtime.ExtensionModule ❷ jcconf.groovy.script.CustomExtensionMethods moduleName=GroovyTableCustomExtensionMethods

    moduleVersion=1.0 extensionClasses=jcconf.groovy.script.CustomExtensionMethods public static String pad(Number self, int length) { return String.format("%0" + length + "d", self); } public static String getPinyin(String self) { return Transliterator.getInstance("Han-Latin").transform(self); }
  5. ScriptBaseClass “Variables and default values” public Object getProperty(String property) {

    try { return super.getProperty(property); } catch (MissingPropertyException e) { return null; } } ❶ jcconf.groovy.script.CustomScriptBaseClass ❷ Undefined variables now default to null println asdf // null Groovy with default ScriptBaseClass: groovy.lang.MissingPropertyException: No such property: asdf
  6. ImportCustomizer “Adding default imports” ❶ GroovyScriptEngine << GroovyClassLoader << CompilerConfiguration

    ❷ Use imported classes and static methods or static fields ImportCustomizer imports = new ImportCustomizer(); imports.addStaticStars(Math.class.getName()); compilerConfiguration.addCompilationCustomizers(imports); sqrt(4) // 2 Groovy with default CompilerConfiguration: import static java.lang.Math.* sqrt(4) // 2
  7. GroovyObjectSupport “Dynamic Properties and Methods” ❶ Override invokeMethod and getProperty

    public class Undefined extends GroovyObjectSupport { […] public Object getProperty(String property) { return new Undefined(name + "." + property); } public Object invokeMethod(String method, Object args) { return new Undefined(name + "." + method + "()"); } } ❷ Groovy: x.y.z() // Undefined: x.y.z()
  8. DefaultTypeTransformation “Getting to the Groovy Truth” ❶ Groovy Truth: ❷

    Groovy Truth from Java: null as boolean // false '' as boolean // false [] as boolean // false 0 as boolean // false DefaultTypeTransformation.castToBoolean(object) // Groovy Truth * Also useful for casting Groovy closures as Java interfaces: DefaultTypeTransformation.castToType(closure, FileFilter.class) def closure = { f -> f.hidden } ❶ Groovy: ❷ Java:
  9. DefaultGroovyMethods “Using the Groovy methods from Java” ❶ Groovy: ❷

    Java: def condition = { it % 2 == 0 } […] return (1..10).findAll(condition).join(', ') // 2, 4, 6, 8, 10 Range range = new IntRange(1, 10); Iterable values = DefaultGroovyMethods.findAll(range, condition); return DefaultGroovyMethods.join(values, ", "); // Groovy Closure `condition` is a given
  10. ❶ Groovy: StringWriter sw = new StringWriter() new groovy.xml.MarkupBuilder(sw).html{ body{

    p(id:1, 'Groovy') } } println sw.toString() Closure.rehydrate() “Invoking the Groovy Builder Pattern” ❷ Java: ❸ My Groovy: <html> <body> <p id='1'>Groovy</p> </body> </html> XML{ html{ body{ p(id:1, 'Groovy') } } } public String XML(Closure closure) { StringWriter sw = new StringWriter(); MarkupBuilder mb = new MarkupBuilder(sw); closure.rehydrate(closure.getDelegate(), mb, mb).call(); return sw.toString();
  11. println XML{ jcconf(year:2016){ talk{ name('Script your Java applications with Groovy')

    github('https://github.com/rednoah/GroovyTableFormat') speaker{ name(lang:'en', 'Reinhard Pointner') name(lang:'zh', '郝瑞尼') email('[email protected]') github('https://github.com/rednoah') } } } } // Goodbye! System.exit(0)