Groovy
André Faria Gomes
O que é Groovy
Groovy é uma linguagem ágil dinâmica
para a plataforma Java com muitas
funcionalidades inspiradas de
linguagens como Python, Ruby e
Smalltalk, disponibilizando tais
funcionalidades para os
desenvolvedores Java em uma sintaxe
muito semelhante a Java.
Mapa do Groovy
Comparado
Groovy
new File('.').eachFileRecurse { println it }



Java

import java.io.File;

public class ListFiles {

	   public static void main(final String... args) {
	   	   printFiles(new File("."));
	   }

	   private static void printFiles(final File file) {
	   	   System.out.println(file);
	   	   final File[] files = file.listFiles();
	   	   for (final File f : files) {
	   	   	    if (f.isDirectory()) {
	   	   	    	   printFiles(f);
	   	   	    } else {
	   	   	    	   System.out.println(f);
	   	   	    }
	   	   }
	   }
}
Fibonnacci
  atual = 1
proximo = 1

10.times {
	 print atual + ' '
	 novo = proximo
	 proximo = atual + proximo
	 atual = novo
}
Importação Automática


Groovy importar automaticamente os
pacotes groovy.lang.*, groovy.util.*,
java.lang.*, java.util.*, java.net.*, and
java.io.*
Executando

•   groovysh: Inicia o command-line shell, que é utilizado para
    executar código Groovy interativamente. O código é
    executado em tempo real, comando-a-comando."

•   groovyConsole: Inicia a interface gráfica que também é
    usada para executar código groovy interativamente; além
    disso, o groovyConsole é carregado e executa os scripts
    Groovy.

•   groovy: Inicia o interpretador que executa scripts Groovy.
O compilador groovyc
groovyc –d classes Fibonacci.groovy


Fibonacci.class
Fibonacci$_run_closure1.class


java -cp $GROOVY_HOME/embeddable/groovy-all-1.0.jar:classes Fibonacci
Groovy e Java
Eclipse Plugin
Breve!

Java
java.net.URLEncoder.encode("a b");




Groovy
URLEncoder.encode 'a b'
Groovy Beans


• Métodos públicos por padrão
• Métodos de acesso por padrão
• Acesso simplificado a atributos de Beans
Groovy Beans
class Car {

    String name

}

def car = new Car();

car.setName(‘Civic’);

car.getNome(); //Civic
Outer Field Access
class Bean {

    public Integer value

    def getValue() {

        value + 1

    }

}

def bean = new Bean();

bean.getValue(); //Inner Field Access

car.@value; //Outer Field Access
GStrings

def nick = 'Gina'

def book = 'Groovy in Action'

assert "$nick is $book" == 'Gina is Groovy in Action'
Regular Expressions
Tudo é Objeto
Números

def x = 1

def y = 2

assert x + y == 3

assert x.plus(y) == 3

assert x instanceof Integer
Listas

def nomes = [‘André’,‘Faria’]

assert nomes[1] == ‘Faria’

nomes[2] = ‘Gomes’
Mapas
def http = [

   100 : 'CONTINUE',

   200 : 'OK',

   400 : 'BAD REQUEST'     ]



assert http[200] == 'OK'
Intervalos (Ranges)
def x   = 1..10

assert x.contains(5)

assert x.contains(15) == false

assert x.size()    == 10

assert x.from      == 1

assert x.to        == 10

assert x.reverse() == 10..1
Closures
Null é False

if (null) {

    assert false;

} else {

    assert true;

}
For in

for (index in 1..10) {


}
For in

def list = [0,1,2,3,4,5]
for (item in list) {


}
Each

def list = [0,1,2,3,4,5]
list.each() { item ->


}
Size

Com Groovy sempre que é preciso saber
 o tamanho de um objeto utiliza-se o
           método size().

   O Java varia entre length, size(),
    getLength(), e groupCount().
Operadores
x+y    Plus   x.plus(y) Number, String, Collection


x-y   Minus x.minus(y) Number, String, Collection


                            Number, String,
x++   Next    x.next(y)
                               Range
Sobrecarga de
                 Operadores
class Dinheiro {
	
	 def valor
	
	 Dinheiro (valor) { this.valor = valor }
	
	 Dinheiro plus (Dinheiro other) {
	 	 new Dinheiro(this.valor + other.valor)
	 }
	
}

Dinheiro a = new Dinheiro(1)
Dinheiro b = new Dinheiro(10)
Dinheiro c = a + b
GStrings
me     = 'Tarzan'

you    = 'Jane'

line   = "me $me - you $you"

assert line == 'me Tarzan - you Jane'

assert line instanceof GString

assert line.strings[0] == 'me '

assert line.strings[1] == ' - you '

assert line.values[0]   == 'Tarzan'

assert line.values[1]   == 'Jane'
Regex
def pattern = ~/foo/
assert pattern instanceof Pattern
assert pattern.matcher("foo").matches()
assert pattern.matcher("foobar").matches() == false

def cheese = ("cheesecheese" =~ /cheese/).replaceFirst("nice")
assert cheese == "nicecheese"
assert "color" == "colour".replaceFirst(/ou/, "o")
Numbers
10.times { /* code */ }

1.upto(5) { number -> /* code */ }

2.downto(-2) { number -> /* code */ }

valor = ''
0.step(0.5, 0.1) { number ->
	 valor += number + ' '
}
assert valor == '0 0.1 0.2 0.3 0.4 '
Ranges
range = 5..8
assert range.size() == 4
assert range.get(2) == 7
assert range[2] == 7
assert range instanceof java.util.List
assert range.contains(5)
assert range.contains(8)

range = 5..<8
assert range.size() == 3
assert range.get(2) == 7
assert range[2] == 7
assert range instanceof java.util.List
assert range.contains(5)
assert ! range.contains(8)

range = 1..10
assert range.from == 1
assert range.to == 10
Ordenação

def listOfCustumers = // ...

listOfCustumers.sort { custumer ->

     custumer.dateOfTheFirstPurchase

 }
Querying
Mapas
def myMap = [a:1, b:2, c:3]

assert myMap instanceof HashMap
assert myMap.size() == 3
assert myMap['a']   == 1

def emptyMap = [:]
assert emptyMap.size() == 0

def explicitMap = new TreeMap()
explicitMap.putAll(myMap)
assert explicitMap['a'] == 1
Any e Every do GDK


def map = [a:1,b:2,c:3]

assert map.every { entry -> entry.value < 10 }

assert map.any { entry -> entry.value < 2 }
FindAll


def map = [a:1,b:2,c:3]

def map2 = map.findAll { entry -> entry.value < 3}

assert map2.size() == 2
Find



def map = [a:1,b:2,c:3]

def x = map.find { entry -> entry.value == 2}
Closures

Closure envelope = { person ->

    new Letter(person).send()

}

addressBook.each (envelope)



addressBook.each { new Letter(it).send() }
Closures it



new File('myfile.txt').eachLine { println it }
Import as

import thirdparty.MathLib as TwiceHalfMathLib

import thirdparty2.MathLib as IncMathLib



def math1 = new TwiceHalfMathLib()

def math2 = new IncMathLib()



assert 3 == math1.half(math2.increment(5))
Meta Programming
GroovyObject
public interface GroovyObject {

    public Object    invokeMethod(String name, Object args);

    public Object    getProperty(String property);

    public void      setProperty(String property, Object newValue);

    public MetaClass getMetaClass();

    public void      setMetaClass(MetaClass metaClass);

}


Also Interception and Proxies
Builders
XML Builder
def builder = new groovy.xml.MarkupBuilder();
builder.numeros {
	 descricao 'Numeros pares'
	 for (i in 1..10) {
	 	 if (i % 2 == 0) {
	 	 	 numero (valor: i, dobro: i*2 )
	 	 }
	 }
}

<numeros>
  <descricao>Numeros pares</descricao>
  <numero valor='2' dobro='4' />
  <numero valor='4' dobro='8' />
  <numero valor='6' dobro='12' />
  <numero valor='8' dobro='16' />
  <numero valor='10' dobro='20' />
</numeros>
Node Builder
def builder = new NodeBuilder();

def   funcionarios = builder.funcionarios {
	
	     funcionario(nome:'André Faria') {
	     	   carro(marca:'Toyota', modelo:'Corolla')
	     }
	
	     funcionario(nome:'Bruno Lui') {
	     	   carro(marca:'Fiat', modelo:'Palio')
	     }
	
}

def donoDoPalio = funcionarios.grep {
	   it.carro.any { it.'@modelo' == 'Palio' }
}.'@nome'

print donoDoPalio //Bruno Lui
Ant Builder

TARGET_DIR   = 'documentos'
FOTOS_DIR = 'fotos'
ant          = new AntBuilder()

ant.delete(dir:TARGET_DIR)
ant.copy(todir:TARGET_DIR){
    fileset(dir:FOTOS_DIR, includes:'*.doc', excludes:'~*')
}
Swing Builder
import groovy.swing.SwingBuilder

data   = [
	      	   [nick:'MrG',         full:'Guillaume Laforge'   ],
	      	   [nick:'jez',         full:'Jeremy Rayner'       ],
	      	   [nick:'fraz',        full:'Franck Rasolo'       ],
	      	   [nick:'sormuras',    full:'Christian Stein'     ],
	      	   [nick:'blackdrag',   full:'Jochen Theodorou'    ],
	      	   [nick:'Mittie',      full:'Dierk Koenig'        ]
	      	   ]

swing = new SwingBuilder()
frame = swing.frame(title:'Table Demo') {
	    scrollPane {
	    	    table() {
	    	    	    tableModel(list:data) {
	    	    	    	    propertyColumn(header:'Nickname', propertyName:'nick')
	    	    	    	    propertyColumn(header:'Full Name',propertyName:'full')
	    	    	    }
	    	    }
	    }
}
frame.pack()
frame.show()
Templates
Template
def mensagem = '''
	   Querido amigo ${destinatario}

	     Gostaria de pedir que me ajudasse a realizar essas ${tarefas.size} tarefas:

	   <% tarefas.each() {	%> - ${it}	
	   <% } %>	
'''

def   engine = new groovy.text.SimpleTemplateEngine();
def   template = engine.createTemplate(mensagem);
def   parametros = [
	     	   destinatario: 'Zé das Couves',
	     	   tarefas: ['comprar um ovo de páscoa', 'regar as plantas']
	     	   ]

print template.make(parametros).toString()

	     Querido amigo Zé das Couves

	     Gostaria de pedir que me ajudasse a realizar essas 2 tarefas:

	      - comprar um ovo de páscoa
	      - regar as plantas
Groovylets
Groovylets
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
    "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd" >

<web-app>
    <display-name>Groovlet Demonstrator</display-name>
    <description>
        Showing the use of Groovlets for Groovy in Action
    </description>

   <servlet>
       <servlet-name>Groovy</servlet-name>
       <servlet-class>groovy.servlet.GroovyServlet</servlet-class>
   </servlet>

   <servlet-mapping>
       <servlet-name>Groovy</servlet-name>
       <url-pattern>*</url-pattern>
   </servlet-mapping>

</web-app>
Groovylets
html.html{
	 head { title 'Groovlet Demonstrator' }
	 body {
	 	 h1 'Variables in the Binding:'
	 	 table(summary:'binding') {
	 	 	 tbody {
	 	 	 	 binding.variables.each { key, value ->
	 	 	 	 	 tr {
	 	 	 	 	 	 td key.toString()
	 	 	 	 	 	 td(value ? value.toString() : 'null')
	 	 	 	 	 }
	 	 	 	 }
	 	 	 }
	 	 }
	 }
}
Groovylets + Templates
<html>
  <head>
    <title>Think of a Number</title>
  </head>
  <body>
    <h1>Think of a Number</h1>
    Your guess $guess is <%
         switch (guess) {
             case goal        : out << 'correct!'; break
             case {it < goal} : out << 'too low' ; break
             case {it > goal} : out << 'too high'; break
        }
    %>
    <p>What&quot;s your guess (0..100)?</p>
     <form action='Templater.groovy'>
       <input type='text' name='guess'>
       <button type='submit'>Guess</button>
       <button type='submit' name='restart' value='true'>New Game
       </button>
     </form>
   </body>
 </html>

def   engine   = new groovy.text.SimpleTemplateEngine()
def   source   = getClass().classLoader.getResource('/Number.template.html')
def   template = engine.createTemplate(source)
out   << template.make(goal:50, guess:49)
Groovy Shell


final GroovyShell groovyShell = new GroovyShell();

final String result = (String) groovyShell.evaluate(" new File('.').eachFile { println it }   ");

System.out.println(result);
Integração com Spring
Grails
Referência

Introduction to Groovy

  • 1.
  • 2.
    O que éGroovy Groovy é uma linguagem ágil dinâmica para a plataforma Java com muitas funcionalidades inspiradas de linguagens como Python, Ruby e Smalltalk, disponibilizando tais funcionalidades para os desenvolvedores Java em uma sintaxe muito semelhante a Java.
  • 3.
  • 4.
    Comparado Groovy new File('.').eachFileRecurse {println it } Java import java.io.File; public class ListFiles { public static void main(final String... args) { printFiles(new File(".")); } private static void printFiles(final File file) { System.out.println(file); final File[] files = file.listFiles(); for (final File f : files) { if (f.isDirectory()) { printFiles(f); } else { System.out.println(f); } } } }
  • 5.
    Fibonnacci atual= 1 proximo = 1 10.times { print atual + ' ' novo = proximo proximo = atual + proximo atual = novo }
  • 6.
    Importação Automática Groovy importarautomaticamente os pacotes groovy.lang.*, groovy.util.*, java.lang.*, java.util.*, java.net.*, and java.io.*
  • 7.
    Executando • groovysh: Inicia o command-line shell, que é utilizado para executar código Groovy interativamente. O código é executado em tempo real, comando-a-comando." • groovyConsole: Inicia a interface gráfica que também é usada para executar código groovy interativamente; além disso, o groovyConsole é carregado e executa os scripts Groovy. • groovy: Inicia o interpretador que executa scripts Groovy.
  • 8.
    O compilador groovyc groovyc–d classes Fibonacci.groovy Fibonacci.class Fibonacci$_run_closure1.class java -cp $GROOVY_HOME/embeddable/groovy-all-1.0.jar:classes Fibonacci
  • 9.
  • 10.
  • 11.
  • 12.
    Groovy Beans • Métodospúblicos por padrão • Métodos de acesso por padrão • Acesso simplificado a atributos de Beans
  • 13.
    Groovy Beans class Car{ String name } def car = new Car(); car.setName(‘Civic’); car.getNome(); //Civic
  • 14.
    Outer Field Access classBean { public Integer value def getValue() { value + 1 } } def bean = new Bean(); bean.getValue(); //Inner Field Access car.@value; //Outer Field Access
  • 15.
    GStrings def nick ='Gina' def book = 'Groovy in Action' assert "$nick is $book" == 'Gina is Groovy in Action'
  • 16.
  • 17.
  • 18.
    Números def x =1 def y = 2 assert x + y == 3 assert x.plus(y) == 3 assert x instanceof Integer
  • 19.
    Listas def nomes =[‘André’,‘Faria’] assert nomes[1] == ‘Faria’ nomes[2] = ‘Gomes’
  • 20.
    Mapas def http =[ 100 : 'CONTINUE', 200 : 'OK', 400 : 'BAD REQUEST' ] assert http[200] == 'OK'
  • 21.
    Intervalos (Ranges) def x = 1..10 assert x.contains(5) assert x.contains(15) == false assert x.size() == 10 assert x.from == 1 assert x.to == 10 assert x.reverse() == 10..1
  • 22.
  • 23.
    Null é False if(null) { assert false; } else { assert true; }
  • 24.
    For in for (indexin 1..10) { }
  • 25.
    For in def list= [0,1,2,3,4,5] for (item in list) { }
  • 26.
    Each def list =[0,1,2,3,4,5] list.each() { item -> }
  • 27.
    Size Com Groovy sempreque é preciso saber o tamanho de um objeto utiliza-se o método size(). O Java varia entre length, size(), getLength(), e groupCount().
  • 28.
    Operadores x+y Plus x.plus(y) Number, String, Collection x-y Minus x.minus(y) Number, String, Collection Number, String, x++ Next x.next(y) Range
  • 29.
    Sobrecarga de Operadores class Dinheiro { def valor Dinheiro (valor) { this.valor = valor } Dinheiro plus (Dinheiro other) { new Dinheiro(this.valor + other.valor) } } Dinheiro a = new Dinheiro(1) Dinheiro b = new Dinheiro(10) Dinheiro c = a + b
  • 30.
    GStrings me = 'Tarzan' you = 'Jane' line = "me $me - you $you" assert line == 'me Tarzan - you Jane' assert line instanceof GString assert line.strings[0] == 'me ' assert line.strings[1] == ' - you ' assert line.values[0] == 'Tarzan' assert line.values[1] == 'Jane'
  • 31.
    Regex def pattern =~/foo/ assert pattern instanceof Pattern assert pattern.matcher("foo").matches() assert pattern.matcher("foobar").matches() == false def cheese = ("cheesecheese" =~ /cheese/).replaceFirst("nice") assert cheese == "nicecheese" assert "color" == "colour".replaceFirst(/ou/, "o")
  • 32.
    Numbers 10.times { /*code */ } 1.upto(5) { number -> /* code */ } 2.downto(-2) { number -> /* code */ } valor = '' 0.step(0.5, 0.1) { number -> valor += number + ' ' } assert valor == '0 0.1 0.2 0.3 0.4 '
  • 33.
    Ranges range = 5..8 assertrange.size() == 4 assert range.get(2) == 7 assert range[2] == 7 assert range instanceof java.util.List assert range.contains(5) assert range.contains(8) range = 5..<8 assert range.size() == 3 assert range.get(2) == 7 assert range[2] == 7 assert range instanceof java.util.List assert range.contains(5) assert ! range.contains(8) range = 1..10 assert range.from == 1 assert range.to == 10
  • 34.
    Ordenação def listOfCustumers =// ... listOfCustumers.sort { custumer -> custumer.dateOfTheFirstPurchase }
  • 35.
  • 36.
    Mapas def myMap =[a:1, b:2, c:3] assert myMap instanceof HashMap assert myMap.size() == 3 assert myMap['a'] == 1 def emptyMap = [:] assert emptyMap.size() == 0 def explicitMap = new TreeMap() explicitMap.putAll(myMap) assert explicitMap['a'] == 1
  • 37.
    Any e Everydo GDK def map = [a:1,b:2,c:3] assert map.every { entry -> entry.value < 10 } assert map.any { entry -> entry.value < 2 }
  • 38.
    FindAll def map =[a:1,b:2,c:3] def map2 = map.findAll { entry -> entry.value < 3} assert map2.size() == 2
  • 39.
    Find def map =[a:1,b:2,c:3] def x = map.find { entry -> entry.value == 2}
  • 40.
    Closures Closure envelope ={ person -> new Letter(person).send() } addressBook.each (envelope) addressBook.each { new Letter(it).send() }
  • 41.
  • 42.
    Import as import thirdparty.MathLibas TwiceHalfMathLib import thirdparty2.MathLib as IncMathLib def math1 = new TwiceHalfMathLib() def math2 = new IncMathLib() assert 3 == math1.half(math2.increment(5))
  • 43.
  • 44.
    GroovyObject public interface GroovyObject{ public Object invokeMethod(String name, Object args); public Object getProperty(String property); public void setProperty(String property, Object newValue); public MetaClass getMetaClass(); public void setMetaClass(MetaClass metaClass); } Also Interception and Proxies
  • 45.
  • 46.
    XML Builder def builder= new groovy.xml.MarkupBuilder(); builder.numeros { descricao 'Numeros pares' for (i in 1..10) { if (i % 2 == 0) { numero (valor: i, dobro: i*2 ) } } } <numeros> <descricao>Numeros pares</descricao> <numero valor='2' dobro='4' /> <numero valor='4' dobro='8' /> <numero valor='6' dobro='12' /> <numero valor='8' dobro='16' /> <numero valor='10' dobro='20' /> </numeros>
  • 47.
    Node Builder def builder= new NodeBuilder(); def funcionarios = builder.funcionarios { funcionario(nome:'André Faria') { carro(marca:'Toyota', modelo:'Corolla') } funcionario(nome:'Bruno Lui') { carro(marca:'Fiat', modelo:'Palio') } } def donoDoPalio = funcionarios.grep { it.carro.any { it.'@modelo' == 'Palio' } }.'@nome' print donoDoPalio //Bruno Lui
  • 48.
    Ant Builder TARGET_DIR = 'documentos' FOTOS_DIR = 'fotos' ant = new AntBuilder() ant.delete(dir:TARGET_DIR) ant.copy(todir:TARGET_DIR){ fileset(dir:FOTOS_DIR, includes:'*.doc', excludes:'~*') }
  • 49.
    Swing Builder import groovy.swing.SwingBuilder data = [ [nick:'MrG', full:'Guillaume Laforge' ], [nick:'jez', full:'Jeremy Rayner' ], [nick:'fraz', full:'Franck Rasolo' ], [nick:'sormuras', full:'Christian Stein' ], [nick:'blackdrag', full:'Jochen Theodorou' ], [nick:'Mittie', full:'Dierk Koenig' ] ] swing = new SwingBuilder() frame = swing.frame(title:'Table Demo') { scrollPane { table() { tableModel(list:data) { propertyColumn(header:'Nickname', propertyName:'nick') propertyColumn(header:'Full Name',propertyName:'full') } } } } frame.pack() frame.show()
  • 50.
  • 51.
    Template def mensagem =''' Querido amigo ${destinatario} Gostaria de pedir que me ajudasse a realizar essas ${tarefas.size} tarefas: <% tarefas.each() { %> - ${it} <% } %> ''' def engine = new groovy.text.SimpleTemplateEngine(); def template = engine.createTemplate(mensagem); def parametros = [ destinatario: 'Zé das Couves', tarefas: ['comprar um ovo de páscoa', 'regar as plantas'] ] print template.make(parametros).toString() Querido amigo Zé das Couves Gostaria de pedir que me ajudasse a realizar essas 2 tarefas: - comprar um ovo de páscoa - regar as plantas
  • 52.
  • 53.
    Groovylets <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd" > <web-app> <display-name>Groovlet Demonstrator</display-name> <description> Showing the use of Groovlets for Groovy in Action </description> <servlet> <servlet-name>Groovy</servlet-name> <servlet-class>groovy.servlet.GroovyServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Groovy</servlet-name> <url-pattern>*</url-pattern> </servlet-mapping> </web-app>
  • 54.
    Groovylets html.html{ head {title 'Groovlet Demonstrator' } body { h1 'Variables in the Binding:' table(summary:'binding') { tbody { binding.variables.each { key, value -> tr { td key.toString() td(value ? value.toString() : 'null') } } } } } }
  • 55.
    Groovylets + Templates <html> <head> <title>Think of a Number</title> </head> <body> <h1>Think of a Number</h1> Your guess $guess is <% switch (guess) { case goal : out << 'correct!'; break case {it < goal} : out << 'too low' ; break case {it > goal} : out << 'too high'; break } %> <p>What&quot;s your guess (0..100)?</p> <form action='Templater.groovy'> <input type='text' name='guess'> <button type='submit'>Guess</button> <button type='submit' name='restart' value='true'>New Game </button> </form> </body> </html> def engine = new groovy.text.SimpleTemplateEngine() def source = getClass().classLoader.getResource('/Number.template.html') def template = engine.createTemplate(source) out << template.make(goal:50, guess:49)
  • 56.
    Groovy Shell final GroovyShellgroovyShell = new GroovyShell(); final String result = (String) groovyShell.evaluate(" new File('.').eachFile { println it } "); System.out.println(result);
  • 57.
  • 58.
  • 59.