Slide 1

Slide 1 text

Groovy Dierk König, Canoo Donnerstag, 1. November 12

Slide 2

Slide 2 text

Die sieben Einsatzmuster Alleskleber Weiches Herz Endoskop Kluge Anpassung Grenzenlose Offenheit Heinzelmännchen Prototyp Beispiele in Groovy Donnerstag, 1. November 12

Slide 3

Slide 3 text

#1 Alleskleber Build application from existing building blocks Java makes perfect infrastructure: middleware, frameworks, widget sets, services Scripting makes a flexible (agile) applikation layer: views und controller Grails, GSP, JBoss Seam, WebWork, Struts 2 Actions,... Example: combination of XML parser, Java networking and Swing widget set in order to build a standard RSS feed reader Donnerstag, 1. November 12

Slide 4

Slide 4 text

def url ='http://www.groovyblogs.org/feed/rss' def items = new XmlParser().parse(url).channel.item def cols = 'pubDate title description'.tokenize() def swing = new groovy.swing.SwingBuilder() def frame = swing.frame(title: 'Groovy Blogs') { scrollPane { table { tableModel(list: items) { cols.each { col -> closureColumn header: col, read: { it[col].text() } } } } } } frame.pack() frame.visible = true Alleskleber Beispiel: RSS Reader Donnerstag, 1. November 12

Slide 5

Slide 5 text

#2 Weiches Herz Externalize business models Given application structure in Java Allow to learn about the business: keep entities, relations, and behaviour flexible through scripting Usages: Spring beans, JBoss components,rule engines (groovyrules.dev.java.net, JSR-94), Grails, enterprise risk management for world-leading insurances Example: calculation rules for bonus allocation Donnerstag, 1. November 12

Slide 6

Slide 6 text

revenue = employee.revenue switch(revenue / 1000) { case 0..100 : return revenue * 0.04 case 100..200 : return revenue * 0.05 case {it > 200} : bonusClub.add employee return revenue * 0.06 } Weiches Herz Beispiel: Boni verteilen Binding binding = new Binding(); binding.setVariable("employee", employee); binding.setVariable("bonusClub", bonusClub); GroovyShell shell = new GroovyShell(binding); File script = new File(filename); float bonus = (float) shell.evaluate(script); Donnerstag, 1. November 12

Slide 7

Slide 7 text

#3 Endoskop Minimal-invasive surgery "in vivo" Lots of need for runtime inspection and modifications Ad-hoc queries are not foreseeable "Backdoor" for the live execution of scripts Particularly useful for product support, failure analysis, hot fixes, emergencies Usages: Oracle JMX Beans, XWiki, SnipSnap, Ant, Canoo WebTest, Grails Console, ULC Admin Console Demo: a Swing remote contol Donnerstag, 1. November 12

Slide 8

Slide 8 text

def ds = Config.dataSource ds.connection = new DebugConnection(ds.connection) Endoskopische Operation: im Servlet users = servletContext.getAttribute('users') bad = users.findAll { user -> user.cart.items.any { it.price < 0 } } servletContext.setAttribute('users', users - bad) Probleme mit der Datenbank Verbindung? Gefährliche Benutzer rauswerfen Donnerstag, 1. November 12

Slide 9

Slide 9 text

#4 Kluge Anpassung Enhance configuration with logic Replace dumb XML configs Use references, loops, conditionals, inheritance, execution logic, runtime environment adaption, ... Typical scenario for domain specific languages (DSLs), Groovy Builder, Grails plugins, user macros, personalisation, product customization Example: Navis SPARCS N4 Donnerstag, 1. November 12

Slide 10

Slide 10 text

def ensureEvent = { change -> if (! event.getMostRecentEvent(change)) { event.postNewEvent(change) } } switch (event.REROUTE_CTR) { case 'OutboundCarrierId' : ensureEvent('CHANGE_VSL') break case 'POD' : if (! event.CHANGE_VSL) ensureEvent('CHANGE_POD') break } Kluge Anpassung für container routing Donnerstag, 1. November 12

Slide 11

Slide 11 text

#5 Grenzenlose Offenheit Every line of code may be changed It's impossible (and not desirable!) to design for every possible future requirement Allow for easily changing the code without tedious setup for compilation and deployment Follow the lessons of Perl, PHP, Python,... Example: groovyblogs.org Donnerstag, 1. November 12

Slide 12

Slide 12 text

#6 Heinzelmännchen Delegate the housework Build automation, continuous integration, deployment, installer, service monitoring, reports, statistics, automated documentation, functional tests, HTML scraping, Web remote control, XML- RPC, REST, WebServices Usages with Ant, Maven, AntBuilder, Gant, Canoo WebTest, Grails scaffolding, ... Examples: sending mails via dynamic Ant scripting, hooking scripts into Ant Donnerstag, 1. November 12

Slide 13

Slide 13 text

def users = [ [name:'Dierk', email:'[email protected]'], [name:'Other', email:'[email protected]'] ] def ant = new AntBuilder() for (user in users) { ant.mail(mailhost: 'my.email.server', subject: 'build done') { from address: '[email protected]' to address: user.email message """ Dear ${user.name}, a new build has finished at ${new Date().toGMTString()}""" } } Heinzelmännchen Beispiel: mail schicken Donnerstag, 1. November 12

Slide 14

Slide 14 text

import org.apache.tools.ant.* import org.jfugue.* project.addBuildListener(new PlayListener()) class PlayListener implements BuildListener { def play = { new Player().play(new Pattern(it)) } void buildStarted(event) { } void buildFinished(event) { } void messageLogged(event) { } void targetStarted(event) { play("D E") } void targetFinished(event) { play("C5maj") } void taskStarted(event) { } void taskFinished(event) { } } Heinzelmännchen II: musikalisches Ant Donnerstag, 1. November 12

Slide 15

Slide 15 text

import org.apache.tools.ant.* import org.jfugue.* def play = { new Player().play( new Pattern(it) ) } def player = [ targetStarted : { play "D E" } targetFinished : { play "C5maj" } ] project.addBuildListener(player as BuildListener ) Es geht auch ein bisschen grooviger ... Donnerstag, 1. November 12

Slide 16

Slide 16 text

#7 Prototyp Feasibility study on the target platform "Spikes" for technological or algorithmic ideas with more expressiveness, quicker feedback, and enhanced analysis capabilities Later port to Java is optional Usages: early user feedback about the domain model through a functional Grails prototype, algorithms for image manipulation Example: prime number disassembly Donnerstag, 1. November 12

Slide 17

Slide 17 text

boolean isPrime(x) { return ! (2.. x % y == 0 } } int primeBelow(x) { (x..1).find { isPrime(it) } } List primeFactors(x) { if (isPrime(x)) return [x] int p = primeBelow(x) while (p > 1) { if (x % p == 0) return [p, *primeFactors(x.intdiv(p))] p = primeBelow(p-1) } } for (n in 100..110) { println "$n : "+primeFactors(n)} Prototype example: prime numbers Donnerstag, 1. November 12

Slide 18

Slide 18 text

class ModCountCategory { static int count = 0 static int mod(Integer self, Integer argument) { count++ return self - argument * self.intdiv(argument) } } use (ModCountCategory) { for (n in 1000..1010) { ModCountCategory.count = 0 factors = primeFactors(n) println "$n : $factors".padRight(30) + "(in " + "${ModCountCategory.count}".padLeft(5) + " steps)" assert n == factors.inject(1){result, item -> result *= item } } } Prime numbers: counting modulo ops Donnerstag, 1. November 12

Slide 19

Slide 19 text

Einsatzmuster Zusammenfassung Alleskleber Weiches Herz Endoskop Kluge Anpassung Grenzenlose Offenheit Heinzelmännchen Prototyp Keep groovin' ! Lipstick Ghostwriter NEU Donnerstag, 1. November 12

Slide 20

Slide 20 text

Weitere Informationen • Groovy in Action groovy.canoo.com/gina Manning, 2007, Foreword by James Gosling König mit Glover, Laforge, King, Skeet • groovy.codehaus.org, grails.org groovyblogs.org, searchgroovy.org Donnerstag, 1. November 12

Slide 21

Slide 21 text

Fragen? Donnerstag, 1. November 12