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

298 |
APPENDIX B Groovy by feature |
B.2 Variables, numbers, and strings
Groovy is an optionally typed language. Groovy uses classes to define data types, just as Java does, but Groovy variables can either have a static type or use the def keyword.
For example, I’m perfectly free to declare variables of type int, String, or Employee, using the standard Java syntax:
int x String name
Employee fred
If I don’t know the type of the variable, or I don’t care, Groovy provides the keyword def:
def arg
Typed vs. untyped variables
When should you use def as opposed to the actual type? There’s no strict answer, but recently I had a (very mild) Twitter debate about this issue with Dierk Koenig (lead author of GinA), Andres Almiray (lead author of Griffon in Action and head of the Griffon project), and Dave Klein (lead author of Grails: A Quick-Start Guide). Dierk had the best recommendation I’ve ever heard on the subject. He said, “If I think of a type, I type it (pun intended).”
My own experience is that as I get more experienced with Groovy, I tend to use def less and less. I agree with Dierk’s recommendation, with the added advice that now when I declare a type, I pause for a moment to see if any actual type occurs to me. If so, I use it.
In some cases def is preferred, most notably when using mock objects in testing. That subject is discussed in chapter 6.
Moving on to data types themselves, Java makes a distinction between primitives and classes. In Groovy there are no primitives. Numbers in Groovy are first-class objects, with their own set of methods.
B.2.1 Numbers
Because in Groovy numbers are objects, I can determine their data types. For integer literals, the data type depends on the value, as shown in this script:
x = 1
assert x.class == java.lang.Integer x = 10000000000000000
assert x.class == java.lang.Long x = 100000000000000000000000
assert x.class == java.math.BigInteger
There are a few points to be made about this script. First, the variable x doesn’t have a declaration at all. This is only legal in a script, where the variable becomes part of the script’s binding and can be set and accessed from outside. Details of this procedure
www.it-ebooks.info
Variables, numbers, and strings |
299 |
are shown in chapter 3 on integration with Java. Suffice it to say here that this is legal in a script, but not in a class. If it makes you feel more comfortable, you’re free to add the word def in front of x.
SCRIPT VARIABLES If a variable in a script is not declared, it becomes part of the script’s binding.
As mentioned earlier, the script lacks semicolons. Semicolons as statement separators are optional in Groovy and can be omitted if there’s no ambiguity. Again, you’re free to add them in without a problem.
SEMICOLONS In Groovy, semicolons work but are optional.
Next, Groovy uses the method called assert extensively. The word assert can be written without parentheses, as done here, or you can surround an expression with them. The resulting expression must evaluate to a Boolean, but that’s a much looser requirement than in Java. In Java, the only available Booleans are true and false. In Groovy, non-null references are true, as are nonzero numbers, non-empty collections, nonempty strings, and the Boolean value true.
That bears repeating and goes by the term The Groovy Truth.
THE GROOVY TRUTH In Groovy, non-null references, non-empty collections, non-empty strings, nonzero numbers, and the Boolean value true are all true.
Finally, the default data type for floating-point values in Java is double, but in Groovy it’s java.math.BigDecimal. The double type in Java has approximately 17 decimal places of precision, but if you want to get depressed about its accuracy, try this tiny sample:
println 2.0d – 1.1d
The d appended to the literals makes them doubles. You would expect the answer here to be 0.9, but in fact it’s 0.8999999999999999. That’s not much of a difference, but I’ve only done a single subtraction and I’m already off. That’s not good. That’s why any serious numerical calculations in Java require java.math.BigDecimal, but that means you can’t use the standard operators (+, -, *, /) anymore and have to use method calls instead.
Groovy handles that issue without a problem. Here’s the analogous Groovy script:
println 2.0 – 1.1
The answer in this case is 0.9, as expected. Because the calculations are done with BigDecimal, the answer is correct. Groovy also has operator overloading, so the plus operator can be used with the BigDecimal values. To summarize:
LITERALS Numbers without a decimal point are of type Integer, Long, or java.math.BigInteger, depending on size. Numbers with a decimal point are of type java.math.BigDecimal.
www.it-ebooks.info

300 |
APPENDIX B Groovy by feature |
Because numbers are objects, they have methods as well. Listing B.2 shows a script putting some numbers through their paces. Several of the expressions use closures, which are the subject of section B.4. The simplest definition is to consider them a block of code that’s executed as though it’s an anonymous method call.
Listing B.2 numbers.groovy, showing method calls on numeric literals
assert 2**3 == 8
assert 2**-2 == 0.25 // i.e., 1/(2*2) = 1/4
def x = ""
3.times { x += "Hello" } assert x == "HelloHelloHello"
def total = 0
1.upto(3) { total += it } assert total == 1 + 2 + 3
def countDown = [] |
|
|
|
|
|
5.downto 1, { countDown << "$it ... |
" } |
|
|
|
|
assert countDown == ['5 ... |
', '4 ... |
', '3 ... |
', '2 ... |
', '1 ... |
'] |
Groovy has an exponentiation operator, unlike Java. Numbers have methods like times, upto, and downto. The times operation takes a single argument of type Closure. When the last argument to a method is a closure, you can put it after the parentheses. Because the method has no other arguments, you can leave out the parentheses altogether.
CLOSURE ARGUMENTS If the last argument to a method is a closure, it can be placed after the parentheses.
The upto and downto methods take two arguments, so the parentheses are shown in the former and a comma is used in the latter to indicate that both the number and the closure are arguments to the method. The countDown variable is a list, which will be discussed in section B.3. The left-shift operator has been overloaded to append to the collection, and its argument here is a parameterized string. Groovy has two types of strings, discussed in the next section.
B.2.2 Strings and Groovy strings
In Java, single quotes delimit characters (a primitive) and double quotes surround instances of java.lang.String. In Groovy, both single and double quotes are used for strings, but there’s a difference. Double-quoted strings are used for parameter replacement. They’re not instances of java.lang.String, but rather instances of
groovy.lang.GString.
Here are a couple of examples to show how they’re used:
def s = 'this is a string'
assert s.class == java.lang.String
def gs = "this might be a GString" assert gs.class == java.lang.String assert !(gs instanceof GString)
www.it-ebooks.info

Variables, numbers, and strings |
301 |
gs = "If I put in a placeholder, this really is a GString: ${1+1}" assert gs instanceof GString
Single-quoted strings are always instances of java.lang.String. Double-quoted strings may or may not be Groovy strings, depending on whether parameter replacement is done or not.
Groovy also has multiline strings, with either single or double quotes. The difference again is whether or not parameter replacement is done:
def picard = '''
(to the tune of Let It Snow)
Oh the vacuum outside is endless Unforgiving, cold, and friendless But still we must boldly go
Make it so, make it so, make it so!
'''
def quote = """
There are ${Integer.toBinaryString(2)} kinds of people in the world: Those who know binary, and those who don't
"""
assert quote == '''
There are 10 kinds of people in the world: Those who know binary, and those who don't
'''
There’s one final kind of string, used for regular expressions. Java has had regularexpression capabilities since version 1.4, but most developers either aren’t aware of them or avoid them.6 One particularly annoying part of regular expressions in Java is that the backslash character, \, is used as an escape character, but if you want to use it in a regular expression, you have to backslash the backslash. This leads to annoying expressions where you have to double-backslash the backslashes, making the resulting expressions almost unreadable.
Groovy provides what’s called the slashy syntax. If you surround an expression with forward slashes, it’s assumed to be a regular expression, and you don’t have to doublebackslash anymore.
STRINGS Groovy uses single quotes for regular strings, double quotes for parameterized strings, and forward slashes for regular expressions.
Here’s an example that checks strings to see if they are palindromes: that is, if they are the same forward and backward. To check for palindromes you first need to remove any punctuation and ignore case before reversing the string:
def palindromes = '''
Able was I ere I saw Elba Madam, in Eden, I'm Adam
6Perl programmers love regular expressions. Ruby developers are fond of them, but reasonable about it. Java developers take one look at the JavaDocs for the java.util.regex.Pattern class and recoil in horror.
www.it-ebooks.info