SlideShare uma empresa Scribd logo
1 de 88
Baixar para ler offline
An Introduction to Groovy for Java
Developers
Kostas Saidis
www.niovity.com
Java Hellenic User Group Meetup
May 17, 2014
Outline
Introduction
to Groovy
1. Meet
Groovy
What is Groovy?
Groovy History
Why Groovy
2. Groovy
Basics
Using Groovy
Language
Overview
Closures
Lists and
Ranges
Maps
3. Real-life
Groovy
Open Public
Data Hackathon
Our Web App
JSON and REST
Groovlets
About Me
Kostas Saidis
saiko@niovity.com
Software & Data
Architect
Twitter:
@saikos
Linkedin:
http://gr.linkedin.com/in/saiko
Short bio:
Academia
BSc @ cs.unipi.gr (2001)
MSc @ di.uoa.gr (2004)
PhD @ di.uoa.gr (2011)
Industry
Freelance consultant, developer &
instructor since 1999
Founder & Managing Director
Java
Early Java enthusiast (1997)
Diving into Groovy since 2011
Target audience
Java developers
with little or no experience in
Groovy or dynamic languages.
So, what brings us here?
The Java Platform
1. The language
2. The development kit
3. The virtual machine
The JVM is the key component!
The language and the JDK are aging, striving to catch up with new
developments.
Yet, Java 8 (with Streams and Lambdas) is a huge step forward!
What really brings us here!
The fun of programming
And Groovy programming is a whole lotta fun!
1. Meet Groovy
What is
Groovy?
Groovy
History
Why Groovy
What is Groovy?
Groovy is
a feature-rich
Java-friendly
dynamic language
for the Java platform
Dynamic language?
What is a dynamic language?
A language that allows the types of variables to be
changed at runtime...
...among other things!
In Groovy
We can also change the behavior of objects and classes at runtime (with
Metaprogramming).
Example
Introduce a new method in Strings
1 String.metaClass.isUpperCase = {−>
2 delegate.toCharArray().every{ Character.isUpperCase(it) }
3 }
4 assert "GROOVY".isUpperCase() == true
5 assert "java".isUpperCase() == false
Keep an open mind
A language that doesn't affect the way
you think about programming, is not
worth knowing.
Alan Perlis (1922 - 1990)
ACM Turing Award, 1966
Languages and Typing
Static vs. Dynamic
Statically typed: resolves the types of variables during
compilation. (e.g. Java)
Dynamically typed: resolves the types of variables at runtime.
(Groovy)
Weak vs. Strong
Strongly typed: you can't coerce to a wrong type --the
language guarantees type conformance. (Java & Groovy)
Weakly typed: you can screw everything up in all possible ways.
(e.g. C)
Java-friendly?
Groovy is:
A super version of Java
Augments Java with additional features → the GDK extends JDK in
so many helpful ways!
Designed as a companion language for Java
seamless integration with Java → an additional jar at runtime!
syntactically aligned with Java → syntactically correct Java will
work in Groovy (with some gotchas)!
compiles into JVM bytecode and preserves Java semantics → call
Groovy from Java == call Java from Java!
the 2nd language targeting the Java platform (JSR-241) →
Java was the first!
Feature-rich?
Groovy features
Fully object-oriented -- e.g. Traits in new version (2.3).
Optional typing --static or dynamic.
Duck typing.
List, map, range, regular expression literals.
Operator overloading.
Closures.
GroovyBeans.
GString and GPath.
Multimethods and metaprogramming.
Easily build custom DSLs (e.g. Gradle, Spock).
Example
Optional Typing
1 def s1 = "saiko"
2 assert s1.class == String.class
3 s1 = 3
4 assert s1.class == Integer.class
5 Integer s2 = 3
6 try {
7 s2 = "saiko"
8 }
9 catch(ex) {
10 assert ex.message == "Cannot cast object 'saiko' with class '
java.lang.String' to class 'java.lang.Integer'"
11 }
Groovy History
2003: Started by James Strachan and Bob McWhirter.
2004: Commissioned into JSR 241 but was almost abandoned.
2005: Brought back to life by Guillaume Laforge and Jeremy
Rayner.
2007: Groovy version 1.0.
2012: Groovy version 2.0.
2014: Groovy version 2.3 (official support for JDK 8).
Going Mainstream
Awesome Groovy-based tools & frameworks
Grails: Web development framework.
Gradle: Build automation tool. (my next one, if you like!)
Spock: Testing and specification framework.
CodeNarc: Static analysis tool.
easyb: Behavior-driven development framework.
Geb: Browser automation tool.
Griffon: Desktop app framework.
GPars: Multi-paradigm concurrency framework.
Groovy is supported by Pivotal.
Why Groovy?
Open Source. → Apache v2.0 License.
Near-zero learning curve. → You' ll become a Groovyist before
you realize it!
Leverage Java investment. → Rock-solid Java foundations.
Focus on your problem/app. → No more boilerplate!
More expressive, powerful and concise code. →
Productivity boost!
A picture is worth some thousand words
2. Groovy Basics
Using
Groovy
Language
Overview
Closures
Lists and
Ranges
Maps
Groovy Tools
1. groovyc: Compliles groovy sources to JVM class files.
2. groovysh: Executes code interactively.
3. groovyConsole: GUI for interactive code execution
the best place to start .
4. groovy: Executes groovy scripts. Use it like bash, perl, python,
etc. (#!/usr/bin/groovy).
5. groovydoc: Generates documentation (like javadoc).
Using the Groovy Console
Use Groovy console to experiment, test and evaluate code.
Using the Groovy Interpreter
What date/time is it?
groovy −e "print new Date()"
List files recursively
groovy −e "new File('.').
eachFileRecurse { println it }"
Groovy scripts
No mandatory class definitions, no main methods, no
boilerplate.
Groovy creates them for you automagically!
Writing a Groovy script
Fibonacci.groovy
1 def fib(n) { // a method: the return type is not mandatory
2 n<2 ? 1 : fib(n−1)+fib(n−2)
3 }
4 if (args) { // command−line args
5 println fib(args[0] as Integer)
6 }
Groovy scripts continued
Running the script
> groovy Fibonacci 8
34
> groovyc Fibonacci.groovy
> java −cp $GROOVY_HOME/embeddable/
groovy−all.2.0.0.jar:. Fibonacci 8
34
The Groovy Syntax
The majority of Java syntax is part of the Groovy syntax:
packages
imports
control structures
exception handling
classes and methods
object instantiation and method calls
Gotchas: Arrays, additional Groovy keywords, equals checks, etc.
Default imports
The following imports are included by default
java.lang.*
java.util.*
java.net.*
groovy.lang.*
groovy.util.*
java.math.BigInteger and java.math.BigDecimal
Groovy truth and equals
Null value is false.
Empty collection or map is false.
Empty string is false.
Zero value is false.
Gotcha
The == operator performs value equality (like Java
equals() ).
Use the method is for identity (available in every Groovy
object).
Groovy truth
Examples
1 def f = null
2 def t = "string"
3 assert f == false
4 assert t == true
5 list = []
6 map = [a:1]
7 assert list == false
8 assert map == false
9 String s = ""
10 assert s == false
11 i = 1
12 z = 0.0
13 assert i == true
14 assert z == false
Optionals
The following are optional:
semicolons: required only when you write multiple statements
in one line.
variable types: you decide what should be static or dynamic.
return statements: the last evaluated expression is the
default return value Gotcha .
parentheses: in method/function invocations Gotcha .
Optionals
Examples
1 //a method
2 def fac(n) { n<=1? 1 : n*fac(n−1)}
3 assert fac(3) == 6
4 //a method with default arg value
5 Integer factorial(Integer n=3) { return (n<=1? 1 : n*factorial(n
−1)) }
6 assert factorial(3) == 6
7 //invoke them without parentheses
8 def x = fac 3
9 def y = factorial 3
10 assert x == y
11 x = fac 3 + 1 //will calculate the factorial of 4.
12 assert x == fac(4) //Not always what you want!
13 x = fac(3 + 1) //use parentheses to disambiguate
14 //where parentheses are required
15 x = factorial() //Groovy will look for a property otherwise
16 assert x == fac(3)
Everything is an object
In Groovy:
all objects are derived from groovy.lang.GroovyObject, which
extends java.lang.Object.
all integral numbers are java.lang.Integers (or java.lang.Longs
using the proper Java notation).
all real numbers are java.math.BigDecimals.
all booleans are java.lang.Booleans.
Example
Everything's an object
1 def x = 1
2 int y = 1
3 assert x.class == Integer.class
4 assert y.class == Integer.class
5 def l = 1L
6 assert l.class == Long.class
7 def z = 0.3
8 assert z.class == BigDecimal.class
9 def flag = false
10 assert flag.class == Boolean.class
Strings
Groovy strings support:
Single quotes: ordinary strings.
Double quotes: ordinary strings with variable expansion
(GStrings).
Triple quotes: multi-line strings with variable expansion
(GStrings).
Slashy strings: strings enclosed in slashes; no need to escape
backslashes (useful for regular expressions and file paths).
operator overloading.
Examples
Strings
1 def mlStr = """ I am a multi−line
2 string!"""
3 def name = 'Angus';def surname = "Young"
4 //GStrings
5 def fullname = "$name $surname"
6 assert fullname == "Angus Young"
7 //operator overloading
8 def s = name * 3
9 assert s == "AngusAngusAngus"
10 s = fullname − name
11 assert s.trim() == surname
12 //slashy strings: preserve backslashes; no escaping is required
13 s = /nr/
14 assert s.size() == 4
Numbers
In Groovy all numbers are objects and BigDecimal arithmetic is used by
default.
Examples
1 def x = 3
2 assert x.plus(4) == x + 4
3 assert x.multiply(4) = x * 4
4 assert x.mod(4) == x % 4
5 //BigDecimal arithmetic
6 assert x/4 == x.div(4)
7 assert x/4 != x.intdiv(4)
8 assert 1/2 == 0.5
9 assert 1/3 == 0.3333333333
Java beans for human beings
In Groovy classes/beans:
Methods and classes are public by default.
Members are private by default.
The @PackageScope annotation is used for package scoped
class members.
Enhanced bean property support.
Dynamic constructor arguments.
Accessors (getters and setters) are generated automatically.
You can use the this keyword inside static methods (which
refers to this class).
Defining a Groovy class
A Person class
1 class Person {
2 String name
3 String surname
4 @Override
5 String toString() { "$surname, $name" }
6 }
Compile the Person.groovy
groovyc Person.groovy
Result: A ready to use Person.class
Use the Person class
Examples
From Groovy
1 p = new Person(name:"Theodoros", surname:"Kolokotronis")
2 assert p.toString() == "Theodoros Kolokotronis"
From Java
1 public class UsingPerson {
2 public static void main(String[] args) {
3 Person p = new Person();
4 p.setSurname("Young");
5 p.setName("Angus");
6 HashMap map = new HashMap();
7 map.put("name", "James");
8 map.put("surname", "Bond");
9 Person p1 = new Person(map);
10 }
11 }
Additional Operators
Safe navigation: x?.method()
Elvis: x = y ?: "no y"
Spread: ["java","groovy"]*.size() →
[4,6]
and more... <=> , =~ , ==~ , .@ , .&
Groovy powerful switch statement
1 switch(val) {
2 case "String":
3 //a string
4 break
5 case 10..100:
6 //a range
7 break
8 case Date:
9 //a date instance
10 break
11 case ~/gw+/:
12 //a reg−ex
13 break
14 case ['A', 'B']:
15 //a list
16 break
17 case { it instanceOf Number && it > Integer.MAX_VALUE }
18 //a closure
19 break
20 default:
21 //the default, treated as an "else" in Groovy (if
22 //all else fails, run the default). It should always
23 //be at the end of the switch statement.
24 }
Dynamic method dispatch
Java dispatches methods according to the type of the
arguments at compile time.
Groovy dispatches methods according to the type of the
arguments at runtime (multimethods).
Example
1 public void foo(String arg) { System.out.println("String"); }
2 public void foo(Object o) { System.out.println("Object"); }
3 Object o = "The type of o at runtime is String";
4 foo(o);
Java output: Object
Groovy output: String
Other differences from Java
There is no distinction between checked and unchecked
(runtime) exceptions. All exceptions are runtime exceptions!
Assertions are enabled by default.
Support for default values in method arguments.
use , is and as are keywords. Don't use them as variable
names.
You cannot declare more than one variables in for loops.
Arrays should be initialized with list-like syntax:
int[] a = [1, 2, 3] . Avoid int a[]
notation. Gotcha .
What is a closure?
Definition
A closure is a function together with a referencing environment.
Closures are anonymous functions that:
may accept parameters or return a value,
can be assigned to variables,
can be passed as arguments,
capture the variables of their surrounding lexical scope.
Groovy closures
Example
1 //a block of code assigned to a variable
2 def num = { int n −> n <=> 0 }
3 //what type is that?
4 assert num instanceof Closure
5 //it: the default closure argument
6 def num2 = { it <=> 0 }
7 assert num(−3) == num2(−3)
8 def x = 3
9 def times = { it * x }
10 assert times(3) == 9
11 x = 4
12 assert times(3) == 12
Functional Programming with Groovy
Currying & Higher-order functions
1 def func = { Closure c, int i, int j −>
2 c.call(i, j)
3 }
4 def add = func.curry { int i, int j −> i + j }
5 assert add(1,2) == 3
Composition
1 def add1 = { it + 1}
2 def sq = { it*it }
3 assert sq(add1(2)) == 9 //composition
4 def trans1 = add1 >> sq //left to right
5 assert trans1(2) == sq(add1(2))
6 def trans2 = add1 << sq //right to left
7 assert trans2(2) == add1(sq(2))
Closure owner and delegate
Example
1 //All closures have 3 implicit variables:
2 //this: as in Java
3 //owner: the enclosing object (either a closure or this)
4 //delegate: defaults to owner but can be changed
5 def test = {
6 ((this == owner) && (owner == delegate))
7 return { (this != owner) && (owner == delegate) }
8 }
9 assert test()()
10 //changing the delegate
11 def collectWithIndex = { Closure c−>
12 int i = 0
13 delegate.collect { c(it, i++) }
14 }
15 def map = ["name":"Angus", "surname":"Young"]
16 collectWithIndex.delegate = map
17 def list = collectWithIndex { entry, i −> [i, entry.key, entry.
value] }
18 assert list.flatten() == [0, "name", "Angus", 1, "surname", "
Young"]
Java 8 Lambda Expressions
Groovy closures ̸= Java lambda expressions.
Lambda expressions
Language facility for implementing functional interfaces
Interfaces with a single abstract method.
Function, Predicate, Supplier, Consumer.
Type inference at compile time.
Free variables must be final or effective final.
Do make your Java life easier.
Lists
Groovy offers:
Special syntax for list literals.
Additional common list methods.
Combine with closures for extremely expressive and powerful code!
Examples
1 //a list
2 def list = [1, "2", 3.0]
3 //what type is that?
4 assert list.class == ArrayList.class
5 //list elements
6 assert list.get(1) == "2"
7 assert list[1] == "2"
8 assert list.getAt(1) == "2"
9 //list.getAt(i) equivalent to list[i]
10 //negative indexes − not for the standard list.get(i)
11 assert list[−1] == 3.0
12 assert list.getAt(−2) == "2"
More list examples
1 //another list
2 def list3 = [5, 3, 1, ] //trailing comma OK
3 list3[0] = 3
4 list3.putAt(0, 3) //list.putAt(i,val) equivalent to list[i]=val
5 list3.set(0, 3)
6 assert list3 == [3, 3, 1]
7 //the in operator
8 assert '2' in list
9 assert list.contains('2')
10 //operator overloading
11 assert list + [1] == [1, "2", 3.0, 1]
12 assert list − [1] == ["2", 3.0]
13 assert list * 2 == [1, "2", 3.0, 1, "2", 3.0]
14 assert list + list == list * 2
15 //append to list
16 assert list << 1 == [1, "2", 3.0, 1]
17 def otherList = [4, 5.0, "6"]
18 assert list << otherList == [1, "2", 3.0, 1, [4, 5.0, "6"]]
19 //methods
20 assert list.flatten() == [1, "2", 3.0, 1, 4, 5.0, "6"]
21 assert list.flatten().unique() == [1, "2", 3.0, 4, 5.0, "6"]
Even more list examples
1 //methods that accept closure arguments
2 otherList = list.flatten().collect { it as Integer }
3 assert otherList == [1, 2, 3, 1, 4, 5, 6]
4 def toInt = { Object o −>
5 try { return o as Integer }
6 catch(e) { return 0 }
7 }
8 assert list.flatten().collect(toInt) == otherList
9 assert [5, "6", "seven"].collect(toInt) == [5, 6, 0]
10 //convert a list to a set
11 def set = otherList as Set
12 assert otherList instanceof List
13 assert set instanceof Set
14 //collect is available to all groovy objects
15 set.collect { it + 1 } == [2, 3, 4, 5, 6, 7]
16 //list to string
17 assert otherList.unique().join(', ') == '1, 2, 3, 4, 5, 6'
Enough with these list examples
1 //some more list methods
2 assert otherList.count(1) == 2
3 assert otherList.sum() == 22
4 assert otherList.intersect([1, 3, 4]) == [1, 3, 4]
5 assert otherList.disjoint([0, 10, 20])
6 assert otherList.min() == 1
7 assert otherList.max() == 6
8 assert otherList.reverse().unique().sort() == [1, 2, 3, 4, 5, 6]
9 //some more closures
10 assert otherList.findAll { it%2 == 0} == [2, 4, 6]
11 assert otherList.every { it > 0 } //checks whether the closure
holds for every list element
12 assert !otherList.every { it < 1 }
13 def listWithNulls = [1, null, 2]
14 assert !listWithNulls.every() //checks whether groovy truth
holds for every element
15 //the spread (*.) operator
16 def strings = ['one', 'the other', 'and another']
17 assert strings*.size() == strings.collect { it.size() }
18 //list*.action() calls list.collect { it.action() }
19 assert strings*.toUpperCase() == ['ONE', 'THE OTHER', 'AND
ANOTHER']
Ranges
Groovy:
treats ranges as first-class objects.
offers special syntax for ranges.
Examples
1 def letters = 'a'..'z'
2 def digits = 0..9
3 //what type is that?
4 assert letters.class == ObjectRange
5 assert digits.class == IntRange
6 //okay, but wait...
7 assert letters instanceof java.util.List
8 assert digits instanceof java.util.List
9 //ranges are lists of sequential values.
10 assert digits == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
11 assert letters[0] == 'a'
12 assert letters.size() == 26
More ranges examples
1 //methods
2 def otherDigits = digits.collect { it*2 } //or, equivalently
3 otherDigits = digits*.multiply(2)
4 assert otherDigits == [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
5 //half−open ranges
6 def digits2 = 0..<9 //0 up to 9 exclusive
7 assert digits2.size() == 9
8 //get the from,to values of ranges
9 assert digits.from == digits2.from
10 assert digits.to == digits2.to + 1
11 //another way to express a range
12 assert 1..4 == (1..4)
13 //looping
14 (1..4).each { print it }
15 //stepping
16 (1..4).step(2) { print it }
17 //slicing
18 def list = ['one', 'two', 'three', 'four', 'five', 'six']
19 assert list[1..3] == ['two', 'three', 'four']
20 assert list[0..<2] == ['one', 'two']
21 assert list[−1] == 'six'
22 assert list[3..−1] == ['four', 'five', 'six']
23 assert list[−1..−3] == ['six', 'five', 'four']
Maps
Groovy:
offers pecial syntax for map literals.
provides dditional common map methods.
uses maps + closures for duck typing: if it walks and swims like
a duck, it is a duck! → rapid implementation of interfaces
Examples
1 //a map
2 def map = ['id' : 12, 'name' : "John", 'surname' : "Doe"]
3 assert map.size() == 3
4 //keys which are valid Java identifiers need no quotes
5 def now = new Date()
6 def map2 = [
7 id : 1,
8 value : 2.0,
9 "peter's birthday": now
10 ]
More maps examples
1 //we can use map.key when key is valid Java identifier
2 assert map2.id == 1
3 //we can quote the key if needed
4 assert map2."peter's birthday" == now
5 //we can also use subscription notation map[key]
6 assert map2["peter's birthday"] == now
7 //and the standard get method
8 assert map2.get('value') == 2
9 assert map.get('foo') == null
10 //default value when key not found
11 assert map.get('foo', 'No such key') == 'No such key'
12 //adds the default value in the map
13 assert map.containsKey('foo')
14 //what type is the map?
15 try {
16 assert map.class == LinkedHashMap.class
17 }
18 catch(Error e) {
19 assert map.class == null //the map is looking for the 'class
' key
20 map.getClass() == LinkedHashMap.class
21 }
Even more maps examples
1 //put/update values
2 map.newKey = "new key's value"
3 map2['newKey'] = map.newKey
4 //use parentheses to add the value of a var in a map (and not
its name)
5 def anotherKey = "address"
6 map[(anotherKey)] = "Petraki 28"
7 assert map.address == "Petraki 28"
8 //iterate with each
9 map.each { println "In each: ${it.class}" }
10 //the closure argument is a Map.Entry instance
11 map.each { println "In each again: ${it.key} = ${it.value}" }
12 //all Java Map methods are here
13 assert !map.isEmpty()
14 assert map.containsKey('id')
15 assert map.containsValue(12)
16 //use a HashMap instead of a LinkedHashMap
17 def map3 = new HashMap()
18 assert map3.getClass() == HashMap.class
19 //empty map
20 def map4 = [:]
21 assert !map4//empty map is false
Some more maps examples
1 //find in map
2 assert ['id':12, 'foo':'No such key'] == map.findAll{ it.key.
size() <= 3}
3 //group by
4 def list = [1, '2', 3, '4', '5', 6]
5 def map5 = list.groupBy { it.getClass().getSimpleName() }
6 assert ['String': ['2', '4', '5'], 'Integer': [1, 3, 6]] == map5
7 //store closures in a map
8 def actions = [
9 login : { println "login" },
10 logout : { println "logout" }
11 ]
12 //execute the closures
13 actions.login.call() //or
14 actions['logout'].call() //or
15 actions.logout()
Duck typing
1 //Duck typing − a comparator
2 def cmp = [
3 compare : { a, b −> a.size() <=> b.size() }
4 ] as Comparator
5 assert cmp instanceof Comparator
6 //a list
7 def list2 = ['a' , 'quick', 'brown', 'fox', 'jumps', 'over', 'a'
, 'lazy', 'dog']
8 assert list2.sort(cmp) == ['a', 'a', 'fox', 'dog', 'over', 'lazy
', 'quick', 'brown', 'jumps']
9 //a runnable
10 def r = [
11 run : {
12 def t = Thread.currentThread()
13 println "Thread ${t.getId()} starting"
14 t.sleep(1000)
15 println "Thread ${t.getId()} finished"
16 }
17 ] as Runnable
18 assert r instanceof Runnable
19 new Thread(r).start()
Duck typing continued
Another Example
1 interface Doer {
2 void doThis();
3 void doThat();
4 }
5 class DoerImpl implements Doer {
6 void doThis(){"Did this"}
7 void doThat(){"Did that"}
8 }
9 def doer1 = new DoerImpl()
10 assert doer1 instanceof Doer
11 def doer2 = [
12 doThis:{"This done"},
13 doThat:{"That done"}
14 ] as Doer
15 assert doer2 instanceof Doer
3. Real-life
Groovy
Open
Public Data
Hackathon
Our Web
App
JSON
and REST
Groovlets
Open Public Data Hackathon
Held between 15 - 30 April 2014.
Organized by the Ministry of Administration Reform and E-Governance
(ydmed.gr), in association with:
1. aspete.gr
2. hua.gr
3. ellak.gr
Requirement: deliver an app that utilizes open public data (from
data.gov.gr or elsewhere).
We won the 2nd prize!
And Groovy helped us do it!
We shall discuss:
1. How to build a RESTful API with Groovy and Restlet.
2. How to build dynamic web pages with Groovlets.
Our Web App
A prototype of a cloud service for
Accessing/retrieving data
Searching/querying data
Visualizing/embedding data
through a powerful RESTful API.
Quick demo here
opendatacloud.gr
Technologies used
Backend
Java 7.x
Apache Tomcat 7.0.x
Groovy 2.2.x
Restlet 2.2.0
Apache POI 3.10
Elastic Search 1.1.1
Frontend
Bootstrap 3
jQuery 1.10
D3.js
The data model
We have
Kept thins as simple as possible.
Data source groups: Sets of
Data sources: Tabular data in excel files arranged
in columns
and rows.
After all, it is a prototype!
The web.xml
Two servlets
1 <servlet>
2 <servlet−name>RestletServlet</servlet−name>
3 <servlet−class>org.restlet.ext.servlet.ServerServlet</servlet−
class>
4 <init−param>
5 <param−name>org.restlet.application</param−name>
6 <param−value>com.niovity.opd.restlet.App</param−value>
7 </init−param>
8 </servlet>
9 <servlet−mapping>
10 <servlet−name>RestletServlet</servlet−name>
11 <url−pattern>/api/v0/*</url−pattern>
12 </servlet−mapping>
13 <servlet>
14 <servlet−name>groovy</servlet−name>
15 <servlet−class>groovy.servlet.GroovyServlet</servlet−class>
16 </servlet>
17 <servlet−mapping>
18 <servlet−name>groovy</servlet−name>
19 <url−pattern>*.groovy</url−pattern>
20 </servlet−mapping>
The web.xml continued
And a listener
1 <listener>
2 <listener−class>com.niovity.opd.Listener</listener−class>
3 </listener>
1 package com.niovity.opd
2 class Listener implements ServletContextListener {
3 @Override
4 void contextInitialized(ServletContextEvent e) {
5 try {
6 //Initialize log4j & elastic
7 ...
8 //Initialize the config
9 String basePath = ctx.getRealPath("/data")
10 Config.instance.init(basePath)
11 } catch(Exception e) {
12 System.err.println("Fatal error: ${e.getMessage()}")
13 e.printStackTrace(System.err)
14 throw new ServletException(e.getMessage(), e)
15 }
16 }
17 }
Groovy @Singleton Annotation
Config
1 package com.niovity.opd
2 @Singleton class Config {
3 String basePath
4 Map<String, DataSourceGroup> sourceGroups = [:]
5 void init(String basePath) throws Exception {
6 this.basePath = basePath
7 def groups = [:]
8 DataSourceGroup nte = new DataSourceGroup(
9 id: "nte",
10 title:"...", ...
11 )
12 nte.addDataSource(new DataSource(title: "...",...))
13 groups.nte = nte
14 ...
15 sourceGroups = Collections.unmodifiableMap(groups)
16 }
17 }
The Restlet App
The REST router
1 package com.niovity.opd.restlet
2 import org.restlet.Application
3 import org.restlet.Restlet
4 import org.restlet.routing.Router
5 class App extends Application {
6 @Override
7 synchronized Restlet createInboundRoot() {
8 Router router = new Router(getContext())
9 router.attach "/groups", SourceGroups
10 router.attach "/{grp}/{src}", Source
11 router.attach "/search", Search
12 return router
13 }
14 }
An example of a Restlet
GET the source groups
1 package com.niovity.opd.restlet
2 import ...
3 class SourceGroups extends ServerResource{
4 @Override
5 protected Representation get() throws ResourceException {
6 def groups = Config.instance.sourceGroups
7 def result = [:]
8 result.total = groups.size()
9 result.groups = []
10 groups.each {
11 def group = [id : it.key, title : it.value.title, ...]
12 group.sources = []
13 it.value.dataSources().eachWithIndex { source, index −>
14 def src = [id:"/${it.key}/$index",...]
15 group.sources.push(src)
16 }
17 result.groups.push(group)
18 }
19 return new JsonRespresentation(result)
20 }
21 }
JSON
JsonRepresentation
1 package com.niovity.opd.restlet
2 import groovy.json.JsonBuilder
3 import org.restlet.data.MediaType
4 import org.restlet.representation.WriterRepresentation
5 class JsonRespresentation extends WriterRepresentation {
6 private Map result
7 JsonRespresentation(Map result) {
8 super(MediaType.APPLICATION_JSON)
9 this.result = result ?: [:]
10 }
11 @Override
12 void write(Writer writer) throws IOException {
13 new JsonBuilder(result).writeTo(writer)
14 }
15 }
Groovlets
Groovy scripts on the server side
Compiled on the fly
No boilerplate
With some handy implicit variables provided by default
request,response : Http servler request and
response
params : request parameters
context, application : the ServletContext
object
session : the HttpSession object
out : the writer of the response
sout : the output stream of the response
html: a groovy.xml.MarkupBuilder which writes to out
Display a data source in HTML table
source.grovy
1 String groupId = request.getParameter("grp")
2 String srcId = request.getParameter("src")
3 def group = Config.instance.sourceGroups.get(groupId)
4 def sources = group.dataSources()
5 int index = srcId as Integer
6 def source = group.dataSources().get(index)
7 println """
8 ...
9 <table class="table table−bordered table−striped" >
10 <thead>
11 <tr>
12 <th>#</th>
13 ${source.columnNames.collect {"<th>$it</th>"}.join("")}
14 </tr>
15 </thead>
16 <tbody >
17 """
HTML table continued
source.grovy
1 source.rows.eachWithIndex {Map row, int i −>
2 println """
3 <tr>
4 <td>${i+1}</td>
5 ${source.columnNames.collect{ "<td>${row.get(it)}</td>"}.join
("")}
6 </tr>
7 """
8 }
9 println """
10 </tbody>
11 </table>
12 ...
13 """
4. Epilogue
Groovy is Java on steroids!
Easy to use: Its integration with the Java platform is insanely
brilliant!
Expressive: Do more with less code!
Effective: Focus on your app and stop wasting your time with
the irrelevant!
Agile: Groovy is agile and rapid prototyping is a few Groovy lines
away!
Leverage Java expertise. Build upon your Java skills.
Powerful: The swiss army knife of the Java hacker!
Swiss army knife, indeed
Ain't this groovy or what?
db.groovy
1 @GrabConfig(systemClassLoader=true)
2 @Grab(group='mysql', module='mysql−connector−java', version='
5.1.6')
3 import groovy.sql.Sql
4 def query="select count(*) as c, date(creationDate) as d from
dofields group by d order by c desc limit 10"
5 def url="jdbc:mysql://localhost:3306/test_db?characterEncoding=
utf−8"
6 def (u,p)=["test","test"]
7 try {
8 def sql = Sql.newInstance(url,u,p,"com.mysql.jdbc.Driver")
9 sql.eachRow(query) { println("${it.c}:${it.d}") }
10 }
11 catch(e) { e.printStackTrace() }
Output
Run it
groovy db
Output
1 9427:2004−08−20
2 6615:2004−10−29
3 5498:2004−10−08
4 5103:2004−08−31
5 4864:2004−10−14
6 4675:2004−10−31
7 4583:2004−10−05
8 4570:2004−08−21
9 4339:2004−09−30
10 4235:2004−10−30
Groovy rocks!
We 've only scratched the surface
Groovy topics not covered
Metaprogramming
Grape
Builders
Working with XML
Working with SQL
Testing
And much, much more...
Perhaps in a 2nd part?
What about performance?
Programmers have spent far too much time
worrying about efficiency in the wrong places
at the wrong times; premature optimization is
the root of all evil.
Donald E. Knuth
ACM Turing Award, 1974
Put in other terms
The reason to use Groovy should be because it
improves your performance not the computer's.
matthew@stackoverflow
About Groovy Performance
Sorry, it hasn't bothered me yet.
Groovy 2.x introduced the @CompileStatic annotation.
Most of Groovy method calls are compiled into direct JVM bytecode
method calls.
People report that Groovy reaches to almost identical performance
with Java.
Start with Groovy and (re)write your performance-critical
classes in Java as you grow.
You can find various benchmarks and performance comparisons
on the web.
Any volunteers for benchmarking, should we do a 2nd part?
Resources
1. Programming Groovy 2, V. Subramaniam, The Pragmatic
Bookshelf, 978-1-937785-30-7, 2013
2. Groovy in Action, D. Koenig, A. Glover, P. King, G. Laforge and J.
Skeet, Manning Publications, 1-932394-84-2, 2007
3. Groovy Web Site
http://groovy.codehaus.org
4. Groovy language documentation beta
http://beta.groovy-lang.org/docs/
groovy-2.3.0/html/documentation/
Thank you
Questions?
Proudly powered by:
LATEX
Using the Beamer class &
the Wronki theme (slightly modified).

Mais conteúdo relacionado

Mais procurados

Metaprogramming Techniques In Groovy And Grails
Metaprogramming Techniques In Groovy And GrailsMetaprogramming Techniques In Groovy And Grails
Metaprogramming Techniques In Groovy And Grails
zenMonkey
 
Groovy overview, DSLs and ecosystem - Mars JUG - 2010
Groovy overview, DSLs and ecosystem - Mars JUG - 2010Groovy overview, DSLs and ecosystem - Mars JUG - 2010
Groovy overview, DSLs and ecosystem - Mars JUG - 2010
Guillaume Laforge
 

Mais procurados (20)

2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws
 
Eclipsecon08 Introduction To Groovy
Eclipsecon08 Introduction To GroovyEclipsecon08 Introduction To Groovy
Eclipsecon08 Introduction To Groovy
 
Metaprogramming Techniques In Groovy And Grails
Metaprogramming Techniques In Groovy And GrailsMetaprogramming Techniques In Groovy And Grails
Metaprogramming Techniques In Groovy And Grails
 
GR8Conf 2009: Practical Groovy DSL by Guillaume Laforge
GR8Conf 2009: Practical Groovy DSL by Guillaume LaforgeGR8Conf 2009: Practical Groovy DSL by Guillaume Laforge
GR8Conf 2009: Practical Groovy DSL by Guillaume Laforge
 
DSL's with Groovy
DSL's with GroovyDSL's with Groovy
DSL's with Groovy
 
Groovy overview, DSLs and ecosystem - Mars JUG - 2010
Groovy overview, DSLs and ecosystem - Mars JUG - 2010Groovy overview, DSLs and ecosystem - Mars JUG - 2010
Groovy overview, DSLs and ecosystem - Mars JUG - 2010
 
Greach 2014 - Metaprogramming with groovy
Greach 2014 - Metaprogramming with groovyGreach 2014 - Metaprogramming with groovy
Greach 2014 - Metaprogramming with groovy
 
Dart
DartDart
Dart
 
Groovy DSL
Groovy DSLGroovy DSL
Groovy DSL
 
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
 
Introduction to Groovy runtime metaprogramming and AST transforms
Introduction to Groovy runtime metaprogramming and AST transformsIntroduction to Groovy runtime metaprogramming and AST transforms
Introduction to Groovy runtime metaprogramming and AST transforms
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to Go
 
Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012
 
Groovy AST Demystified
Groovy AST DemystifiedGroovy AST Demystified
Groovy AST Demystified
 
Groovy AST Transformations
Groovy AST TransformationsGroovy AST Transformations
Groovy AST Transformations
 
Ast transformation
Ast transformationAst transformation
Ast transformation
 
Go 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX GoGo 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX Go
 
Groovy And Grails Introduction
Groovy And Grails IntroductionGroovy And Grails Introduction
Groovy And Grails Introduction
 
Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with Groovy
 

Destaque

新規 Microsoft power point presentation
新規 Microsoft power point presentation新規 Microsoft power point presentation
新規 Microsoft power point presentation
Akira Sawada
 
The Pub Digital Press Kit
The Pub Digital Press KitThe Pub Digital Press Kit
The Pub Digital Press Kit
TRG2014
 
5. arteria carotida int.
5. arteria carotida int.5. arteria carotida int.
5. arteria carotida int.
anatogral
 
Hb networking 2014
Hb networking 2014Hb networking 2014
Hb networking 2014
suzcarle
 
4. arteria carotida externa
4. arteria carotida externa4. arteria carotida externa
4. arteria carotida externa
anatogral
 
Nft Distribution Holdings interview questions and answers
Nft Distribution Holdings interview questions and answersNft Distribution Holdings interview questions and answers
Nft Distribution Holdings interview questions and answers
mayanevaeh121
 

Destaque (20)

Curso de Groovy
Curso de GroovyCurso de Groovy
Curso de Groovy
 
Arduino e Python: Do It Yourself
Arduino e Python: Do It YourselfArduino e Python: Do It Yourself
Arduino e Python: Do It Yourself
 
Groovy Power Features
Groovy Power FeaturesGroovy Power Features
Groovy Power Features
 
Refactoring: Improve the design of existing code
Refactoring: Improve the design of existing codeRefactoring: Improve the design of existing code
Refactoring: Improve the design of existing code
 
Confessions of a java developer that fell in love with the groovy language
Confessions of a java developer that fell in love with the groovy languageConfessions of a java developer that fell in love with the groovy language
Confessions of a java developer that fell in love with the groovy language
 
Aldenmc capabilities 05-12-14-cc
Aldenmc capabilities 05-12-14-ccAldenmc capabilities 05-12-14-cc
Aldenmc capabilities 05-12-14-cc
 
남동구 라선거구 최승원
남동구 라선거구 최승원남동구 라선거구 최승원
남동구 라선거구 최승원
 
When the connection fails
When the connection failsWhen the connection fails
When the connection fails
 
Heart buddy
Heart buddyHeart buddy
Heart buddy
 
Heart buddy
Heart buddyHeart buddy
Heart buddy
 
How aspects clean your code
How aspects clean your codeHow aspects clean your code
How aspects clean your code
 
新規 Microsoft power point presentation
新規 Microsoft power point presentation新規 Microsoft power point presentation
新規 Microsoft power point presentation
 
The Pub Digital Press Kit
The Pub Digital Press KitThe Pub Digital Press Kit
The Pub Digital Press Kit
 
5. arteria carotida int.
5. arteria carotida int.5. arteria carotida int.
5. arteria carotida int.
 
Hb networking 2014
Hb networking 2014Hb networking 2014
Hb networking 2014
 
Clip voor altijd in mijn hart
Clip voor altijd in mijn hartClip voor altijd in mijn hart
Clip voor altijd in mijn hart
 
Predicting the Future as a Service with Azure ML and R
Predicting the Future as a Service with Azure ML and R Predicting the Future as a Service with Azure ML and R
Predicting the Future as a Service with Azure ML and R
 
4. arteria carotida externa
4. arteria carotida externa4. arteria carotida externa
4. arteria carotida externa
 
Sveriges politiska partier
Sveriges politiska partierSveriges politiska partier
Sveriges politiska partier
 
Nft Distribution Holdings interview questions and answers
Nft Distribution Holdings interview questions and answersNft Distribution Holdings interview questions and answers
Nft Distribution Holdings interview questions and answers
 

Semelhante a An Introduction to Groovy for Java Developers

eXo EC - Groovy Programming Language
eXo EC - Groovy Programming LanguageeXo EC - Groovy Programming Language
eXo EC - Groovy Programming Language
Hoat Le
 
Polyglot Programming in the JVM
Polyglot Programming in the JVMPolyglot Programming in the JVM
Polyglot Programming in the JVM
Andres Almiray
 

Semelhante a An Introduction to Groovy for Java Developers (20)

Groovy intro
Groovy introGroovy intro
Groovy intro
 
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume LaforgeGroovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
 
Learning groovy -EU workshop
Learning groovy  -EU workshopLearning groovy  -EU workshop
Learning groovy -EU workshop
 
Groovy features
Groovy featuresGroovy features
Groovy features
 
Groovy Update - JavaPolis 2007
Groovy Update - JavaPolis 2007Groovy Update - JavaPolis 2007
Groovy Update - JavaPolis 2007
 
Apache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and YouApache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and You
 
An Introduction to Gradle for Java Developers
An Introduction to Gradle for Java DevelopersAn Introduction to Gradle for Java Developers
An Introduction to Gradle for Java Developers
 
Groovy a Scripting Language for Java
Groovy a Scripting Language for JavaGroovy a Scripting Language for Java
Groovy a Scripting Language for Java
 
Oscon Java Testing on the Fast Lane
Oscon Java Testing on the Fast LaneOscon Java Testing on the Fast Lane
Oscon Java Testing on the Fast Lane
 
Groovy!
Groovy!Groovy!
Groovy!
 
Groovy And Grails
Groovy And GrailsGroovy And Grails
Groovy And Grails
 
Groovy best pratices at EWAY
Groovy best pratices at EWAYGroovy best pratices at EWAY
Groovy best pratices at EWAY
 
OpenLogic
OpenLogicOpenLogic
OpenLogic
 
Groovy.pptx
Groovy.pptxGroovy.pptx
Groovy.pptx
 
eXo EC - Groovy Programming Language
eXo EC - Groovy Programming LanguageeXo EC - Groovy Programming Language
eXo EC - Groovy Programming Language
 
What's New in Groovy 1.6?
What's New in Groovy 1.6?What's New in Groovy 1.6?
What's New in Groovy 1.6?
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)
 
Groovy Metaprogramming for Dummies
Groovy Metaprogramming for DummiesGroovy Metaprogramming for Dummies
Groovy Metaprogramming for Dummies
 
Polyglot Programming in the JVM
Polyglot Programming in the JVMPolyglot Programming in the JVM
Polyglot Programming in the JVM
 
Go. Why it goes
Go. Why it goesGo. Why it goes
Go. Why it goes
 

Último

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Último (20)

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 

An Introduction to Groovy for Java Developers

  • 1. An Introduction to Groovy for Java Developers Kostas Saidis www.niovity.com Java Hellenic User Group Meetup May 17, 2014
  • 2. Outline Introduction to Groovy 1. Meet Groovy What is Groovy? Groovy History Why Groovy 2. Groovy Basics Using Groovy Language Overview Closures Lists and Ranges Maps 3. Real-life Groovy Open Public Data Hackathon Our Web App JSON and REST Groovlets
  • 3. About Me Kostas Saidis saiko@niovity.com Software & Data Architect Twitter: @saikos Linkedin: http://gr.linkedin.com/in/saiko Short bio: Academia BSc @ cs.unipi.gr (2001) MSc @ di.uoa.gr (2004) PhD @ di.uoa.gr (2011) Industry Freelance consultant, developer & instructor since 1999 Founder & Managing Director Java Early Java enthusiast (1997) Diving into Groovy since 2011
  • 4. Target audience Java developers with little or no experience in Groovy or dynamic languages.
  • 5. So, what brings us here? The Java Platform 1. The language 2. The development kit 3. The virtual machine The JVM is the key component! The language and the JDK are aging, striving to catch up with new developments. Yet, Java 8 (with Streams and Lambdas) is a huge step forward!
  • 6. What really brings us here! The fun of programming And Groovy programming is a whole lotta fun!
  • 7. 1. Meet Groovy What is Groovy? Groovy History Why Groovy
  • 8. What is Groovy? Groovy is a feature-rich Java-friendly dynamic language for the Java platform
  • 9. Dynamic language? What is a dynamic language? A language that allows the types of variables to be changed at runtime... ...among other things! In Groovy We can also change the behavior of objects and classes at runtime (with Metaprogramming).
  • 10. Example Introduce a new method in Strings 1 String.metaClass.isUpperCase = {−> 2 delegate.toCharArray().every{ Character.isUpperCase(it) } 3 } 4 assert "GROOVY".isUpperCase() == true 5 assert "java".isUpperCase() == false
  • 11.
  • 12. Keep an open mind A language that doesn't affect the way you think about programming, is not worth knowing. Alan Perlis (1922 - 1990) ACM Turing Award, 1966
  • 13. Languages and Typing Static vs. Dynamic Statically typed: resolves the types of variables during compilation. (e.g. Java) Dynamically typed: resolves the types of variables at runtime. (Groovy) Weak vs. Strong Strongly typed: you can't coerce to a wrong type --the language guarantees type conformance. (Java & Groovy) Weakly typed: you can screw everything up in all possible ways. (e.g. C)
  • 14. Java-friendly? Groovy is: A super version of Java Augments Java with additional features → the GDK extends JDK in so many helpful ways! Designed as a companion language for Java seamless integration with Java → an additional jar at runtime! syntactically aligned with Java → syntactically correct Java will work in Groovy (with some gotchas)! compiles into JVM bytecode and preserves Java semantics → call Groovy from Java == call Java from Java! the 2nd language targeting the Java platform (JSR-241) → Java was the first!
  • 15. Feature-rich? Groovy features Fully object-oriented -- e.g. Traits in new version (2.3). Optional typing --static or dynamic. Duck typing. List, map, range, regular expression literals. Operator overloading. Closures. GroovyBeans. GString and GPath. Multimethods and metaprogramming. Easily build custom DSLs (e.g. Gradle, Spock).
  • 16. Example Optional Typing 1 def s1 = "saiko" 2 assert s1.class == String.class 3 s1 = 3 4 assert s1.class == Integer.class 5 Integer s2 = 3 6 try { 7 s2 = "saiko" 8 } 9 catch(ex) { 10 assert ex.message == "Cannot cast object 'saiko' with class ' java.lang.String' to class 'java.lang.Integer'" 11 }
  • 17. Groovy History 2003: Started by James Strachan and Bob McWhirter. 2004: Commissioned into JSR 241 but was almost abandoned. 2005: Brought back to life by Guillaume Laforge and Jeremy Rayner. 2007: Groovy version 1.0. 2012: Groovy version 2.0. 2014: Groovy version 2.3 (official support for JDK 8).
  • 18. Going Mainstream Awesome Groovy-based tools & frameworks Grails: Web development framework. Gradle: Build automation tool. (my next one, if you like!) Spock: Testing and specification framework. CodeNarc: Static analysis tool. easyb: Behavior-driven development framework. Geb: Browser automation tool. Griffon: Desktop app framework. GPars: Multi-paradigm concurrency framework. Groovy is supported by Pivotal.
  • 19. Why Groovy? Open Source. → Apache v2.0 License. Near-zero learning curve. → You' ll become a Groovyist before you realize it! Leverage Java investment. → Rock-solid Java foundations. Focus on your problem/app. → No more boilerplate! More expressive, powerful and concise code. → Productivity boost!
  • 20. A picture is worth some thousand words
  • 22. Groovy Tools 1. groovyc: Compliles groovy sources to JVM class files. 2. groovysh: Executes code interactively. 3. groovyConsole: GUI for interactive code execution the best place to start . 4. groovy: Executes groovy scripts. Use it like bash, perl, python, etc. (#!/usr/bin/groovy). 5. groovydoc: Generates documentation (like javadoc).
  • 23. Using the Groovy Console Use Groovy console to experiment, test and evaluate code.
  • 24. Using the Groovy Interpreter What date/time is it? groovy −e "print new Date()" List files recursively groovy −e "new File('.'). eachFileRecurse { println it }"
  • 25. Groovy scripts No mandatory class definitions, no main methods, no boilerplate. Groovy creates them for you automagically! Writing a Groovy script Fibonacci.groovy 1 def fib(n) { // a method: the return type is not mandatory 2 n<2 ? 1 : fib(n−1)+fib(n−2) 3 } 4 if (args) { // command−line args 5 println fib(args[0] as Integer) 6 }
  • 26. Groovy scripts continued Running the script > groovy Fibonacci 8 34 > groovyc Fibonacci.groovy > java −cp $GROOVY_HOME/embeddable/ groovy−all.2.0.0.jar:. Fibonacci 8 34
  • 27. The Groovy Syntax The majority of Java syntax is part of the Groovy syntax: packages imports control structures exception handling classes and methods object instantiation and method calls Gotchas: Arrays, additional Groovy keywords, equals checks, etc.
  • 28. Default imports The following imports are included by default java.lang.* java.util.* java.net.* groovy.lang.* groovy.util.* java.math.BigInteger and java.math.BigDecimal
  • 29. Groovy truth and equals Null value is false. Empty collection or map is false. Empty string is false. Zero value is false. Gotcha The == operator performs value equality (like Java equals() ). Use the method is for identity (available in every Groovy object).
  • 30. Groovy truth Examples 1 def f = null 2 def t = "string" 3 assert f == false 4 assert t == true 5 list = [] 6 map = [a:1] 7 assert list == false 8 assert map == false 9 String s = "" 10 assert s == false 11 i = 1 12 z = 0.0 13 assert i == true 14 assert z == false
  • 31. Optionals The following are optional: semicolons: required only when you write multiple statements in one line. variable types: you decide what should be static or dynamic. return statements: the last evaluated expression is the default return value Gotcha . parentheses: in method/function invocations Gotcha .
  • 32. Optionals Examples 1 //a method 2 def fac(n) { n<=1? 1 : n*fac(n−1)} 3 assert fac(3) == 6 4 //a method with default arg value 5 Integer factorial(Integer n=3) { return (n<=1? 1 : n*factorial(n −1)) } 6 assert factorial(3) == 6 7 //invoke them without parentheses 8 def x = fac 3 9 def y = factorial 3 10 assert x == y 11 x = fac 3 + 1 //will calculate the factorial of 4. 12 assert x == fac(4) //Not always what you want! 13 x = fac(3 + 1) //use parentheses to disambiguate 14 //where parentheses are required 15 x = factorial() //Groovy will look for a property otherwise 16 assert x == fac(3)
  • 33. Everything is an object In Groovy: all objects are derived from groovy.lang.GroovyObject, which extends java.lang.Object. all integral numbers are java.lang.Integers (or java.lang.Longs using the proper Java notation). all real numbers are java.math.BigDecimals. all booleans are java.lang.Booleans.
  • 34. Example Everything's an object 1 def x = 1 2 int y = 1 3 assert x.class == Integer.class 4 assert y.class == Integer.class 5 def l = 1L 6 assert l.class == Long.class 7 def z = 0.3 8 assert z.class == BigDecimal.class 9 def flag = false 10 assert flag.class == Boolean.class
  • 35. Strings Groovy strings support: Single quotes: ordinary strings. Double quotes: ordinary strings with variable expansion (GStrings). Triple quotes: multi-line strings with variable expansion (GStrings). Slashy strings: strings enclosed in slashes; no need to escape backslashes (useful for regular expressions and file paths). operator overloading.
  • 36. Examples Strings 1 def mlStr = """ I am a multi−line 2 string!""" 3 def name = 'Angus';def surname = "Young" 4 //GStrings 5 def fullname = "$name $surname" 6 assert fullname == "Angus Young" 7 //operator overloading 8 def s = name * 3 9 assert s == "AngusAngusAngus" 10 s = fullname − name 11 assert s.trim() == surname 12 //slashy strings: preserve backslashes; no escaping is required 13 s = /nr/ 14 assert s.size() == 4
  • 37. Numbers In Groovy all numbers are objects and BigDecimal arithmetic is used by default. Examples 1 def x = 3 2 assert x.plus(4) == x + 4 3 assert x.multiply(4) = x * 4 4 assert x.mod(4) == x % 4 5 //BigDecimal arithmetic 6 assert x/4 == x.div(4) 7 assert x/4 != x.intdiv(4) 8 assert 1/2 == 0.5 9 assert 1/3 == 0.3333333333
  • 38. Java beans for human beings In Groovy classes/beans: Methods and classes are public by default. Members are private by default. The @PackageScope annotation is used for package scoped class members. Enhanced bean property support. Dynamic constructor arguments. Accessors (getters and setters) are generated automatically. You can use the this keyword inside static methods (which refers to this class).
  • 39. Defining a Groovy class A Person class 1 class Person { 2 String name 3 String surname 4 @Override 5 String toString() { "$surname, $name" } 6 } Compile the Person.groovy groovyc Person.groovy Result: A ready to use Person.class
  • 40. Use the Person class Examples From Groovy 1 p = new Person(name:"Theodoros", surname:"Kolokotronis") 2 assert p.toString() == "Theodoros Kolokotronis" From Java 1 public class UsingPerson { 2 public static void main(String[] args) { 3 Person p = new Person(); 4 p.setSurname("Young"); 5 p.setName("Angus"); 6 HashMap map = new HashMap(); 7 map.put("name", "James"); 8 map.put("surname", "Bond"); 9 Person p1 = new Person(map); 10 } 11 }
  • 41. Additional Operators Safe navigation: x?.method() Elvis: x = y ?: "no y" Spread: ["java","groovy"]*.size() → [4,6] and more... <=> , =~ , ==~ , .@ , .&
  • 42. Groovy powerful switch statement 1 switch(val) { 2 case "String": 3 //a string 4 break 5 case 10..100: 6 //a range 7 break 8 case Date: 9 //a date instance 10 break 11 case ~/gw+/: 12 //a reg−ex 13 break 14 case ['A', 'B']: 15 //a list 16 break 17 case { it instanceOf Number && it > Integer.MAX_VALUE } 18 //a closure 19 break 20 default: 21 //the default, treated as an "else" in Groovy (if 22 //all else fails, run the default). It should always 23 //be at the end of the switch statement. 24 }
  • 43. Dynamic method dispatch Java dispatches methods according to the type of the arguments at compile time. Groovy dispatches methods according to the type of the arguments at runtime (multimethods). Example 1 public void foo(String arg) { System.out.println("String"); } 2 public void foo(Object o) { System.out.println("Object"); } 3 Object o = "The type of o at runtime is String"; 4 foo(o); Java output: Object Groovy output: String
  • 44. Other differences from Java There is no distinction between checked and unchecked (runtime) exceptions. All exceptions are runtime exceptions! Assertions are enabled by default. Support for default values in method arguments. use , is and as are keywords. Don't use them as variable names. You cannot declare more than one variables in for loops. Arrays should be initialized with list-like syntax: int[] a = [1, 2, 3] . Avoid int a[] notation. Gotcha .
  • 45. What is a closure? Definition A closure is a function together with a referencing environment. Closures are anonymous functions that: may accept parameters or return a value, can be assigned to variables, can be passed as arguments, capture the variables of their surrounding lexical scope.
  • 46. Groovy closures Example 1 //a block of code assigned to a variable 2 def num = { int n −> n <=> 0 } 3 //what type is that? 4 assert num instanceof Closure 5 //it: the default closure argument 6 def num2 = { it <=> 0 } 7 assert num(−3) == num2(−3) 8 def x = 3 9 def times = { it * x } 10 assert times(3) == 9 11 x = 4 12 assert times(3) == 12
  • 47. Functional Programming with Groovy Currying & Higher-order functions 1 def func = { Closure c, int i, int j −> 2 c.call(i, j) 3 } 4 def add = func.curry { int i, int j −> i + j } 5 assert add(1,2) == 3 Composition 1 def add1 = { it + 1} 2 def sq = { it*it } 3 assert sq(add1(2)) == 9 //composition 4 def trans1 = add1 >> sq //left to right 5 assert trans1(2) == sq(add1(2)) 6 def trans2 = add1 << sq //right to left 7 assert trans2(2) == add1(sq(2))
  • 48. Closure owner and delegate Example 1 //All closures have 3 implicit variables: 2 //this: as in Java 3 //owner: the enclosing object (either a closure or this) 4 //delegate: defaults to owner but can be changed 5 def test = { 6 ((this == owner) && (owner == delegate)) 7 return { (this != owner) && (owner == delegate) } 8 } 9 assert test()() 10 //changing the delegate 11 def collectWithIndex = { Closure c−> 12 int i = 0 13 delegate.collect { c(it, i++) } 14 } 15 def map = ["name":"Angus", "surname":"Young"] 16 collectWithIndex.delegate = map 17 def list = collectWithIndex { entry, i −> [i, entry.key, entry. value] } 18 assert list.flatten() == [0, "name", "Angus", 1, "surname", " Young"]
  • 49. Java 8 Lambda Expressions Groovy closures ̸= Java lambda expressions. Lambda expressions Language facility for implementing functional interfaces Interfaces with a single abstract method. Function, Predicate, Supplier, Consumer. Type inference at compile time. Free variables must be final or effective final. Do make your Java life easier.
  • 50. Lists Groovy offers: Special syntax for list literals. Additional common list methods. Combine with closures for extremely expressive and powerful code! Examples 1 //a list 2 def list = [1, "2", 3.0] 3 //what type is that? 4 assert list.class == ArrayList.class 5 //list elements 6 assert list.get(1) == "2" 7 assert list[1] == "2" 8 assert list.getAt(1) == "2" 9 //list.getAt(i) equivalent to list[i] 10 //negative indexes − not for the standard list.get(i) 11 assert list[−1] == 3.0 12 assert list.getAt(−2) == "2"
  • 51. More list examples 1 //another list 2 def list3 = [5, 3, 1, ] //trailing comma OK 3 list3[0] = 3 4 list3.putAt(0, 3) //list.putAt(i,val) equivalent to list[i]=val 5 list3.set(0, 3) 6 assert list3 == [3, 3, 1] 7 //the in operator 8 assert '2' in list 9 assert list.contains('2') 10 //operator overloading 11 assert list + [1] == [1, "2", 3.0, 1] 12 assert list − [1] == ["2", 3.0] 13 assert list * 2 == [1, "2", 3.0, 1, "2", 3.0] 14 assert list + list == list * 2 15 //append to list 16 assert list << 1 == [1, "2", 3.0, 1] 17 def otherList = [4, 5.0, "6"] 18 assert list << otherList == [1, "2", 3.0, 1, [4, 5.0, "6"]] 19 //methods 20 assert list.flatten() == [1, "2", 3.0, 1, 4, 5.0, "6"] 21 assert list.flatten().unique() == [1, "2", 3.0, 4, 5.0, "6"]
  • 52. Even more list examples 1 //methods that accept closure arguments 2 otherList = list.flatten().collect { it as Integer } 3 assert otherList == [1, 2, 3, 1, 4, 5, 6] 4 def toInt = { Object o −> 5 try { return o as Integer } 6 catch(e) { return 0 } 7 } 8 assert list.flatten().collect(toInt) == otherList 9 assert [5, "6", "seven"].collect(toInt) == [5, 6, 0] 10 //convert a list to a set 11 def set = otherList as Set 12 assert otherList instanceof List 13 assert set instanceof Set 14 //collect is available to all groovy objects 15 set.collect { it + 1 } == [2, 3, 4, 5, 6, 7] 16 //list to string 17 assert otherList.unique().join(', ') == '1, 2, 3, 4, 5, 6'
  • 53. Enough with these list examples 1 //some more list methods 2 assert otherList.count(1) == 2 3 assert otherList.sum() == 22 4 assert otherList.intersect([1, 3, 4]) == [1, 3, 4] 5 assert otherList.disjoint([0, 10, 20]) 6 assert otherList.min() == 1 7 assert otherList.max() == 6 8 assert otherList.reverse().unique().sort() == [1, 2, 3, 4, 5, 6] 9 //some more closures 10 assert otherList.findAll { it%2 == 0} == [2, 4, 6] 11 assert otherList.every { it > 0 } //checks whether the closure holds for every list element 12 assert !otherList.every { it < 1 } 13 def listWithNulls = [1, null, 2] 14 assert !listWithNulls.every() //checks whether groovy truth holds for every element 15 //the spread (*.) operator 16 def strings = ['one', 'the other', 'and another'] 17 assert strings*.size() == strings.collect { it.size() } 18 //list*.action() calls list.collect { it.action() } 19 assert strings*.toUpperCase() == ['ONE', 'THE OTHER', 'AND ANOTHER']
  • 54. Ranges Groovy: treats ranges as first-class objects. offers special syntax for ranges. Examples 1 def letters = 'a'..'z' 2 def digits = 0..9 3 //what type is that? 4 assert letters.class == ObjectRange 5 assert digits.class == IntRange 6 //okay, but wait... 7 assert letters instanceof java.util.List 8 assert digits instanceof java.util.List 9 //ranges are lists of sequential values. 10 assert digits == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 11 assert letters[0] == 'a' 12 assert letters.size() == 26
  • 55. More ranges examples 1 //methods 2 def otherDigits = digits.collect { it*2 } //or, equivalently 3 otherDigits = digits*.multiply(2) 4 assert otherDigits == [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] 5 //half−open ranges 6 def digits2 = 0..<9 //0 up to 9 exclusive 7 assert digits2.size() == 9 8 //get the from,to values of ranges 9 assert digits.from == digits2.from 10 assert digits.to == digits2.to + 1 11 //another way to express a range 12 assert 1..4 == (1..4) 13 //looping 14 (1..4).each { print it } 15 //stepping 16 (1..4).step(2) { print it } 17 //slicing 18 def list = ['one', 'two', 'three', 'four', 'five', 'six'] 19 assert list[1..3] == ['two', 'three', 'four'] 20 assert list[0..<2] == ['one', 'two'] 21 assert list[−1] == 'six' 22 assert list[3..−1] == ['four', 'five', 'six'] 23 assert list[−1..−3] == ['six', 'five', 'four']
  • 56. Maps Groovy: offers pecial syntax for map literals. provides dditional common map methods. uses maps + closures for duck typing: if it walks and swims like a duck, it is a duck! → rapid implementation of interfaces Examples 1 //a map 2 def map = ['id' : 12, 'name' : "John", 'surname' : "Doe"] 3 assert map.size() == 3 4 //keys which are valid Java identifiers need no quotes 5 def now = new Date() 6 def map2 = [ 7 id : 1, 8 value : 2.0, 9 "peter's birthday": now 10 ]
  • 57. More maps examples 1 //we can use map.key when key is valid Java identifier 2 assert map2.id == 1 3 //we can quote the key if needed 4 assert map2."peter's birthday" == now 5 //we can also use subscription notation map[key] 6 assert map2["peter's birthday"] == now 7 //and the standard get method 8 assert map2.get('value') == 2 9 assert map.get('foo') == null 10 //default value when key not found 11 assert map.get('foo', 'No such key') == 'No such key' 12 //adds the default value in the map 13 assert map.containsKey('foo') 14 //what type is the map? 15 try { 16 assert map.class == LinkedHashMap.class 17 } 18 catch(Error e) { 19 assert map.class == null //the map is looking for the 'class ' key 20 map.getClass() == LinkedHashMap.class 21 }
  • 58. Even more maps examples 1 //put/update values 2 map.newKey = "new key's value" 3 map2['newKey'] = map.newKey 4 //use parentheses to add the value of a var in a map (and not its name) 5 def anotherKey = "address" 6 map[(anotherKey)] = "Petraki 28" 7 assert map.address == "Petraki 28" 8 //iterate with each 9 map.each { println "In each: ${it.class}" } 10 //the closure argument is a Map.Entry instance 11 map.each { println "In each again: ${it.key} = ${it.value}" } 12 //all Java Map methods are here 13 assert !map.isEmpty() 14 assert map.containsKey('id') 15 assert map.containsValue(12) 16 //use a HashMap instead of a LinkedHashMap 17 def map3 = new HashMap() 18 assert map3.getClass() == HashMap.class 19 //empty map 20 def map4 = [:] 21 assert !map4//empty map is false
  • 59. Some more maps examples 1 //find in map 2 assert ['id':12, 'foo':'No such key'] == map.findAll{ it.key. size() <= 3} 3 //group by 4 def list = [1, '2', 3, '4', '5', 6] 5 def map5 = list.groupBy { it.getClass().getSimpleName() } 6 assert ['String': ['2', '4', '5'], 'Integer': [1, 3, 6]] == map5 7 //store closures in a map 8 def actions = [ 9 login : { println "login" }, 10 logout : { println "logout" } 11 ] 12 //execute the closures 13 actions.login.call() //or 14 actions['logout'].call() //or 15 actions.logout()
  • 60. Duck typing 1 //Duck typing − a comparator 2 def cmp = [ 3 compare : { a, b −> a.size() <=> b.size() } 4 ] as Comparator 5 assert cmp instanceof Comparator 6 //a list 7 def list2 = ['a' , 'quick', 'brown', 'fox', 'jumps', 'over', 'a' , 'lazy', 'dog'] 8 assert list2.sort(cmp) == ['a', 'a', 'fox', 'dog', 'over', 'lazy ', 'quick', 'brown', 'jumps'] 9 //a runnable 10 def r = [ 11 run : { 12 def t = Thread.currentThread() 13 println "Thread ${t.getId()} starting" 14 t.sleep(1000) 15 println "Thread ${t.getId()} finished" 16 } 17 ] as Runnable 18 assert r instanceof Runnable 19 new Thread(r).start()
  • 61. Duck typing continued Another Example 1 interface Doer { 2 void doThis(); 3 void doThat(); 4 } 5 class DoerImpl implements Doer { 6 void doThis(){"Did this"} 7 void doThat(){"Did that"} 8 } 9 def doer1 = new DoerImpl() 10 assert doer1 instanceof Doer 11 def doer2 = [ 12 doThis:{"This done"}, 13 doThat:{"That done"} 14 ] as Doer 15 assert doer2 instanceof Doer
  • 62. 3. Real-life Groovy Open Public Data Hackathon Our Web App JSON and REST Groovlets
  • 63. Open Public Data Hackathon Held between 15 - 30 April 2014. Organized by the Ministry of Administration Reform and E-Governance (ydmed.gr), in association with: 1. aspete.gr 2. hua.gr 3. ellak.gr Requirement: deliver an app that utilizes open public data (from data.gov.gr or elsewhere).
  • 64. We won the 2nd prize! And Groovy helped us do it! We shall discuss: 1. How to build a RESTful API with Groovy and Restlet. 2. How to build dynamic web pages with Groovlets.
  • 65. Our Web App A prototype of a cloud service for Accessing/retrieving data Searching/querying data Visualizing/embedding data through a powerful RESTful API.
  • 67. Technologies used Backend Java 7.x Apache Tomcat 7.0.x Groovy 2.2.x Restlet 2.2.0 Apache POI 3.10 Elastic Search 1.1.1 Frontend Bootstrap 3 jQuery 1.10 D3.js
  • 68. The data model We have Kept thins as simple as possible. Data source groups: Sets of Data sources: Tabular data in excel files arranged in columns and rows. After all, it is a prototype!
  • 69. The web.xml Two servlets 1 <servlet> 2 <servlet−name>RestletServlet</servlet−name> 3 <servlet−class>org.restlet.ext.servlet.ServerServlet</servlet− class> 4 <init−param> 5 <param−name>org.restlet.application</param−name> 6 <param−value>com.niovity.opd.restlet.App</param−value> 7 </init−param> 8 </servlet> 9 <servlet−mapping> 10 <servlet−name>RestletServlet</servlet−name> 11 <url−pattern>/api/v0/*</url−pattern> 12 </servlet−mapping> 13 <servlet> 14 <servlet−name>groovy</servlet−name> 15 <servlet−class>groovy.servlet.GroovyServlet</servlet−class> 16 </servlet> 17 <servlet−mapping> 18 <servlet−name>groovy</servlet−name> 19 <url−pattern>*.groovy</url−pattern> 20 </servlet−mapping>
  • 70. The web.xml continued And a listener 1 <listener> 2 <listener−class>com.niovity.opd.Listener</listener−class> 3 </listener> 1 package com.niovity.opd 2 class Listener implements ServletContextListener { 3 @Override 4 void contextInitialized(ServletContextEvent e) { 5 try { 6 //Initialize log4j & elastic 7 ... 8 //Initialize the config 9 String basePath = ctx.getRealPath("/data") 10 Config.instance.init(basePath) 11 } catch(Exception e) { 12 System.err.println("Fatal error: ${e.getMessage()}") 13 e.printStackTrace(System.err) 14 throw new ServletException(e.getMessage(), e) 15 } 16 } 17 }
  • 71. Groovy @Singleton Annotation Config 1 package com.niovity.opd 2 @Singleton class Config { 3 String basePath 4 Map<String, DataSourceGroup> sourceGroups = [:] 5 void init(String basePath) throws Exception { 6 this.basePath = basePath 7 def groups = [:] 8 DataSourceGroup nte = new DataSourceGroup( 9 id: "nte", 10 title:"...", ... 11 ) 12 nte.addDataSource(new DataSource(title: "...",...)) 13 groups.nte = nte 14 ... 15 sourceGroups = Collections.unmodifiableMap(groups) 16 } 17 }
  • 72. The Restlet App The REST router 1 package com.niovity.opd.restlet 2 import org.restlet.Application 3 import org.restlet.Restlet 4 import org.restlet.routing.Router 5 class App extends Application { 6 @Override 7 synchronized Restlet createInboundRoot() { 8 Router router = new Router(getContext()) 9 router.attach "/groups", SourceGroups 10 router.attach "/{grp}/{src}", Source 11 router.attach "/search", Search 12 return router 13 } 14 }
  • 73. An example of a Restlet GET the source groups 1 package com.niovity.opd.restlet 2 import ... 3 class SourceGroups extends ServerResource{ 4 @Override 5 protected Representation get() throws ResourceException { 6 def groups = Config.instance.sourceGroups 7 def result = [:] 8 result.total = groups.size() 9 result.groups = [] 10 groups.each { 11 def group = [id : it.key, title : it.value.title, ...] 12 group.sources = [] 13 it.value.dataSources().eachWithIndex { source, index −> 14 def src = [id:"/${it.key}/$index",...] 15 group.sources.push(src) 16 } 17 result.groups.push(group) 18 } 19 return new JsonRespresentation(result) 20 } 21 }
  • 74. JSON JsonRepresentation 1 package com.niovity.opd.restlet 2 import groovy.json.JsonBuilder 3 import org.restlet.data.MediaType 4 import org.restlet.representation.WriterRepresentation 5 class JsonRespresentation extends WriterRepresentation { 6 private Map result 7 JsonRespresentation(Map result) { 8 super(MediaType.APPLICATION_JSON) 9 this.result = result ?: [:] 10 } 11 @Override 12 void write(Writer writer) throws IOException { 13 new JsonBuilder(result).writeTo(writer) 14 } 15 }
  • 75. Groovlets Groovy scripts on the server side Compiled on the fly No boilerplate With some handy implicit variables provided by default request,response : Http servler request and response params : request parameters context, application : the ServletContext object session : the HttpSession object out : the writer of the response sout : the output stream of the response html: a groovy.xml.MarkupBuilder which writes to out
  • 76. Display a data source in HTML table source.grovy 1 String groupId = request.getParameter("grp") 2 String srcId = request.getParameter("src") 3 def group = Config.instance.sourceGroups.get(groupId) 4 def sources = group.dataSources() 5 int index = srcId as Integer 6 def source = group.dataSources().get(index) 7 println """ 8 ... 9 <table class="table table−bordered table−striped" > 10 <thead> 11 <tr> 12 <th>#</th> 13 ${source.columnNames.collect {"<th>$it</th>"}.join("")} 14 </tr> 15 </thead> 16 <tbody > 17 """
  • 77. HTML table continued source.grovy 1 source.rows.eachWithIndex {Map row, int i −> 2 println """ 3 <tr> 4 <td>${i+1}</td> 5 ${source.columnNames.collect{ "<td>${row.get(it)}</td>"}.join ("")} 6 </tr> 7 """ 8 } 9 println """ 10 </tbody> 11 </table> 12 ... 13 """
  • 79. Groovy is Java on steroids! Easy to use: Its integration with the Java platform is insanely brilliant! Expressive: Do more with less code! Effective: Focus on your app and stop wasting your time with the irrelevant! Agile: Groovy is agile and rapid prototyping is a few Groovy lines away! Leverage Java expertise. Build upon your Java skills. Powerful: The swiss army knife of the Java hacker!
  • 80. Swiss army knife, indeed Ain't this groovy or what? db.groovy 1 @GrabConfig(systemClassLoader=true) 2 @Grab(group='mysql', module='mysql−connector−java', version=' 5.1.6') 3 import groovy.sql.Sql 4 def query="select count(*) as c, date(creationDate) as d from dofields group by d order by c desc limit 10" 5 def url="jdbc:mysql://localhost:3306/test_db?characterEncoding= utf−8" 6 def (u,p)=["test","test"] 7 try { 8 def sql = Sql.newInstance(url,u,p,"com.mysql.jdbc.Driver") 9 sql.eachRow(query) { println("${it.c}:${it.d}") } 10 } 11 catch(e) { e.printStackTrace() }
  • 81. Output Run it groovy db Output 1 9427:2004−08−20 2 6615:2004−10−29 3 5498:2004−10−08 4 5103:2004−08−31 5 4864:2004−10−14 6 4675:2004−10−31 7 4583:2004−10−05 8 4570:2004−08−21 9 4339:2004−09−30 10 4235:2004−10−30
  • 83. We 've only scratched the surface Groovy topics not covered Metaprogramming Grape Builders Working with XML Working with SQL Testing And much, much more... Perhaps in a 2nd part?
  • 84. What about performance? Programmers have spent far too much time worrying about efficiency in the wrong places at the wrong times; premature optimization is the root of all evil. Donald E. Knuth ACM Turing Award, 1974
  • 85. Put in other terms The reason to use Groovy should be because it improves your performance not the computer's. matthew@stackoverflow
  • 86. About Groovy Performance Sorry, it hasn't bothered me yet. Groovy 2.x introduced the @CompileStatic annotation. Most of Groovy method calls are compiled into direct JVM bytecode method calls. People report that Groovy reaches to almost identical performance with Java. Start with Groovy and (re)write your performance-critical classes in Java as you grow. You can find various benchmarks and performance comparisons on the web. Any volunteers for benchmarking, should we do a 2nd part?
  • 87. Resources 1. Programming Groovy 2, V. Subramaniam, The Pragmatic Bookshelf, 978-1-937785-30-7, 2013 2. Groovy in Action, D. Koenig, A. Glover, P. King, G. Laforge and J. Skeet, Manning Publications, 1-932394-84-2, 2007 3. Groovy Web Site http://groovy.codehaus.org 4. Groovy language documentation beta http://beta.groovy-lang.org/docs/ groovy-2.3.0/html/documentation/
  • 88. Thank you Questions? Proudly powered by: LATEX Using the Beamer class & the Wronki theme (slightly modified).