Soumettre la recherche
Mettre en ligne
Groovy.Tutorial
•
8 j'aime
•
1,433 vues
L
Larry Cheng
Suivre
an overview of groovy technology
Lire moins
Lire la suite
Business
Technologie
Signaler
Partager
Signaler
Partager
1 sur 104
Télécharger maintenant
Télécharger pour lire hors ligne
Recommandé
groovy
groovy
Shilong Sang
JSR-299 (CDI), Weld & the Future of Seam (JavaOne 2010)
JSR-299 (CDI), Weld & the Future of Seam (JavaOne 2010)
Dan Allen
Throwing complexity over the wall: Rapid development for enterprise Java (Jav...
Throwing complexity over the wall: Rapid development for enterprise Java (Jav...
Dan Allen
CDI and Weld
CDI and Weld
jensaug
Moving to Java EE 6 and CDI and away from the clutter
Moving to Java EE 6 and CDI and away from the clutter
Dan Allen
10 generics a-4_in_1
10 generics a-4_in_1
arasforever
CDI, Weld and the future of Seam
CDI, Weld and the future of Seam
Dan Allen
Java 7 Dolphin manjula kollipara
Java 7 Dolphin manjula kollipara
Manjula Kollipara
Recommandé
groovy
groovy
Shilong Sang
JSR-299 (CDI), Weld & the Future of Seam (JavaOne 2010)
JSR-299 (CDI), Weld & the Future of Seam (JavaOne 2010)
Dan Allen
Throwing complexity over the wall: Rapid development for enterprise Java (Jav...
Throwing complexity over the wall: Rapid development for enterprise Java (Jav...
Dan Allen
CDI and Weld
CDI and Weld
jensaug
Moving to Java EE 6 and CDI and away from the clutter
Moving to Java EE 6 and CDI and away from the clutter
Dan Allen
10 generics a-4_in_1
10 generics a-4_in_1
arasforever
CDI, Weld and the future of Seam
CDI, Weld and the future of Seam
Dan Allen
Java 7 Dolphin manjula kollipara
Java 7 Dolphin manjula kollipara
Manjula Kollipara
Polyglot OSGi
Polyglot OSGi
Matt Stine
Replication Tips & Trick for SMUG
Replication Tips & Trick for SMUG
Mats Kindahl
Replication Tips & Tricks
Replication Tips & Tricks
Mats Kindahl
2012 04-09-v2-tdp-1167-cdi-bestpractices-final
2012 04-09-v2-tdp-1167-cdi-bestpractices-final
Rohit Kelapure
HowTo Build an OSGI EJB3 Server
HowTo Build an OSGI EJB3 Server
ekkehard gentz
GlassFish REST Administration Backend
GlassFish REST Administration Backend
Arun Gupta
5050 dev nation
5050 dev nation
Arun Gupta
Template Building Workshop
Template Building Workshop
norton07302
Consolidated shared indexes in real time
Consolidated shared indexes in real time
Jeff Mace
Building Content Applications with JCR and OSGi
Building Content Applications with JCR and OSGi
Cédric Hüsler
[Pilarczyk] Adrenaline programing implementing - SOA and BPM in your application
[Pilarczyk] Adrenaline programing implementing - SOA and BPM in your application
javablend
Java Summit Chennai: JAX-RS 2.0
Java Summit Chennai: JAX-RS 2.0
Arun Gupta
New Features of Java7 SE
New Features of Java7 SE
dogangoko
Garbage Collection for Dummies
Garbage Collection for Dummies
輝 子安
Java, Up to Date
Java, Up to Date
輝 子安
Running your Java EE 6 applications in the Cloud
Running your Java EE 6 applications in the Cloud
Arun Gupta
groovy and concurrency
groovy and concurrency
Paul King
Groovy Testing Sep2009
Groovy Testing Sep2009
Paul King
Groovy Testing Aug2009
Groovy Testing Aug2009
guest4a266c
Terracotta Java Scalability - Stateless Versus Stateful Apps
Terracotta Java Scalability - Stateless Versus Stateful Apps
Matthew McCullough
Groovy Tutorial
Groovy Tutorial
Paul King
Asterisk-Java Framework Presentation
Asterisk-Java Framework Presentation
Justin Grammens
Contenu connexe
Tendances
Polyglot OSGi
Polyglot OSGi
Matt Stine
Replication Tips & Trick for SMUG
Replication Tips & Trick for SMUG
Mats Kindahl
Replication Tips & Tricks
Replication Tips & Tricks
Mats Kindahl
2012 04-09-v2-tdp-1167-cdi-bestpractices-final
2012 04-09-v2-tdp-1167-cdi-bestpractices-final
Rohit Kelapure
HowTo Build an OSGI EJB3 Server
HowTo Build an OSGI EJB3 Server
ekkehard gentz
GlassFish REST Administration Backend
GlassFish REST Administration Backend
Arun Gupta
5050 dev nation
5050 dev nation
Arun Gupta
Template Building Workshop
Template Building Workshop
norton07302
Consolidated shared indexes in real time
Consolidated shared indexes in real time
Jeff Mace
Building Content Applications with JCR and OSGi
Building Content Applications with JCR and OSGi
Cédric Hüsler
[Pilarczyk] Adrenaline programing implementing - SOA and BPM in your application
[Pilarczyk] Adrenaline programing implementing - SOA and BPM in your application
javablend
Java Summit Chennai: JAX-RS 2.0
Java Summit Chennai: JAX-RS 2.0
Arun Gupta
New Features of Java7 SE
New Features of Java7 SE
dogangoko
Garbage Collection for Dummies
Garbage Collection for Dummies
輝 子安
Java, Up to Date
Java, Up to Date
輝 子安
Running your Java EE 6 applications in the Cloud
Running your Java EE 6 applications in the Cloud
Arun Gupta
Tendances
(16)
Polyglot OSGi
Polyglot OSGi
Replication Tips & Trick for SMUG
Replication Tips & Trick for SMUG
Replication Tips & Tricks
Replication Tips & Tricks
2012 04-09-v2-tdp-1167-cdi-bestpractices-final
2012 04-09-v2-tdp-1167-cdi-bestpractices-final
HowTo Build an OSGI EJB3 Server
HowTo Build an OSGI EJB3 Server
GlassFish REST Administration Backend
GlassFish REST Administration Backend
5050 dev nation
5050 dev nation
Template Building Workshop
Template Building Workshop
Consolidated shared indexes in real time
Consolidated shared indexes in real time
Building Content Applications with JCR and OSGi
Building Content Applications with JCR and OSGi
[Pilarczyk] Adrenaline programing implementing - SOA and BPM in your application
[Pilarczyk] Adrenaline programing implementing - SOA and BPM in your application
Java Summit Chennai: JAX-RS 2.0
Java Summit Chennai: JAX-RS 2.0
New Features of Java7 SE
New Features of Java7 SE
Garbage Collection for Dummies
Garbage Collection for Dummies
Java, Up to Date
Java, Up to Date
Running your Java EE 6 applications in the Cloud
Running your Java EE 6 applications in the Cloud
Similaire à Groovy.Tutorial
groovy and concurrency
groovy and concurrency
Paul King
Groovy Testing Sep2009
Groovy Testing Sep2009
Paul King
Groovy Testing Aug2009
Groovy Testing Aug2009
guest4a266c
Terracotta Java Scalability - Stateless Versus Stateful Apps
Terracotta Java Scalability - Stateless Versus Stateful Apps
Matthew McCullough
Groovy Tutorial
Groovy Tutorial
Paul King
Asterisk-Java Framework Presentation
Asterisk-Java Framework Presentation
Justin Grammens
Groovy and Grails in Google App Engine
Groovy and Grails in Google App Engine
Guillaume Laforge
Project Zero For Javapolis 2007
Project Zero For Javapolis 2007
Jason McGee
GlassFish v3 at JavaZone 09
GlassFish v3 at JavaZone 09
Alexis Moussine-Pouchkine
Groovy Online 100
Groovy Online 100
reynolds
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Paul King
Groovy Power Features
Groovy Power Features
Paul King
Paulking groovy
Paulking groovy
d0nn9n
BeJUG JavaFx In Practice
BeJUG JavaFx In Practice
Pursuit Consulting
Quick Intro To JRuby
Quick Intro To JRuby
Frederic Jean
GlassFish v3 Prelude Aquarium Paris
GlassFish v3 Prelude Aquarium Paris
Alexis Moussine-Pouchkine
Galera Multi Master Synchronous My S Q L Replication Clusters
Galera Multi Master Synchronous My S Q L Replication Clusters
PerconaPerformance
Rails Scala Citec Presentation
Rails Scala Citec Presentation
dkristian
Ola Bini Evolving The Java Platform
Ola Bini Evolving The Java Platform
deimos
The Tantric Team: Getting Your Automated Build Groove On
The Tantric Team: Getting Your Automated Build Groove On
Atlassian
Similaire à Groovy.Tutorial
(20)
groovy and concurrency
groovy and concurrency
Groovy Testing Sep2009
Groovy Testing Sep2009
Groovy Testing Aug2009
Groovy Testing Aug2009
Terracotta Java Scalability - Stateless Versus Stateful Apps
Terracotta Java Scalability - Stateless Versus Stateful Apps
Groovy Tutorial
Groovy Tutorial
Asterisk-Java Framework Presentation
Asterisk-Java Framework Presentation
Groovy and Grails in Google App Engine
Groovy and Grails in Google App Engine
Project Zero For Javapolis 2007
Project Zero For Javapolis 2007
GlassFish v3 at JavaZone 09
GlassFish v3 at JavaZone 09
Groovy Online 100
Groovy Online 100
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Groovy Power Features
Groovy Power Features
Paulking groovy
Paulking groovy
BeJUG JavaFx In Practice
BeJUG JavaFx In Practice
Quick Intro To JRuby
Quick Intro To JRuby
GlassFish v3 Prelude Aquarium Paris
GlassFish v3 Prelude Aquarium Paris
Galera Multi Master Synchronous My S Q L Replication Clusters
Galera Multi Master Synchronous My S Q L Replication Clusters
Rails Scala Citec Presentation
Rails Scala Citec Presentation
Ola Bini Evolving The Java Platform
Ola Bini Evolving The Java Platform
The Tantric Team: Getting Your Automated Build Groove On
The Tantric Team: Getting Your Automated Build Groove On
Dernier
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...
daisycvs
Falcon Invoice Discounting: The best investment platform in india for investors
Falcon Invoice Discounting: The best investment platform in india for investors
Falcon Invoice Discounting
Eluru Call Girls Service ☎ ️93326-06886 ❤️🔥 Enjoy 24/7 Escort Service
Eluru Call Girls Service ☎ ️93326-06886 ❤️🔥 Enjoy 24/7 Escort Service
Damini Dixit
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
dlhescort
Call Girls From Raj Nagar Extension Ghaziabad❤️8448577510 ⊹Best Escorts Servi...
Call Girls From Raj Nagar Extension Ghaziabad❤️8448577510 ⊹Best Escorts Servi...
lizamodels9
Call Girls From Pari Chowk Greater Noida ❤️8448577510 ⊹Best Escorts Service I...
Call Girls From Pari Chowk Greater Noida ❤️8448577510 ⊹Best Escorts Service I...
lizamodels9
SEO Case Study: How I Increased SEO Traffic & Ranking by 50-60% in 6 Months
SEO Case Study: How I Increased SEO Traffic & Ranking by 50-60% in 6 Months
IndeedSEO
Business Model Canvas (BMC)- A new venture concept
Business Model Canvas (BMC)- A new venture concept
P&CO
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
Call Girls in Nagpur High Profile Call Girls
Falcon's Invoice Discounting: Your Path to Prosperity
Falcon's Invoice Discounting: Your Path to Prosperity
hemanthkumar470700
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Seo
Value Proposition canvas- Customer needs and pains
Value Proposition canvas- Customer needs and pains
P&CO
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...
amitlee9823
PHX May 2024 Corporate Presentation Final
PHX May 2024 Corporate Presentation Final
PanhandleOilandGas
Call Girls In Noida 959961⊹3876 Independent Escort Service Noida
Call Girls In Noida 959961⊹3876 Independent Escort Service Noida
dlhescort
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...
allensay1
Uneak White's Personal Brand Exploration Presentation
Uneak White's Personal Brand Exploration Presentation
uneakwhite
Al Mizhar Dubai Escorts +971561403006 Escorts Service In Al Mizhar
Al Mizhar Dubai Escorts +971561403006 Escorts Service In Al Mizhar
allensay1
Cracking the Cultural Competence Code.pptx
Cracking the Cultural Competence Code.pptx
Workforce Group
Cheap Rate Call Girls In Noida Sector 62 Metro 959961乂3876
Cheap Rate Call Girls In Noida Sector 62 Metro 959961乂3876
dlhescort
Dernier
(20)
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...
Falcon Invoice Discounting: The best investment platform in india for investors
Falcon Invoice Discounting: The best investment platform in india for investors
Eluru Call Girls Service ☎ ️93326-06886 ❤️🔥 Enjoy 24/7 Escort Service
Eluru Call Girls Service ☎ ️93326-06886 ❤️🔥 Enjoy 24/7 Escort Service
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls From Raj Nagar Extension Ghaziabad❤️8448577510 ⊹Best Escorts Servi...
Call Girls From Raj Nagar Extension Ghaziabad❤️8448577510 ⊹Best Escorts Servi...
Call Girls From Pari Chowk Greater Noida ❤️8448577510 ⊹Best Escorts Service I...
Call Girls From Pari Chowk Greater Noida ❤️8448577510 ⊹Best Escorts Service I...
SEO Case Study: How I Increased SEO Traffic & Ranking by 50-60% in 6 Months
SEO Case Study: How I Increased SEO Traffic & Ranking by 50-60% in 6 Months
Business Model Canvas (BMC)- A new venture concept
Business Model Canvas (BMC)- A new venture concept
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
Falcon's Invoice Discounting: Your Path to Prosperity
Falcon's Invoice Discounting: Your Path to Prosperity
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Call Girls Ludhiana Just Call 98765-12871 Top Class Call Girl Service Available
Value Proposition canvas- Customer needs and pains
Value Proposition canvas- Customer needs and pains
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...
PHX May 2024 Corporate Presentation Final
PHX May 2024 Corporate Presentation Final
Call Girls In Noida 959961⊹3876 Independent Escort Service Noida
Call Girls In Noida 959961⊹3876 Independent Escort Service Noida
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...
Call Girls Service In Old Town Dubai ((0551707352)) Old Town Dubai Call Girl ...
Uneak White's Personal Brand Exploration Presentation
Uneak White's Personal Brand Exploration Presentation
Al Mizhar Dubai Escorts +971561403006 Escorts Service In Al Mizhar
Al Mizhar Dubai Escorts +971561403006 Escorts Service In Al Mizhar
Cracking the Cultural Competence Code.pptx
Cracking the Cultural Competence Code.pptx
Cheap Rate Call Girls In Noida Sector 62 Metro 959961乂3876
Cheap Rate Call Girls In Noida Sector 62 Metro 959961乂3876
Groovy.Tutorial
1.
Submission 631 ©
ASERT 2007 Groovy Tutorial Dr Paul King ASERT, Australia Agile 2007 - 1
2.
Topics
Introduction • Language Basics • Closures • Builders • Submission 631 © ASERT 2007 Data Access • Other Features • Testing with Groovy • Further Integration • Grails • More Information Agile 2007 - 2
3.
What is Groovy?
• “Groovy is like a super version of Java. It can leverage Java's enterprise capabilities but also has cool productivity features like closures, Submission 631 © ASERT 2007 DSL support, builders and dynamic typing.” Groovy = Java – boiler plate code + optional dynamic typing + closures + domain specific languages + builders + metaprogramming Agile 2007 - 3
4.
Groovy Goodies Overview
• Fully object oriented • Closures: reusable and assignable pieces of code • Operators can be • GPath: efficient Submission 631 © ASERT 2007 overloaded object navigation • Multimethods • GroovyBeans • Literal declaration for • grep and switch lists (arrays), maps, ranges and regular • Templates, builder, expressions swing, Ant, markup, XML, SQL, XML-RPC, Scriptom, Grails, tests, Mocks Agile 2007 - 4
5.
Growing Acceptance
• A slow and steady start but now gaining in momentum; growing in maturity & mindshare Submission 631 © ASERT 2007 Groovy Recipes Pragmatic Bookshelf Agile 2007 - 5
6.
The Landscape of
JVM Languages optional static types Submission 631 © ASERT 2007 Dynamic features call for dynamic types Java bytecode calls for static types The terms “Java Virtual Machine” and “JVM” mean a Virtual Machine for the Java™ platform. Agile 2007 - 6
7.
Groovy Starter
System.out.println(quot;Hello, World!quot;); // optional semicolon, println 'Hello, World!' // System.out, brackets, // main() method def name = 'Guillaume' // dynamic typing println quot;$name, I'll get the car.quot; // GString String longer = quot;quot;quot;${name}, the car Submission 631 © ASERT 2007 is in the next row.quot;quot;quot; // multi-line string // with static typing assert 0.5 == 1/2 // BigDecimal equals() def printSize(obj) { // optional duck typing print obj?.size() // safe dereferencing } def animals = ['ant', 'bee', 'cat'] // native list syntax assert animals.every { pet -> // closure support pet < 'dog' // overloading } Agile 2007 - 7
8.
A Better Java...
import java.util.List; import java.util.ArrayList; class Erase { private List filterLongerThan(List strings, int length) { This code List result = new ArrayList(); for (int i = 0; i < strings.size(); i++) { is valid String s = (String) strings.get(i); Java and if (s.length() <= length) { result.add(s); valid Groovy Submission 631 © ASERT 2007 } } return result; } public static void main(String[] args) { List names = new ArrayList(); names.add(quot;Tedquot;); names.add(quot;Fredquot;); names.add(quot;Jedquot;); names.add(quot;Nedquot;); System.out.println(names); Based on an Erase e = new Erase(); example by List shortNames = e.filterLongerThan(names, 3); Jim Weirich System.out.println(shortNames.size()); for (int i = 0; i < shortNames.size(); i++) { & Ted Leung String s = (String) shortNames.get(i); System.out.println(s); } } } Agile 2007 - 8
9.
...A Better Java...
import java.util.List; import java.util.ArrayList; class Erase { private List filterLongerThan(List strings, int length) { Do the List result = new ArrayList(); for (int i = 0; i < strings.size(); i++) { semicolons String s = (String) strings.get(i); add anything? if (s.length() <= length) { result.add(s); And shouldn’t Submission 631 © ASERT 2007 } } we us more } return result; modern list public static void main(String[] args) { notation? List names = new ArrayList(); names.add(quot;Tedquot;); names.add(quot;Fredquot;); Why not names.add(quot;Jedquot;); names.add(quot;Nedquot;); System.out.println(names); import common Erase e = new Erase(); libraries? List shortNames = e.filterLongerThan(names, 3); System.out.println(shortNames.size()); for (int i = 0; i < shortNames.size(); i++) { String s = (String) shortNames.get(i); System.out.println(s); } } } Agile 2007 - 9
10.
...A Better Java...
class Erase { private List filterLongerThan(List strings, int length) { List result = new ArrayList() for (String s in strings) { if (s.length() <= length) { result.add(s) } } return result } Submission 631 © ASERT 2007 public static void main(String[] args) { List names = new ArrayList() names.add(quot;Tedquot;); names.add(quot;Fredquot;) names.add(quot;Jedquot;); names.add(quot;Nedquot;) System.out.println(names) Erase e = new Erase() List shortNames = e.filterLongerThan(names, 3) System.out.println(shortNames.size()) for (String s in shortNames) { System.out.println(s) } } } Agile 2007 - 10
11.
...A Better Java...
class Erase { private List filterLongerThan(List strings, int length) { List result = new ArrayList() for (String s in strings) { if (s.length() <= length) { result.add(s) Do we need } the static types? } return result Must we always } have a main Submission 631 © ASERT 2007 public static void main(String[] args) { List names = new ArrayList() method and names.add(quot;Tedquot;); names.add(quot;Fredquot;) class definition? names.add(quot;Jedquot;); names.add(quot;Nedquot;) System.out.println(names) How about Erase e = new Erase() List shortNames = e.filterLongerThan(names, 3) improved System.out.println(shortNames.size()) consistency? for (String s in shortNames) { System.out.println(s) } } } Agile 2007 - 11
12.
...A Better Java...
def filterLongerThan(strings, length) { def result = new ArrayList() for (s in strings) { if (s.size() <= length) { result.add(s) } } return result Submission 631 © ASERT 2007 } names = new ArrayList() names.add(quot;Tedquot;) names.add(quot;Fredquot;) names.add(quot;Jedquot;) names.add(quot;Nedquot;) System.out.println(names) shortNames = filterLongerThan(names, 3) System.out.println(shortNames.size()) for (s in shortNames) { System.out.println(s) } Agile 2007 - 12
13.
...A Better Java...
def filterLongerThan(strings, length) { def result = new ArrayList() for (s in strings) { if (s.size() <= length) { result.add(s) Shouldn’t we } } have special return result notation for lists? Submission 631 © ASERT 2007 } And special names = new ArrayList() facilities for names.add(quot;Tedquot;) names.add(quot;Fredquot;) list processing? names.add(quot;Jedquot;) names.add(quot;Nedquot;) System.out.println(names) shortNames = filterLongerThan(names, 3) System.out.println(shortNames.size()) for (s in shortNames) { System.out.println(s) } Agile 2007 - 13
14.
...A Better Java...
def filterLongerThan(strings, length) { return strings.findAll{ it.size() <= length } } names = [quot;Tedquot;, quot;Fredquot;, quot;Jedquot;, quot;Nedquot;] System.out.println(names) shortNames = filterLongerThan(names, 3) System.out.println(shortNames.size()) Submission 631 © ASERT 2007 shortNames.each{ System.out.println(s) } Agile 2007 - 14
15.
...A Better Java...
def filterLongerThan(strings, length) { return strings.findAll{ it.size() <= length } } Is the method names = [quot;Tedquot;, quot;Fredquot;, quot;Jedquot;, quot;Nedquot;] now needed? System.out.println(names) shortNames = filterLongerThan(names, 3) Easier ways to System.out.println(shortNames.size()) use common Submission 631 © ASERT 2007 shortNames.each{ System.out.println(s) } methods? Are brackets required here? Agile 2007 - 15
16.
...A Better Java...
names = [quot;Tedquot;, quot;Fredquot;, quot;Jedquot;, quot;Nedquot;] println names shortNames = names.findAll{ it.size() <= 3 } println shortNames.size() shortNames.each{ println it } Submission 631 © ASERT 2007 [quot;Tedquot;, quot;Fredquot;, quot;Jedquot;, quot;Nedquot;] 3 Ted Jed Ned Agile 2007 - 16
17.
...A Better Java
names = [quot;Tedquot;, quot;Fredquot;, quot;Jedquot;, quot;Nedquot;] println names shortNames = names.findAll{ it.size() <= 3 } println shortNames.size() shortNames.each{ println it } import java.util.List; Submission 631 © ASERT 2007 import java.util.ArrayList; class Erase { private List filterLongerThan(List strings, int length) { List result = new ArrayList(); for (int i = 0; i < strings.size(); i++) { String s = (String) strings.get(i); if (s.length() <= length) { result.add(s); } } return result; } public static void main(String[] args) { List names = new ArrayList(); names.add(quot;Tedquot;); names.add(quot;Fredquot;); names.add(quot;Jedquot;); names.add(quot;Nedquot;); System.out.println(names); Erase e = new Erase(); List shortNames = e.filterLongerThan(names, 3); System.out.println(shortNames.size()); for (int i = 0; i < shortNames.size(); i++) { String s = (String) shortNames.get(i); System.out.println(s); } } } Agile 2007 - 17
18.
Better JavaBeans...
import java.math.BigDecimal; ... public class BikeJavaBean { public void setModel(String model) { private String manufacturer; this.model = model; private String model; } private int frame; private String serialNo; public int getFrame() { private double weight; return frame; private String status; } private BigDecimal cost; public String getSerialNo() { public BikeJavaBean(String manufacturer, String model, return serialNo; int frame, String serialNo, } double weight, String status) { this.manufacturer = manufacturer; public void setSerialNo(String serialNo) { this.model = model; this.serialNo = serialNo; Submission 631 © ASERT 2007 this.frame = frame; } this.serialNo = serialNo; this.weight = weight; public double getWeight() { this.status = status; return weight; } } public String toString() { public void setWeight(double weight) { return quot;Bike:‚ + this.weight = weight; ‚n manufacturer -- quot; + manufacturer + } quot;n model -- quot; + model + quot;n frame -- quot; + frame + public String getStatus() { quot;n serialNo -- quot; + serialNo + return status; quot;nquot;; } } public void setStatus(String status) { public String getManufacturer() { this.status = status; return manufacturer; } } public BigDecimal getCost() { public void setManufacturer(String manufacturer) { return cost; this.manufacturer = manufacturer; } } public void setCost(BigDecimal cost) { public String getModel() { this.cost = cost.setScale(3, BigDecimal.ROUND_HALF_UP); return model; } } } ... Modified example from: http://www.ibm.com/developerworks/library/j-pg09196.html Agile 2007 - 18
19.
...Better JavaBeans...
import java.math.BigDecimal; ... public class BikeJavaBean { public void setModel(String model) { Auto private String manufacturer; this.model = model; private String model; private int frame; } getters? private String serialNo; private double weight; private String status; public int getFrame() { } return frame; Auto private BigDecimal cost; public String getSerialNo() { setters? public BikeJavaBean(String manufacturer, String model, return serialNo; int frame, String serialNo, double weight, String status) { } Auto this.manufacturer = manufacturer; this.model = model; construction? public void setSerialNo(String serialNo) { this.serialNo = serialNo; Submission 631 © ASERT 2007 this.frame = frame; } this.serialNo = serialNo; this.weight = weight; public double getWeight() { this.status = status; return weight; } } public String toString() { public void setWeight(double weight) { return quot;Bike:‚ + this.weight = weight; ‚n manufacturer -- quot; + manufacturer + } quot;n model -- quot; + model + quot;n frame -- quot; + frame + public String getStatus() { quot;n serialNo -- quot; + serialNo + return status; quot;nquot;; } } public void setStatus(String status) { public String getManufacturer() { this.status = status; return manufacturer; } } public BigDecimal getCost() { public void setManufacturer(String manufacturer) { return cost; this.manufacturer = manufacturer; } } public void setCost(BigDecimal cost) { public String getModel() { this.cost = cost.setScale(3, BigDecimal.ROUND_HALF_UP); return model; } } } ... Agile 2007 - 19
20.
... Better JavaBeans
class BikeGroovyBean { String manufacturer, model, serialNo, status final Integer frame Double weight BigDecimal cost public void setCost(BigDecimal newCost) { Submission 631 © ASERT 2007 cost = newCost.setScale(3, BigDecimal.ROUND_HALF_UP) } public String toString() { return quot;quot;quot;Bike: manufacturer -- $manufacturer model -- $model frame -- $frame serialNo -- $serialNo quot;quot;quot; } } Agile 2007 - 20
21.
Topics
• Introduction Language Basics • Closures • Builders Submission 631 © ASERT 2007 • Data Access • Other Features • Testing with Groovy • Further Integration • Grails • More Information Agile 2007 - 21
22.
Strings…
• Several forms – Single quotes for // normal strings simple strings def firstname = 'Kate' def surname= quot;Bushquot; – Double quotes for assert firstname * 2 == 'KateKate' GStrings which // GString support variable Submission 631 © ASERT 2007 def fullname = quot;$firstname $surnamequot; expansion assert fullname == 'Kate Bush' – Slashy strings assert fullname - firstname == ' Bush' assert fullname.padLeft(10) == behave like ' Kate Bush' GStrings but preserve // indexing (including ranges) assert fullname[0..3] == firstname backslashes (great assert fullname[-4..-1] == surname for regex and assert fullname[5, 3..1] == 'Beta' directory names) – Multi-line versions Agile 2007 - 22
23.
…Strings…
// slashy string: (almost) no escaping // Multi-line strings def path = /C:WindowsSystem32/ def twister = ''' She sells, sea shells def plain = 'nrtbf$' By the sea shore''' assert plain.size() == 7 def slashy = /nrtbf$/ def lines = assert slashy.size() == 14 twister.split('n') Submission 631 © ASERT 2007 assert lines.size() == 2 // late binding trick with closures fullname = quot;${-> firstname} $surnamequot; def address = quot;quot;quot; assert fullname == 'Kate Bush' $fullname firstname = 'George' 123 First Ave surname = 'Clooney' New York assert fullname == 'George Bush' quot;quot;quot;.trim() println quot;quot;quot; def lines = ---------------------- address.split('n') | $fullname | assert lines.size() == 3 | 123 First Ave | | New York | ---------------------- quot;quot;quot; Agile 2007 - 23
24.
…Strings
// more substrings string = 'hippopotamus' assert string - 'hippo' - 'mus' + 'to' == 'potato' assert string.replace('ppopotam','bisc') == 'hibiscus' // processing characters assert 'apple'.toList() == ['a', 'p', 'p', 'l', 'e'] //also: 'apple' as String[], 'apple'.split(''), 'apple'.each{} Submission 631 © ASERT 2007 string = quot;an apple a dayquot; assert string.toList().unique().sort().join() == ' adelnpy' // reversing chars/words assert 'string'.reverse() == 'gnirts' string = 'Yoda said, quot;can you see this?quot;' revwords = string.split(' ').toList().reverse().join(' ') assert revwords == 'this?quot; see you quot;can said, Yoda' words = ['bob', 'alpha', 'rotator', 'omega', 'reviver'] bigPalindromes = words.findAll{w -> w == w.reverse() && w.size() > 5} assert bigPalindromes == ['rotator', 'reviver'] Agile 2007 - 24
25.
Numbers...
• Java Approach – Supports primitive types and object types – Has wrapper classes to allow conversion – Java 5+ has autoboxing to hide difference • Groovy Approach Submission 631 © ASERT 2007 – Treats everything as an object at the language level • And does appropriate autoboxing under the covers when integrating with Java – BigDecimal used as the default type for non-Integers – Operator overloading applies to all common operations on numbers, e.g. 3 * 4 is the same as 3.multiply(4) • You can use these operators for your own types, e.g. Person * 3 calls the multiple method on your person object Agile 2007 - 25
26.
...Numbers
def x = 3 def y = 4 assert x + y == 7 assert x.plus(y) == 7 assert x instanceof Integer assert 0.5 == 1/2 // uses BigDecimal arithmetic as default def a = 2 / 3 // 0.6666666666 def b = a.setScale(3, BigDecimal.ROUND_HALF_UP) assert b.toString() == '0.667' Submission 631 © ASERT 2007 assert 4 + 3 == 7 // 4.plus(3) assert 4 - 3 == 1 // 4.minus(3) assert 4 * 3 == 12 // 4.multiply(12) assert 4 % 3 == 1 // 4.mod(3) assert 4 ** 3 == 64 // 4.power(3) assert 4 / 3 == 1.3333333333 // 4.div(3) assert 4.intdiv(3) == 1 // normal integer division assert !(4 == 3) // !(4.equals(3)) assert 4 != 3 // ! 4.equals(3) assert !(4 < 3) // 4.compareTo(3) < 0 assert !(4 <= 3) // 4.compareTo(3) <= 0 assert 4 > 3 // 4.compareTo(3) > 0 assert 4 >= 3 // 4.compareTo(3) >= 0 assert 4 <=> 3 == 1 // 4.compareTo(3) Agile 2007 - 26
27.
Dates...
• Mostly same support as Java • Use java.util.Date or java.util.Calendar – Or java.sql.Date etc. – Can use static imports to help • Or 3rd party package like Joda Time Submission 631 © ASERT 2007 • Does have special support for changing times: date2 = date1 + 1.week – 3.days + 6.hours • More utility methods expected for inputting and outputting dates • Potentially will change with JSR 310 Agile 2007 - 27
28.
...Dates
import static java.util.Calendar.getInstance as now import org.codehaus.groovy.runtime.TimeCategory import java.text.SimpleDateFormat println now().time Thu Jun 28 10:10:34 EST 2007 Fri Jun 29 10:10:35 EST 2007 def date = new Date() + 1 Tue Jul 17 11:10:35 EST 2007 Submission 631 © ASERT 2007 println date Date was Jun/03/1998 use(TimeCategory) { println new Date() + 1.hour + 3.weeks - 2.days } input = quot;1998-06-03quot; df1 = new SimpleDateFormat(quot;yyyy-MM-ddquot;) date = df1.parse(input) df2 = new SimpleDateFormat(quot;MMM/dd/yyyyquot;) println 'Date was ' + df2.format(date) Agile 2007 - 28
29.
Lists, Maps, Ranges
• Lists – Special syntax for list literals – Additional common methods (operator overloading) def list = [3, new Date(), 'Jan'] assert list + list == list * 2 Submission 631 © ASERT 2007 • Maps – Special syntax for map literals – Additional common methods def map = [a: 1, b: 2] assert map['a'] == 1 && map.b == 2 • Ranges – Special syntax for various kinds of ranges def letters = 'a'..'z' def numbers = 0..<10 Agile 2007 - 29
30.
Lists
assert [1,2,3,4] == (1..4) assert [1,2,3] + [1] == [1,2,3,1] assert [1,2,3] << 1 == [1,2,3,1] assert [1,2,3,1] - [1] == [2,3] assert [1,2,3] * 2 == [1,2,3,1,2,3] assert [1,[2,3]].flatten() == [1,2,3] assert [1,2,3].reverse() == [3,2,1] Submission 631 © ASERT 2007 assert [1,2,3].disjoint([4,5,6]) assert [1,2,3].intersect([4,3,1]) == [3,1] assert [1,2,3].collect{ it+3 } == [4,5,6] assert [1,2,3,1].unique().size() == 3 assert [1,2,3,1].count(1) == 2 assert [1,2,3,4].min() == 1 assert [1,2,3,4].max() == 4 assert [1,2,3,4].sum() == 10 assert [4,2,1,3].sort() == [1,2,3,4] assert [4,2,1,3].findAll{ it%2 == 0 } == [4,2] Agile 2007 - 30
31.
Maps…
def map = [a:1, 'b':2] println map // [quot;aquot;:1, quot;bquot;:2] println map.a // 1 println map['a'] // 1 println map.keySet() // [quot;aquot;, quot;bquot;] map = [:] // extend the map through assignment Submission 631 © ASERT 2007 map[1] = 'a'; map[2] = 'b' map[true] = 'p'; map[false] = 'q' map[null] = 'x'; map['null'] = 'z' assert map == [ 1:'a', 2:'b', (true):'p', (false):'q', (null):'x', 'null':'z' ] def sb = new StringBuffer() [1:'a', 2:'b', 3:'c'].each{ k, v-> sb << quot;$k:$v, quot; } assert sb.toString() == '1:a, 2:b, 3:c, ' map = [1:'a', 2:'b', 3:'c'] def string = map.collect{ k, v -> quot;$k:$vquot; }.join(', ') assert string == '1:a, 2:b, 3:c' Agile 2007 - 31
32.
…Maps
assert [ [ name: 'Clark', city: 'London' ], [ name: 'Sharma', city: 'London' ], [ name: 'Maradona', city: 'LA' ], [ name: 'Zhang', city: 'HK' ], [ name: 'Ali', city: 'HK' ], [ name: 'Liu', city: 'HK' ] ].groupBy { it.city } == [ Submission 631 © ASERT 2007 London: [ [ name: 'Clark', city: 'London' ], [ name: 'Sharma', city: 'London' ] ], LA: [ [ name: 'Maradona', city: 'LA' ] ], HK: [ [ name: 'Zhang', city: 'HK' ], [ name: 'Ali', city: 'HK' ], [ name: 'Liu', city: 'HK' ] ] ] Agile 2007 - 32
33.
Regular Expressions…
assert quot;Hello World!quot; =~ /Hello/ // Find operator assert quot;Hello World!quot; ==~ /Hellob.*/ // Match operator def p = ~/Hellob.*/ // Pattern operator assert p.class.name == 'java.util.regex.Pattern' // replace matches with calculated values Submission 631 © ASERT 2007 assert quot;1.23quot;.replaceAll(/./){ ch -> ch.next() } == '2/34' assert quot;1.23quot;.replaceAll(/d/){ num -> num.toInteger() + 1 } == '2.34' assert quot;1.23quot;.replaceAll(/d+/){ num -> num.toInteger() + 1 } == '2.24' Agile 2007 - 33
34.
…Regular Expressions
str = 'groovy.codehaus.org and www.aboutgroovy.com' re = '''(?x) # to enable whitespace and comments ( # capture the hostname in $1 (?: # these parens for grouping only (?! [-_] ) # neither underscore nor dash lookahead [w-] + # hostname component . # and the domain dot ) + # now repeat whole thing a few times Submission 631 © ASERT 2007 [A-Za-z] # next must be a letter [w-] + # now trailing domain part ) # end of $1 capture ''' finder = str =~ re out = str (0..<finder.count).each{ adr = finder[it][0] out = out.replaceAll(adr, quot;$adr [${InetAddress.getByName(adr).hostAddress}]quot;) } println out // => groovy.codehaus.org [63.246.7.187] // and www.aboutgroovy.com [63.246.7.76] Agile 2007 - 34
35.
Control Structures
if (1) // ... switch (10) { if (object) // ... case 0 : /* F */ ; break if (list) // ... case 0..9 : // F case [8,9,11] : // F for (item in iterable) { } case Float : // F Submission 631 © ASERT 2007 case {it % 3 == 0} : // F myMap.each { key, value -> case ~/../ : // T println quot;$key : $valuequot; default : // F } } // if (condition)... // implement // else if (condition) ... // boolean isCase(candidate) // else ... // throw, catch, finally // for, while // eachWithIndex, eachLine, ... Agile 2007 - 35
36.
GroovyBeans and GPath
class Dir { String name List dirs } def root = new Dir (name: '/', dirs: [ new Dir (name: 'a'), Submission 631 © ASERT 2007 new Dir (name: 'b') ]) assert root.dirs[0].name == 'a' assert root.dirs.name == ['a', 'b'] assert root.dirs.name*.size() == [1, 1] def expected = ['getName', 'setName', 'getDirs', 'setDirs'] def accessorMethods = Dir.methods.name.grep(~/(g|s)et.*/) assert accessorMethods.intersect(expected) == expected // find, findAll, grep, every, any, … Agile 2007 - 36
37.
Static Imports
import static java.awt.Color.LIGHT_GRAY Works with Java 1.4 import static Boolean.FALSE as F Slightly more powerful import static Calendar.getInstance as now than Java equivalent println LIGHT_GRAY // => java.awt.Color[r=192,g=192,b=192] println !F // => true println now().time // => Sun Apr 29 11:12:43 EST 2007 Submission 631 © ASERT 2007 import static Integer.* println quot;Integers are between $MIN_VALUE and $MAX_VALUEquot; // => Integers are between -2147483648 and 2147483647 def toHexString(int val, boolean upperCase) { def hexval = upperCase ? toHexString(val).toUpperCase() : toHexString(val) return '0x' + hexval } println toHexString(15, true) // => 0xF println toHexString(15, false) // => 0xf import static Math.* assert cos(2 * PI) == 1.0 Agile 2007 - 37
38.
Topics
• Introduction • Language Basics Closures • Builders Submission 631 © ASERT 2007 • Data Access • Other Features • Testing with Groovy • Further Integration • Grails • More Information Agile 2007 - 38
39.
Using Closures...
• Traditional mainstream languages – Data can be stored in variables, passed around, combined in structured ways to form more complex data; code stays put where it is defined • Languages supporting closures Submission 631 © ASERT 2007 – Data and code can be stored in variables, passed around, combined in structured ways to form more complex algorithms and data doubleNum = { num -> num * 2 } println doubleNum(3) // => 6 processThenPrint = { num, closure -> num = closure(num); println quot;num is $numquot; } processThenPrint(3, doubleNum) // => num is 6 processThenPrint(10) { it / 2 } // => num is 5 Agile 2007 - 39
40.
...Using Closures...
import static Math.* Algorithm piE differs by 1.0206946399193839E-11 Algorithm piF differs by 1.0070735356748628E-9 Algorithm piC differs by 2.668102068170697E-7 piA = { 22 / 7 } Algorithm piD differs by 4.813291008076703E-5 piB = { 333/106 } Algorithm piB differs by 8.321958979307098E-5 piC = { 355/113 } Algorithm piA differs by 0.001264489310206951 piD = { 0.6 * (3 + sqrt(5)) } piE = { 22/17 + 37/47 + 88/83 } piF = { sqrt(sqrt(2143/22)) } Submission 631 © ASERT 2007 howCloseToPI = { abs(it.value() - PI) } algorithms = [piA:piA, piB:piB, piC:piC, piD:piD, piE:piE, piF:piF] findBestPI(algorithms) def findBestPI(map) { map.entrySet().sort(howCloseToPI).each { entry -> def diff = howCloseToPI(entry) println quot;Algorithm $entry.key differs by $diffquot; } } Agile 2007 - 40
41.
...Using Closures...
• Used for many things in Groovy: • Iterators new File('/x.txt').eachLine { println it • Callbacks } • Higher-order functions • Specialized control structures Submission 631 © ASERT 2007 • Dynamic method definition • Resource allocation 3.times { println 'Hi' } • Threads [0, 1, 2].each { number -> • Continuations println number } def houston(Closure doit) { (10..1).each { count -> [0, 1, 2].each { println it} doit(count) } def printit = { println it } } [0, 1, 2].each printit houston { println it } Agile 2007 - 41
42.
...Using Closures...
map = ['a': 1, 'b': 2] map.each {key, value -> map[key] = value * 2} assert map == ['a': 2, 'b': 4] doubler = {key, value -> map[key] = value * 2} Submission 631 © ASERT 2007 map.each(doubler) assert map == ['a': 4, 'b': 8] def doubleMethod(entry) { map[entry.key] = entry.value * 2 } doubler = this.&doubleMethod map.each(doubler) assert map == ['a': 8, 'b': 16] Agile 2007 - 42
43.
...Using Closures...
assert [1, 2, 3].grep{ it < 3 } == [1, 2] assert [1, 2, 3].any{ it % 2 == 0 } assert [1, 2, 3].every{ it < 4 } assert (1..9).collect{it}.join() == '123456789' assert (1..4).collect{it * 2}.join() == '2468' Submission 631 © ASERT 2007 def add = { x, y -> x + y } def mult = { x, y -> x * y } assert add(1, 3) == 4 assert mult(1, 3) == 3 def min = { x, y -> [x, y].min() } def max = { x, y -> [x, y].max() } def triple = mult.curry(3); assert triple(2) == 6 def atLeastTen = max.curry(10) assert atLeastTen(5) == 10 assert atLeastTen(15) == 15 Agile 2007 - 43
44.
...Using Closures
def pairWise(list, Closure invoke) { if (list.size() < 2) return [] def next = invoke(list[0], list[1]) return [next] + pairWise(list[1..-1], invoke) } Submission 631 © ASERT 2007 // using min, max, etc. From previous slide assert pairWise(1..5, add) == [3, 5, 7, 9] assert pairWise(1..5, mult) == [2, 6, 12, 20] assert pairWise(1..5, min) == [1, 2, 3, 4] assert pairWise(1..5, max) == [2, 3, 4, 5] assert 'cbaxabc' == ['a', 'b', 'c'].inject('x') { result, item -> item + result + item } Agile 2007 - 44
45.
Topics
• Introduction • Language Basics • Closures Builders Submission 631 © ASERT 2007 • Data Access • Other Features • Testing with Groovy • Further Integration • Grails • More Information Agile 2007 - 45
46.
Builder Pattern Inclusive
• Builder pattern from the GoF at the syntax-level • Represents easily any nested tree-structured data import groovy.xml.* • Create new builder def page = new MarkupBuilder() Submission 631 © ASERT 2007 page.html { • Call pretended methods head { title 'Hello' } (html, head, ...) body { • Arguments are Closures ul { for (count in 1..10) { • Builder code looks very li quot;world $countquot; declarative but is ordinary } } } } Groovy program code and can contain any kind of NodeBuilder, DomBuilder, logic SwingBuilder, AntBuilder, … Agile 2007 - 46
47.
SwingBuilder
import java.awt.FlowLayout builder = new groovy.swing.SwingBuilder() langs = [quot;Groovyquot;, quot;Rubyquot;, quot;Pythonquot;, quot;Pnutsquot;] gui = builder.frame(size: [290, 100], title: 'Swinging with Groovy!’) { panel(layout: new FlowLayout()) { panel(layout: new FlowLayout()) { Submission 631 © ASERT 2007 for (lang in langs) { checkBox(text: lang) } } button(text: 'Groovy Button', actionPerformed: { builder.optionPane(message: 'Indubitably Groovy!'). createDialog(null, 'Zen Message').show() }) button(text: 'Groovy Quit', actionPerformed: {System.exit(0)}) } } gui.show() Source: http://www.ibm.com/developerworks/java/library/j-pg04125/ Agile 2007 - 47
48.
AntBuilder
def ant = new AntBuilder() ant.echo(quot;helloquot;) // lets just call one task // create a block of Ant using the builder pattern ant.sequential { myDir = quot;target/AntTest/quot; Submission 631 © ASERT 2007 mkdir(dir: myDir) copy(todir: myDir) { fileset(dir: quot;src/testquot;) { include(name: quot;**/*.groovyquot;) } } echo(quot;donequot;) } // now lets do some normal Groovy again file = new File(quot;target/test/AntTest.groovyquot;) assert file.exists() Agile 2007 - 48
49.
Using AntLibs: Maven
Ant Tasks & AntUnit… def ant = new AntBuilder() items = [[groupId:'jfree', artifactId:'jfreechart', version:'1.0.5'], [groupId:'jfree', artifactId:'jcommon', version:'1.0.9']] def mvn = new AntLibHelper(ant:ant, namespace:'org.apache.maven.artifact.ant') def antunit = new AntLibHelper(ant:ant, namespace:'org.apache.ant.antunit') Submission 631 © ASERT 2007 // download artifacts with Maven Ant tasks mvn.dependencies(filesetId:'artifacts') { items.each{ dependency(it) } } // print out what we downloaded ant.fileScanner { fileset(refid:'artifacts') }.each { println it } // use AntUnit to confirm expected files were downloaded def prefix = System.properties.'user.home' + '/.m2/repository' items.each { item -> def g = item.groupId def a = item.artifactId def v = item.version antunit.assertFileExists(file:quot;$prefix/$g/$a/$v/$a-${v}.jarquot;) } Agile 2007 - 49
50.
…Using AntLibs: Maven
Ant Tasks & AntUnit ... class AntLibHelper { def namespace, ant Object invokeMethod(String name, Object params) { ant.quot;antlib:$namespace:$namequot;(*params) } } Submission 631 © ASERT 2007 /* => Downloading: jfree/jfreechart/1.0.5/jfreechart-1.0.5.pom Transferring 1K Downloading: jfree/jcommon/1.0.9/jcommon-1.0.9.pom Transferring 1K Downloading: jfree/jfreechart/1.0.5/jfreechart-1.0.5.jar Transferring 1157K Downloading: jfree/jcommon/1.0.9/jcommon-1.0.9.jar Transferring 298K C:UsersPaul.m2repositoryjfreejcommon1.0.9jcommon-1.0.9.jar C:UsersPaul.m2repositoryjfreejfreechart1.0.5jfreechart-1.0.5.jar */ Agile 2007 - 50
51.
Topics
• Introduction • Language Basics • Closures • Builders Data Access Submission 631 © ASERT 2007 Objects XML Databases • Other Features • Testing with Groovy • Further Integration • Grails • More Information Agile 2007 - 51
52.
Uniform Data Access
• Data Access to Objects, XML, SQL Databases has some differences and some similarities – Differences in detail about how to set up structures – Similarities in how to process data within resulting Submission 631 © ASERT 2007 structures Agile 2007 - 52
53.
Object Data Access…
import java.text.SimpleDateFormat class Athlete { def firstname, lastname, gender, country, dateOfBirth } def asDate(dateStr) { new SimpleDateFormat(quot;yyyy-MM-ddquot;).parse(dateStr) Submission 631 © ASERT 2007 } def athletes = [ new Athlete(firstname: 'Paul', lastname: 'Tergat', dateOfBirth: '1969-06-17', gender: 'M', country: 'KEN'), new Athlete(firstname: 'Khalid', lastname: 'Khannouchi', dateOfBirth: '1971-12-22', gender: 'M', country: 'USA'), new Athlete(firstname: 'Sammy', lastname: 'Korir', dateOfBirth: '1971-12-12', gender: 'M', country: 'KEN'), new Athlete(firstname: 'Ronaldo', lastname: 'da Costa', dateOfBirth: '1970-06-07', gender: 'M', country: 'BRA'), new Athlete(firstname: 'Paula', lastname: 'Radcliffe', dateOfBirth: '1973-12-17', gender: 'F', country: 'GBR') ] Agile 2007 - 53
54.
…Object Data Access
def bornSince70 = { asDate(it.dateOfBirth) > asDate('1970-1-1') } def excludingKh = { it.lastname <= 'Kg' || it.lastname >= 'Ki' } def byGenderDescThenByCountry = { a, b -> a.gender == b.gender ? Submission 631 © ASERT 2007 a.country <=> b.country : b.gender <=> a.gender } def someYoungsters = athletes. findAll(bornSince70). findAll(excludingKh). sort(byGenderDescThenByCountry) someYoungsters.each { def name = quot;$it.firstname $it.lastnamequot;.padRight(25) println quot;$name ($it.gender) $it.country $it.dateOfBirthquot; } Agile 2007 - 54
55.
Xml Data Access…
import java.text.SimpleDateFormat import com.thoughtworks.xstream.XStream class Athlete { String firstname, lastname, gender, country, dateOfBirth } def asDate(dateStr) { new SimpleDateFormat(quot;yyyy-MM-ddquot;).parse(dateStr) } Submission 631 © ASERT 2007 def athleteList = [ new Athlete(firstname: 'Paul', lastname: 'Tergat‘, dateOfBirth: '1969-06-17', gender: 'M', country: 'KEN'), new Athlete(firstname: 'Khalid', lastname: 'Khannouchi', dateOfBirth: '1971-12-22', gender: 'M', country: 'USA'), new Athlete(firstname: 'Sammy', lastname: 'Korir', dateOfBirth: '1971-12-12', gender: 'M', country: 'KEN'), new Athlete(firstname: 'Ronaldo', lastname: 'da Costa', dateOfBirth: '1970-06-07', gender: 'M', country: 'BRA'), new Athlete(firstname: 'Paula', lastname: 'Radcliffe', dateOfBirth: '1973-12-17', gender: 'F', country: 'GBR') ] // create XML as input def input = new XStream().toXML(athleteList) Agile 2007 - 55
56.
…Xml Data Access
def athletes = new XmlSlurper().parseText(input).Athlete def bornSince70 = { asDate(it.dateOfBirth.text()) > asDate('1970-1-1') } def excludingKh = { it.lastname.text() <= 'Kg' || it.lastname.text() >= 'Ki' } def byGenderDescThenByCountry = { a, b -> Submission 631 © ASERT 2007 a.gender.text() == b.gender.text() ? a.country.text() <=> b.country.text() : b.gender.text() <=> a.gender.text() } def someYoungsters = athletes. findAll(bornSince70).findAll(excludingKh).list(). sort(byGenderDescThenByCountry) someYoungsters.each { def name = quot;$it.firstname $it.lastnamequot;.padRight(25) println quot;$name ($it.gender) $it.country $it.dateOfBirthquot; } Agile 2007 - 56
57.
Sql Data Access…
import groovy.sql.Sql dbHandle = null def getDb() { if (dbHandle) return dbHandle def source = new org.hsqldb.jdbc.jdbcDataSource() source.database = 'jdbc:hsqldb:mem:GIA' source.user = 'sa' source.password = '' Submission 631 © ASERT 2007 dbHandle = new Sql(source) return dbHandle } db.execute ''' DROP INDEX athleteIdx IF EXISTS; DROP TABLE Athlete IF EXISTS; CREATE TABLE Athlete ( athleteId INTEGER GENERATED BY DEFAULT AS IDENTITY, firstname VARCHAR(64), lastname VARCHAR(64), country VARCHAR(3), gender CHAR(1), dateOfBirth DATE ); CREATE INDEX athleteIdx ON Athlete (athleteId); ''' Agile 2007 - 57
58.
…Sql Data Access…
def athleteList = [ [firstname: 'Paul', lastname: 'Tergat', dateOfBirth: '1969-06-17', gender: 'M', country: 'KEN'], [firstname: 'Khalid', lastname: 'Khannouchi', dateOfBirth: '1971-12-22', gender: 'M', country: 'USA'], [firstname: 'Sammy', lastname: 'Korir', Submission 631 © ASERT 2007 dateOfBirth: '1971-12-12', gender: 'M', country: 'KEN'], [firstname: 'Ronaldo', lastname: 'da Costa', dateOfBirth: '1970-06-07', gender: 'M', country: 'BRA'], [firstname: 'Paula', lastname: 'Radcliffe', dateOfBirth: '1973-12-17', gender: 'F', country: 'GBR'] ] def athletes = db.dataSet('Athlete') athleteList.each {a -> athletes.add(a)} Agile 2007 - 58
59.
…Sql Data Access
def bornSince70 = { it.dateOfBirth > '1970-1-1' } def excludingKh = { it.lastname <= 'Kg' || it.lastname >= 'Ki' } def someYoungsters = athletes. findAll(bornSince70). findAll(excludingKh). sort { it.gender }.reverse(). // * experimental sort { it.country } // * experimental Submission 631 © ASERT 2007 println someYoungsters.sql + 'n' + someYoungsters.parameters someYoungsters.each { def name = quot;$it.firstname $it.lastnamequot;.padRight(25) println quot;$name ($it.gender) $it.country $it.dateOfBirthquot; } /* => select * from Athlete where dateOfBirth > ? and (lastname <= ? or lastname >= ?) order by gender DESC, country [quot;1970-1-1quot;, quot;Kgquot;, quot;Kiquot;] Ronaldo da Costa (M) BRA 1970-06-07 Sammy Korir (M) KEN 1971-12-12 Paula Radcliffe (F) GBR 1973-12-17 */ Agile 2007 - 59
60.
More Details: XmlSlurper…
• Features – One-line parsing – GPath Syntax – Efficient lazy evaluation static def CAR_RECORDS = ''' Submission 631 © ASERT 2007 <records> <car name='HSV Maloo' make='Holden' year='2006'> <country>Australia</country> <record type='speed'>Production Pickup Truck with speed of 271kph</record> </car> <car name='P50' make='Peel' year='1962'> <country>Isle of Man</country> <record type='size'>Smallest Street-Legal Car at 99cm wide and 59 kg in weight</record> </car> <car name='Royale' make='Bugatti' year='1931'> <country>France</country> <record type='price'>Most Valuable Car at $15 million</record> </car> </records> ''' Agile 2007 - 60
61.
…More Details: XmlSlurper
def records = new XmlSlurper().parseText(XmlExamples.CAR_RECORDS) // 3 records in total assert 3 == records.car.size() // 10 nested nodes assert 10 == records.depthFirst().collect{ it }.size() // test properties of the first record def firstRecord = records.car[0] assert 'car' == firstRecord.name() assert 'Holden' == firstRecord.@make.toString() assert 'Australia' == firstRecord.country.text() Submission 631 © ASERT 2007 // 2 cars have an 'e' in the make assert 2 == records.car.findAll{ it.@make.toString().contains('e') }.size() // 2 cars have an 'e' in the make assert 2 == records.car.findAll{ it.@make =~ '.*e.*' }.size() // makes of cars that have an 's' followed by an 'a' in the country assert ['Holden', 'Peel'] == records.car.findAll{ it.country =~ '.*s.*a.*' }.@make.collect{ it.toString // types of records assert ['speed', 'size', 'price'] == records.depthFirst().grep{ it.@type != '' }.'@type'*.toString() assert ['speed', 'size', 'price'] == records.'**'.grep{ it.@type != '' }.'@type'*.toString() // check parent() operator def countryOne = records.car[1].country assert 'Peel' == countryOne.parent().@make.toString() assert 'Peel' == countryOne.'..'.@make.toString() // names of cars with records sorted by year def names = records.car.list().sort{ it.@year.toInteger() }.'@name'*.toString() assert ['Royale', 'P50', 'HSV Maloo'] == names Agile 2007 - 61
62.
More Details: Working
with Databases • Using standard SQL statements import groovy.sql.Sql def foo = 'cheese' def sql = Sql.newInstance(quot;jdbc:mysql://localhost:3306/mydbquot;, quot;userquot;, quot;pswdquot;, quot;com.mysql.jdbc.Driverquot;) sql.eachRow(quot;select * from FOOD where type=${foo}quot;) { Submission 631 © ASERT 2007 println quot;Gromit likes ${it.name}quot; } • Using DataSets import groovy.sql.Sql def sql = Sql.newInstance(quot;jdbc:mysql://localhost:3306/mydbquot;, quot;userquot;, quot;pswdquot;, quot;com.mysql.jdbc.Driverquot;) def food = sql.dataSet('FOOD') def cheese = food.findAll { it.type == 'cheese' } cheese.each { println quot;Eat ${it.name}quot; } Agile 2007 - 62
63.
DataSets and Lazy
Evaluation athleteSet = db.dataSet('Athlete') youngsters = athleteSet.findAll{ it.dateOfBirth > '1970-1-1'} paula = youngsters.findAll{ it.firstname == 'Paula'} println paula.sql // => Submission 631 © ASERT 2007 // select * from Athlete where dateOfBirth > ? and firstname = ? println paula.parameters // => // [1970-1-1, Paula] paula.each { println it.lastname } // database called here // => // Radcliffe Agile 2007 - 63
64.
Topics
• Introduction • Language Basics • Closures • Builders Submission 631 © ASERT 2007 • Data Access Other Features • Testing with Groovy • Further Integration • Grails • More Information Agile 2007 - 64
65.
JMX
import javax.management.remote.* import javax.management.* import javax.naming.Context def urlRuntime = '/jndi/weblogic.management.mbeanservers.runtime' def urlBase = 'service:jmx:t3://localhost:7001' def serviceURL = new JMXServiceURL(urlBase + urlRuntime) def h = new Hashtable() h.put(Context.SECURITY_PRINCIPAL, 'weblogic') Submission 631 © ASERT 2007 h.put(Context.SECURITY_CREDENTIALS, 'weblogic') h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, 'weblogic.management.remote') def server = JMXConnectorFactory.connect(serviceURL, h).mBeanServerConnection def domainName = new ObjectName('com.bea:Name=RuntimeService,' + 'Type=weblogic.management.mbeanservers.runtime.RuntimeServiceMBean') def rtName = server.getAttribute(domainName, 'ServerRuntime') def rt = new GroovyMBean(server, rtName) println quot;Server: name=$rt.Name, state=$rt.State, version=$rt.WeblogicVersionquot; def destFilter = Query.match(Query.attr('Type'), Query.value( 'JMSDestinationRuntime')) server.queryNames(new ObjectName('com.bea:*'), destFilter).each {name -> def jms = new GroovyMBean(server, name) println quot;JMS Destination: name=$jms.Name, type=$jms.DestinationTypequot; + quot;, messages=$jms.MessagesReceivedCountquot; } Agile 2007 - 65
66.
ExpandoMetaClass…
String.metaClass.swapCase = {-> def sb = new StringBuffer() delegate.each { sb << (Character.isUpperCase(it as char) ? Character.toLowerCase(it as char) : Character.toUpperCase(it as char)) } Submission 631 © ASERT 2007 sb.toString() } List.metaClass.sizeDoubled = {-> delegate.size() * 2 } LinkedList list = [] list << 1 list << 2 assert 4 == list.sizeDoubled() Agile 2007 - 66
67.
…ExpandoMetaClass
class Person { String name } class MortgageLender { def borrowMoney() { quot;buy housequot; Submission 631 © ASERT 2007 } } def lender = new MortgageLender() Person.metaClass.buyHouse = lender.&borrowMoney def p = new Person() assert quot;buy housequot; == p.buyHouse() Agile 2007 - 67
68.
Constraint Programming
// require(url:'http://www.alice.unibo.it/tuProlog/', jar:'tuprolog.jar‘, version:'2.1') import alice.tuprolog.* ... /** Pretty Printing */ mother(X,Y) :- def pprint(soln) { parent(X,Y), female(X). father(X,Y) :- println soln.isSuccess() ? quot;$soln.query = $soln.solutionquot; : parent(X,Y), male(X). … 'no solution found' grandparent(X,Z) :- def engine = new Prolog() } parent(X,Y), engine.theory = theory parent(Y,Z). pprint engine.solve('ancestor(tom,X).') /** Prolog clauses */ grandmother(X,Y) :- while(engine.hasOpenAlternatives()) { Submission 631 © ASERT 2007 grandparent(X,Y), def getTheory() { female(X). pprint engine.solveNext() new Theory(quot;quot;“ grandfather(X,Y) :- } parent(pam, bob). grandparent(X,Y), parent(tom, bob). male(X). parent(tom, liz). parent(bob, ann). sister(X,Y) :- parent(Z,X), parent(bob, pat). parent(Z,Y), parent(pat, jim). female(X). brother(X,Y) :- female(pam). parent(Z,X), ancestor(tom,X) = ancestor(tom,bob) male(tom). parent(Z,Y), ancestor(tom,X) = ancestor(tom,liz) male(bob). male(X). ancestor(tom,X) = ancestor(tom,ann) female(liz). ancestor(tom,X) = ancestor(tom,pat) ancestor(X,Y) :- parent(X,Y). ancestor(tom,X) = ancestor(tom,jim) female(pat). ancestor(X,Z) :- female(ann). parent(X,Y), no solution found male(jim). ancestor(Y,Z). quot;quot;quot;) offspring(X,Y) :- parent(Y,X). } Agile 2007 - 68
69.
Functional Programming
def fac(n) { n == 0 ? 1 : n * fac(n - 1) } assert 24 == fac(4) // now define and use infinite streams def integers(n) { cons(n, { integers(n+1) }) } Submission 631 © ASERT 2007 def naturalnumbers = integers(1) assert '1 2 3 4 5 6 7 8 9 10' == naturalnumbers.take(10).join(' ') def evennumbers = naturalnumbers.filter{ it % 2 == 0 } assert '2 4 6 8 10 12 14 16 18 20' == evennumbers.take(10).join(' ') Agile 2007 - 69
Télécharger maintenant