
- •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

Making Java library classes better: the Groovy JDK |
71 |
4.3Making Java library classes better: the Groovy JDK
Every Groovy class contains a metaclass. In addition to providing information about a class, the metaclass contains methods that come into play if a method or property that doesn’t exist is accessed through an instance. By intercepting those method or property “missing” failures, developers can provide whatever they want.
One application of this is for Groovy to add methods to existing classes. This is especially useful when you want to add methods to classes where you cannot change the source code. As mentioned earlier, Groovy makes extensive use of the existing Java standard libraries. It does not, however, simply use them as it finds them. In many cases, a range of new methods has been added to the Java libraries to make them easier and more powerful.
Collectively the set of enhanced Java libraries is known as the Groovy JDK. Groovy has two sets of Javadoc documentation. One is the Groovy API, which contains information about the included Groovy libraries. The other is the Groovy JDK, which shows only those methods and properties that have been added to the standard Java libraries, in order to, as the saying goes, make them groovier (see figure 4.4).
For example, Groovy adds many methods to the java.util.Collection interface, including collect, count, find, findAll, leftShift, max, min, sort, and sum. These methods are then available in any Groovy collection, whether they include objects from Java or Groovy.
I’ve already spent a fair amount of time on collections, though, and I’ll revisit them frequently in the book. So to choose an example from a different Java class, let’s illustrate why it’s a bad idea to use basic authentication over HTTP.
In basic authentication a username and password are transmitted in encoded form to a server. Basic authentication concatenates the username and the password
Figure 4.4 Groovy adds convenience methods to classes in the Java standard library.
www.it-ebooks.info

72 |
CHAPTER 4 Using Groovy features in Java |
together, separated by a colon, performs a Base 64 encoding on the resulting string, and sends the result as part of the authenticated HTTP request header.
There’s a big difference, however, between encoding and encrypting. Encoded strings can just as easily be decoded. Groovy makes it easy to demonstrate this, because the Groovy JDK adds a method called encodeBase64 to, of all things, byte arrays. It also adds a decodeBase64 method to String. The following listing demonstrates both.
Listing 4.4 Base 64 encoding and decoding username/password information
def u = 'username' def p = 'password'
def encoded = "$u:$p".getBytes().encodeBase64().toString() println "$u:$p -> $encoded"
assert encoded == 'dXNlcm5hbWU6cGFzc3dvcmQ='
def (user,pass) = new String(encoded.decodeBase64()).split(':') println "(user,pass) = ($user,$pass)"
assert user == u assert pass == p
Mixing Java and Groovy methods
Reversing the encoding
There’s a lot going on in this short script. First, a username and password are assembled into a Groovy string. Then the getBytes method is invoked on the combined string, which encodes the string into a sequence of bytes using the default character encoding. That method is from Java. The result is a byte array. Check the Groovy JDK and you’ll find that Groovy has added the method encodeBase64 to byte[], which returns an instance of groovy.lang.Writable. Here I just use its toString method (from Java, of course, though it’s overridden in the Groovy class) to see the resulting values. In effect I went from Java to Groovy to Java in one chained method call.
To go the other direction, first I use the decodeBase64 method that Groovy adds to java.lang.String, which returns a byte[] again. Then String has a constructor that takes a byte array, and I use the split method from Java to separate the username from the password again and verify that they haven’t been modified by the transformations.
Other than showing how the Groovy JDK adds new methods to standard Java data types, this example also demonstrates that encoded text isn’t encrypted. Anyone who intercepts the request and accesses the encoded header can extract the username and password. Using basic authentication therefore is not at all secure if the requests are transmitted over an unencrypted connection, like HTTP. At a minimum the request should be sent over HTTPS instead.4
There are lots and lots of useful methods in the Groovy JDK. As another example, date manipulation is always painful in Java.5 Groovy doesn’t necessarily fix the many problems, but the Groovy JDK adds several methods to make date-related classes more
4For several years Twitter supported basic authentication as part of its RESTful API. Hopefully all the many Twitter clients who used it transmitted their authentication over secure sockets. If not you might want to consider changing your password. These days Twitter has switched to OAuth, which may be overly complicated but is much better than basic authentication.
5Java 8 is supposed to fix this, at long last. In the meantime, the open source date/time library of choice in the Java world is Joda time: http://joda-time.sourceforge.net/.
www.it-ebooks.info

Making Java library classes better: the Groovy JDK |
73 |
Invokes getTime to return a Date
powerful. Here’s an example, which hopefully will be both interesting and at least mildly amusing to some readers.
In the United States and Canada, February 2 is known as Groundhog Day. On Groundhog Day, the groundhog is supposed to emerge from his hole and look for his shadow. If he doesn’t see it he’ll stay out of the burrow, and winter is nearly over. If he sees his shadow, he goes back to sleep in his burrow, and we’ll sadly have to suffer through six more weeks of winter.
Let’s check the math on that, though, as shown in the next listing.
Listing 4.5 GroundHog Day—an example of Date and Calendar in the Groovy JDK
println 'Groundhog sees shadow --> 6 more weeks of Winter' def c = Calendar.instance
c.set 2013, Calendar.FEBRUARY, 2 def groundHogDay = c.time
c.set 2013, Calendar.MARCH, 20 def firstDayOfSpring = c.time
def days = firstDayOfSpring – groundHogDay assert days == (firstDayOfSpring..groundHogDay).size() – 1 println """
There are ${(int)(days/7)} weeks and ${days % 7} days between GroundHog Day and the first day of Spring (March 20), so Spring
comes early if the groundhog sees his shadow.
"""
I get an instance of the Calendar class by accessing its instance property. Of course, there’s no instance property in Calendar, but the syntax actually means that I invoke the static getInstance method with no arguments. Then I call set with the appropriate arguments for Groundhog Day and the first day of spring. Extracting a Date instance from the Calendar is done through the getTime method (sigh6), which again is invoked by accessing the time property. So far this is straight Java, except that I’m invoking methods via properties and omitting optional parentheses.
I can subtract dates, though, because the Groovy JDK shows that the minus method in Date returns the number of days between them. The Date class has a next method and a previous method and implements compareTo. Those are the requirements necessary for a class to be used as part of a range, so I can check the math by invoking the size method on a range. The size of a range counts both ends, so I have to correct for the potential off-by-one error by subtracting one.
The bottom line is that there are six weeks and four days between Groundhog Day and the first day of spring (March 20). In other words, if the groundhog sees his shadow the resulting six more weeks of winter is actually a (slightly) early spring anyway.7
One last convenience should be noted here. In Java, arrays have a length property, strings have a length method, collections have a size method, NodeLists have
6Seriously, couldn’t the method getDate have been used to extract a Date from a Calendar?
7Yes, that’s a long way to go for a gag, but it does clearly show a mix of Java and Groovy that takes advantage of both Groovy JDK methods and operator overloading. The joke is just a side benefit.
www.it-ebooks.info