
- •brief contents
- •contents
- •foreword
- •preface
- •acknowledgments
- •about this book
- •Roadmap
- •Code conventions and downloads
- •Author Online
- •About the author
- •about the cover illustration
- •1 Why add Groovy to Java?
- •1.1 Issues with Java
- •1.1.1 Is static typing a bug or a feature?
- •1.1.2 Methods must be in a class, even if you don’t need or want one
- •1.1.3 Java is overly verbose
- •1.1.4 Groovy makes testing Java much easier
- •1.1.5 Groovy tools simplify your build
- •1.2 Groovy features that help Java
- •1.3 Java use cases and how Groovy helps
- •1.3.1 Spring framework support for Groovy
- •1.3.2 Simplified database access
- •1.3.3 Building and accessing web services
- •1.3.4 Web application enhancements
- •1.4 Summary
- •2 Groovy by example
- •2.1 Hello, Groovy
- •2.2 Accessing Google Chart Tools
- •2.2.1 Assembling the URL with query string
- •2.2.2 Transmitting the URL
- •2.2.3 Creating a UI with SwingBuilder
- •2.3 Groovy Baseball
- •2.3.1 Database data and Plain Old Groovy Objects
- •2.3.2 Parsing XML
- •2.3.3 HTML builders and groovlets
- •2.4 Summary
- •3 Code-level integration
- •3.1 Integrating Java with other languages
- •3.2 Executing Groovy scripts from Java
- •3.2.1 Using JSR223 scripting for the Java Platform API
- •3.2.2 Working with the Groovy Eval class
- •3.2.3 Working with the GroovyShell class
- •3.2.4 Calling Groovy from Java the easy way
- •3.2.5 Calling Java from Groovy
- •3.3 Summary
- •4 Using Groovy features in Java
- •4.1 Treating POJOs like POGOs
- •4.2 Implementing operator overloading in Java
- •4.3 Making Java library classes better: the Groovy JDK
- •4.4 Cool AST transformations
- •4.4.1 Delegating to contained objects
- •4.4.2 Creating immutable objects
- •4.4.3 Creating singletons
- •4.5 Working with XML
- •4.6 Working with JSON data
- •4.7 Summary
- •5 Build processes
- •5.1 The build challenge
- •5.2 The Java approach, part 1: Ant
- •5.3 Making Ant Groovy
- •5.3.1 The <groovy> Ant task
- •5.3.2 The <groovyc> Ant task
- •5.3.3 Writing your build in Groovy with AntBuilder
- •5.3.4 Custom build scripts with Gant
- •5.3.5 Ant summary
- •5.4 The Java approach, part 2: Maven
- •5.4.2 The GMaven project
- •5.4.3 Maven summary
- •5.5 Grapes and @Grab
- •5.6 The Gradle build system
- •5.6.1 Basic Gradle builds
- •5.6.2 Interesting configurations
- •5.7 Summary
- •6 Testing Groovy and Java projects
- •6.1 Working with JUnit
- •6.1.1 A Java test for the Groovy implementation
- •6.1.2 A Groovy test for the Java implementation
- •6.1.3 A GroovyTestCase test for a Java implementation
- •6.2 Testing scripts written in Groovy
- •6.2.1 Useful subclasses of GroovyTestCase: GroovyShellTestCase
- •6.2.2 Useful subclasses of GroovyTestCase: GroovyLogTestCase
- •6.3 Testing classes in isolation
- •6.3.1 Coerced closures
- •6.3.2 The Expando class
- •6.3.3 StubFor and MockFor
- •6.4 The future of testing: Spock
- •6.4.1 The Search for Spock
- •6.4.2 Test well, and prosper
- •6.4.4 The trouble with tribbles
- •6.4.5 Other Spock capabilities
- •6.5 Summary
- •7 The Spring framework
- •7.1 A Spring application
- •7.2 Refreshable beans
- •7.3 Spring AOP with Groovy beans
- •7.4 Inline scripted beans
- •7.5 Groovy with JavaConfig
- •7.6 Building beans with the Grails BeanBuilder
- •7.7 Summary
- •8 Database access
- •8.1 The Java approach, part 1: JDBC
- •8.2 The Groovy approach, part 1: groovy.sql.Sql
- •8.3 The Java approach, part 2: Hibernate and JPA
- •8.4 The Groovy approach, part 2: Groovy and GORM
- •8.4.1 Groovy simplifications
- •8.5 Groovy and NoSQL databases
- •8.5.1 Populating Groovy vampires
- •8.5.2 Querying and mapping MongoDB data
- •8.6 Summary
- •9 RESTful web services
- •9.1 The REST architecture
- •9.3 Implementing JAX-RS with Groovy
- •9.4 RESTful Clients
- •9.5 Hypermedia
- •9.5.1 A simple example: Rotten Tomatoes
- •9.5.2 Adding transitional links
- •9.5.3 Adding structural links
- •9.5.4 Using a JsonBuilder to control the output
- •9.6 Other Groovy approaches
- •9.6.1 Groovlets
- •9.6.2 Ratpack
- •9.6.3 Grails and REST
- •9.7 Summary
- •10 Building and testing web applications
- •10.1 Groovy servlets and ServletCategory
- •10.2 Easy server-side development with groovlets
- •10.2.1 A “Hello, World!” groovlet
- •10.2.2 Implicit variables in groovlets
- •10.3.2 Integration testing with Gradle
- •10.3.3 Automating Jetty in the Gradle build
- •10.4 Grails: the Groovy “killer app”
- •10.4.1 The quest for the holy Grails
- •10.5 Summary
- •A.1 Installing a JDK
- •A.2 Installing Groovy
- •A.3 Testing your installation
- •A.4 IDE support
- •A.5 Installing other projects in the Groovy ecosystem
- •B.1 Scripts and the traditional example
- •B.2 Variables, numbers, and strings
- •B.2.1 Numbers
- •B.2.2 Strings and Groovy strings
- •B.3 Plain Old Groovy Objects
- •B.4 Collections
- •B.4.1 Ranges
- •B.4.2 Lists
- •B.4.3 Maps
- •B.5 Closures
- •B.6 Loops and conditionals
- •B.6.1 Loops
- •B.6.2 Conditionals
- •B.6.3 Elvis
- •B.6.4 Safe de-reference
- •B.7 File I/O
- •B.8.1 Parsing and slurping XML
- •B.8.2 Generating XML
- •B.8.3 Validation
- •B.9 JSON support
- •B.9.1 Slurping JSON
- •B.9.2 Building JSON
- •index
- •Symbols
Collections |
303 |
class Person { String firstName String lastName
String toString() { "$firstName $lastName" }
}
POGOs don’t require access modifiers, because in Groovy attributes are private by default and methods are public by default. The class is public by default, as well. Any property without an access modifier automatically gets a public getter and setter method. If you want to add public or private you can, and either on an attribute will prevent the generation of the associated getter and setter.
GROOVY PROPERTIES In Groovy, property access is done through dynamically generated getter and setter methods.
Here’s a script using the Person class:
Person mrIncredible = new Person() mrIncredible.firstName = 'Robert' mrIncredible.setLastName('Parr') assert 'Robert Parr' ==
"${mrIncredible.firstName} ${mrIncredible.getLastName()}"
Person elastigirl = new Person(firstName: 'Helen', lastName: 'Parr') assert 'Helen Parr' == elastigirl.toString()
The script shows that you also get a default, map-based constructor, so called because it uses the same property:value syntax used by Groovy maps.
This idiom is so common in Groovy that getter and setter methods anywhere in the standard library are typically accessed with the property notation. For example, Calendar.instance is used to invoke the getInstance method on the Calendar class.
Moving now to collections of instances, I’ll start with ranges, then move to lists, and finally look at maps.
B.4 Collections
Since J2SE 1.2, the Java standard library has included the collections framework. The framework defines interfaces for lists, sets, and maps, and provides a small but useful set of implementation classes for each interface, as well as a set of polymorphic utility methods in the class java.util.Collections.
Groovy can use all of these collections but adds a lot:
■Native syntax for lists and maps
■A Range class
■Many additional convenience methods
I’ll present examples of each in this section.
www.it-ebooks.info

304 |
APPENDIX B Groovy by feature |
B.4.1 Ranges
Ranges are collections in Groovy consisting of two values separated by a pair of dots. Ranges are normally used as parts of other expressions, like loops, but they can be used by themselves.
The class groovy.lang.Range has methods for accessing the boundaries of a range, as well as checking whether it contains a particular element. Here’s a simple example:
Range bothEnds = 5..8 assert bothEnds.contains(5) assert bothEnds.contains(8) assert bothEnds.from == 5 assert bothEnds.to == 8
assert bothEnds == [5, 6, 7, 8]
Using two dots includes the boundaries. To exclude the upper boundary, use a lessthan sign:
Range noUpper = 5..<8 assert noUpper.contains(5) assert !noUpper.contains(8) assert noUpper.from == 5 assert noUpper.to == 7 assert noUpper == [5, 6, 7]
A range of numbers iterates over the contained integers. Other library classes can be used in ranges. Strings go letter by letter:
assert 1..5 == [1,2,3,4,5]
assert 'A'..'E' == ["A","B","C","D","E"]
Dates iterate over the contained days, as shown in the next listing.
Listing B.3 Using dates in a range with Java’s Calendar class
def cal = Calendar.instance
cal.set 2013, Calendar.FEBRUARY, 27 def now = cal.time
cal.set 2013, Calendar.MARCH, 1 def then = cal.time
def days = [] (now..then).each { day ->
days << day.format('MMM dd, yyyy')
Invokes getInstance()
Retrieve the assigned Date
Iterate over the range
}
assert days == ['Feb 27, 2013', 'Feb 28, 2013', 'Mar 01, 2013']
For all its gifts, even Groovy can’t tame Java’s awkward java.util.Date and java.util
.Calendar classes, but it can make the code for using them a bit simpler. Calendar is an abstract class with the factory method getInstance, so in Groovy I call it by accessing the instance property. The Groovy JDK adds the format method to Date, so it isn’t necessary to separately instantiate SimpleDateFormat.
www.it-ebooks.info

Collections |
305 |
In the listing, after setting the year, month, and day, the Date instance is retrieved by invoking getTime.8 In this case, that’s equivalent to accessing the time property. The dates are used as the boundaries of a range by the each method, which appends each one to a list.
In fact, any class can be made into a range if it includes three features:
■A next() method, for forward iteration
■A previous() method, for backward iteration
■An implementation of the java.util.Comparable interface, for ordering
Here the range is used as the basis of a loop, where the dates are appended to a list.
B.4.2 Lists
Lists in Groovy are the same as lists in Java, except that the syntax is easier and there are some additional methods available. Create a list in Groovy by including values between square brackets:
def teams = ['Red Sox', 'Yankees']
assert teams.class == java.util.ArrayList
The default list is of type java.util.ArrayList. If you prefer to use a LinkedList, instantiate it in the normal way.
Groovy has operator overloading. The Groovy JDK shows that the plus, minus, and left-shift operators have been defined to work with lists:
teams << 'Orioles'
assert teams == ['Red Sox', 'Yankees', 'Orioles'] teams << ['Rays', 'Blue Jays']
assert teams ==
['Red Sox', 'Yankees', 'Orioles', ['Rays', 'Blue Jays']] assert teams.flatten() ==
['Red Sox', 'Yankees', 'Orioles', 'Rays', 'Blue Jays'] assert teams + 'Angels' - 'Orioles' ==
['Red Sox', 'Yankees', ['Rays', 'Blue Jays'], 'Angels']
Accessing elements of a list can be done with array-like syntax. Again, this is done by overriding a method—in this case, the getAt method:
assert teams[0] == 'Red Sox' assert teams[1] == 'Yankees'
assert teams[-1] == ['Rays','Blue Jays']
As shown in figure B.1, access to elements from the left end starts at index 0. Access from the right end starts at index –1. You can use a range in the square brackets, too:
def cities = ['New York', 'Boston', 'Cleveland','Seattle'] assert ['Boston', 'Cleveland'] == cities[1..2]
8 Yes, you read that correctly. You get the date by calling … getTime. Hey, I didn’t write it.
www.it-ebooks.info

306 |
APPENDIX B Groovy by feature |
Forward
0 |
1 |
2 |
3 |
4 |
–5 |
–4 |
–3 |
–2 |
–1 |
|
|
|
|
|
Reverse
Figure B.1 Access any linear collection using an index from either end. The first element is at index 0. The last element is at index –1. You can also use subranges, as in mylist[-4..-2].
ARRAY-LIKE ACCESS Linear collections support element access through an index from either end, or even using a range.
Groovy adds methods like pop, intersect, and reverse to collections. See the GroovyDocs for details.
There are two ways to apply a function to each element. The spread-dot operator (.*) makes it easy to access a property or apply a method to each element:
assert cities*.size() == [8, 6, 9, 7]
The collect method takes a closure as an argument and applies it to each element of the collection, returning a list with the results. This is similar to the spread-dot operator, but can do more general operations:
def abbrev = cities.collect { city -> city[0..2].toLowerCase() } assert abbrev == ['new', 'bos', 'cle', 'sea']
The word city here used before the arrow is like a dummy argument for a method call. The closure extracts the first three letters of each element of the list and then converts them to lowercase.
One particularly interesting feature of collections is that they support type coercion using the as operator. What does that mean? It’s not terribly difficult to convert a Java list into a set, because there’s a constructor for that purpose. Converting a list into an array, however, involves some awkward, counterintuitive code. Here’s Groovy’s take on the process:
def names = teams as String[] assert names.class == String[]
def set = teams as Set
assert set.class == java.util.HashSet
That was easy.9 A set in Groovy is just like a set in Java, meaning it doesn’t contain duplicates and doesn’t guarantee order.
THE AS OPERATOR Groovy uses the keyword as for many purposes. One of them is type coercion, which converts an instance of one class into an instance of another.
9 I know I say that a lot, but with Groovy I think it a lot, too.
www.it-ebooks.info