Groovy Basics

In this section I am going to cover the basics like imports, keywords, comments, assertions, scripts classes and numbers.

Groovy by default imports a number of packages, the reason is that many of the common classes are used and thus this reduces boilerplate code for example you dont have to type System.out.println(...) and instead can use println(...)

Default imports
import java.lang.*
import java.util.*
import java.io.*
import java.net.*
import groovy.lang.*
import groovy.util.*
import java.math.BigInteger
import java.math.BigDecimal
Single and Star imports
import groovy.xml.MarkupBuilder              // single import
import groovy.xml.*                          // star import
Static import
import static Boolean.FALSE                  // static import
Import aliasing
import java.sql.Date as SQLDate                          // use an alias

SQLDate sqlDate = new SQLDate(1000L)                     // now you can use either Date or SQLDate (alias)

import static Calendar.getInstance as now                // you can use aliasing with static imports as well
assert now().class == Calendar.getInstance().class

As with other programming lanuages Groovy has many keywords that cannot be used as a variable, method or class name.

Keywords/Reserved words
abstract, as, assert, boolean, break, byte, case, catch, char, class, const, continue, def, default, do, 
double, else, enum, extends, false, final, finally, float, for, goto, if, implements, import, in, instanceof,
int, interface, long, native, new, null, package, private, protected, public, return, short, static, strictftp,
super, switch, synchronized, this, threadsafe, throw, throws, transient, true, try, void, volatile and while. Also reserved are DEFAULTING, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS, WEEKS, MONTHS, YEAR and DATEFORMAT_DEFAULT. Note: that is really the same as Java bearing in mind that Groovy runs via a JVM.

Some of the comments in Groovy are the same as in Java, there are two extra ones related to Groovy. Make sure you don't go overboard with comments only add them if it would help the next developer. 

Single-line comment
// This is a single-line comment
Multi-line comment
/* This is a 
multi-line comment which
can expand multiple
lines :-) */
Groovy Doc comment
/** 
* This is a comment
* for Groovy documentation
* and can expand multiple lines
*/
shebang comment
#!/usr/bin/groovy                 // same as other linux scripting shebang

Assertions can be used to test your program, you assume a value and you can test for that value in your code to make sure everything is working correctly, if the assert is not true then you get a failed error message.

Assert example
// you must provide an assertion an expression that evaluates to true
assert true

// we can provide a full expression on the right hand side
// note that unlike Java and more like Ruby or Scala == is equality
assert 1 == 1

// like the example above we are evaluating an expression
def x = 1
assert x == 1

// The power assertion statements true power unleashes in complex Boolean statements,
// or statements with collections or other toString-enabled classesDemo:
def x1 = [1,2,3,4,5]
assert (x1 << 6) == [6,7,8,9,10]

Note: below is what a failed assert looks like in intellij

Groovy appears to be a scripting language like Python or Perl, however its much more, but you can create a groovy file and add a shebang and will will run like a script, but groovy scripts are compiled into a class, but when looked into via AST browser lots of code (including a main method) has been added to make it work with the JVM.

Groovy script
#!/usr/bin/groovy
println "Hello World!"

Note: below is the compiled code looking via a the Groovy console AST browser

Classes basics are that they have properties, methods the same as Java, in Groovy the filename does not have to have the same name as the class, if you have multiple classes in a file then when compiled three .class files will be created just like Java.

Onething to note is that if you add anything other than just the class the file becomes a script and you might get an error duplication of class this is because the scripting code gets compiled into a file called Developer.class the same as the Developer class you have coded. // to get around this problem you must either rename the the file different from the // class above or rename the class above

Class basics
// No need to have the filename the same as the class name
// You can have multiple classes in one file
// Three .class files will have three separate classes
class AngryBirds {
}

class Bird {
}

class Pig {
}
Class example
Developer.groovy
--------------------------------------------------------------------------------------------
        
class Developer {
    String firstName
    String lastName

    // def means any type
    def languages = []      // ArrayList

    void work(){
        println "$firstName $lastName"
    }
}

// anything here would be a script but we get an error
// duplication of class this is because the below code get compiled into a file
// called Developer.class the same as the class above

// to get around this problem you must either rename the the file different from the
// class above or rename the class above
//def dev1 = new Developer("Lorraine", "Valle")
//println dev1


AppDevloper.groovy
--------------------------------------------------------------------------------------------

Developer d = new Developer()
d.firstName = "Paul"

// getter and setter methods are automatically created for all member variables
d.setLastName("Valle")

// def keyword means any type
println d.languages.class

d.languages << "Groovy"
d.languages << "Java"

println d.languages     // uses default toString

d.work()

Numbers in Groovy are all wrapper object classes Integer, Float, Double, BigDecimal or Boolean

Numbers in groovy
// In groovy primitive types they are autoboxed to the equivalent type object
println 1234.getClass().getName()             // java.lang.Integer

int x = 1
println x.class         // Integer Object

def y = 5.9876f
println y.class         // Float Object

def z = 5.05d
println z.class         // Double Object

boolean a = true
println a.class         // Boolean Object

Control Structures

In Groovy you have the following

The if and switch statements are the same in other programming languages, see examples below

if, else statement
if( false ) {
    println "true"
} else { 
    println "false"
}
if, else-if, else statement
def someage = 37

if( someage >= 21 && someage < 35 ) {
    println "buy some beer"
} else if( someage >= 35 ) {
    println "run for president"
} else {
    println "under 21..."
}
switch statement
def num = 12

switch( num ) {
    case 1:
        println "1"
        break
    case 2:
        println "2"
        break
    case 1..3:
        println "in range 1..3"    
        break
    case [1,2,12]:
        println "num is in list [1,2,12]"
        break
    case Integer:
        println "num is an Integer"
        break
    case Float:
        println "num is a float"
        break
    default:
        println "default..."    
}

Loops in Groovy are again the same in as in other programming languages, see some examples below

while loop
// while
List numbers = [1,2,3]

while( numbers ) {             // while there is a number in numbers
    // do something
    numbers.remove(0)
}
for-in loop
List nums = [1,2,3]
for( Integer i in 1..10 ) {
    println i
}


for( i in 1..5 ) { 
    // Do something
}

for( String s in 'a'..'z' ){
    if( s == 'a') continue
        println s
    if( s > 'b' ) break
}
Closure
def list = [1,2,3,4,5]
list.each { println it }

For exceptions you have the traditonal try-catch block

try {
  foo()  
} catch( Exception e ) {
    log << e.message            // same as e.getMessage()
} finally {
    log << 'finally'
}
println log

// Java 7 introduced a multi catch syntax
try {
    // do stuff
} catch( FileNotFoundException | NullPointerException e ) {             // notice only one |
    println e.class.name
    println e.message
}

Annonations and AST

AST (Abstract Syntax Tree) transforms allows us to hook into the Groovy compilation process and customize it to meet our needs, an annotation is an AST transformation. Annotations in Groovy are the same as in Java, if you have not used annotations before, Annotations are a form of metadata wherein they provide data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate, they are used for, we can also use the built-in ones

Here are a few annotation examples but there are many more, see the Groovy documentation for a list of all annotations

Annotation example
@ToString(includeNames = true, excludes = ["email"])         // create a method called toString but exclude email    
class Person {
    String first
    String last
    String email
}

@Canonical                                        //  toString, tuple and equals combined into one)
@Sortable( includes = ['last', 'first'] )         // sort in the order of last then first
class Person {
    String first
    String last
}


@Singleton                                        // singleton annotation
class DatabaseConnection {

}

Operators

Groovy has many operators incluide ones that are specific to the Groovy

Arithmetic
assert 10 + 1 == 11
assert 10 - 1 == 9
assert 10 * 2 == 20
assert 10 / 5 == 2
assert 10 % 3 == 1
assert 10 ** 2 == 100
Binary
// += -= *= /= %= **=

def a = 10
a += 5                         // a = a + 5
assert a == 15
Relational
assert 1 + 2 == 3
assert 3 != 4

assert -2 < 3
assert 2 <= 2
assert 3 <= 4

assert 5 > 1
assert 5 >= -2
Logical
assert !false                 // logical NOT
assert true && true
assert true || false
Ternary
String s1 = ""
result = ( s1 != null && s1.length() > 0 ) ? 'Found' : 'Not Found'
Elvis
class User {
    String name
}
def user = new User(name: 'Paul Valle')
displayName = user.name ? user.name : 'Anonymous'
displayName = user.name ?: 'Anonymous'                    // short-hand of above
Safe Navigation
// Java Code
Person2 p = new Person2()
if( p.address != null ) {                       // in groovy use p?.address
    Address address = p.address
    address.first = "1234 Main"
}

// Groovy Code
def address = p?.address                        // is the same as the !=
assert address == null

Grapes

Grape is a jar dependancy manager in Groovy, Grape (The Groovy Adaptable Packaging Engine or Groovy Advanced Packaging Engine) is the infrastructure enabling the grab() calls in Groovy, Grape will, at runtime, download as needed and link the named libraries and all dependencies forming a transitive closure when the script is run from the selected repository.

If the dependancy has already been pulled down then it won't do it again.

// Grape example
@Grapes(
        @Grab(group='org.apache.commons',module = 'commons-lang3', version = '3.4')
)

// Import a specific version of JdbcTemplate
@Grab(group='org.springframework', module='spring-orm', version='3.2.5.RELEASE')
import org.springframework.jdbc.core.JdbcTemplate

// short-hand of above
@Grab('org.springframework:spring-orm:3.2.5.RELEASE')
import org.springframework.jdbc.core.JdbcTemplate

// Using Maven central as a repository
@GrabResolver(name='restlet', root='http://maven.restlet.org/')
@Grab(group='org.restlet', module='org.restlet', version='1.1.6')