Java plus Groovy
Présentation du 15/07/09, lors du Riviera JUG. Bertrand Goetzmann, odelia technologies.
»
Java plus Groovy
Bertrand Goetzmann
Architecte, LaSer-Symag
bertrand.goetzmann@lasersymag.com
Mais aussi...
odelia technologies
http://www.odelia-technologies.com
bgoetzmann@odelia-technologies.com
Vous avez dit Groovy ?
3.times { println 'Salut !' }
"notepad".execute()
Thread.start { sleep 500; print "Salut" }
Thread.start { sleep 1000; println " tout le monde !" }
"http://www.odelia-technologies.com".toURL().text
new File("test.txt").write "Hello World!"
Groovy
A propos de Groovy
Groovy est un langage dynamique pour la machine virtuelle Java (JVM)
Conduit par Guillaume Laforge, Groovy est un projet open source sous licence Apache hébergé chez Codehaus : http://groovy.codehaus.org/
Bâti au-dessus de Java, Groovy comprend de nouvelles fonctionnalités puissantes inspirées de plusieurs autres langages dynamiques
Une notoriété et une librairie grandissante
Installation
Télécharger l’archive de Groovy depuis http://groovy.codehaus.org/Download et l'extraire dans un répertoire local (il existe aussi un exécutable d’installation pour Windows)
Il suffit de positionner une variable d’environnement GROOVY_HOME vers le répertoire d’installation, et d’ajouter %GROOVY_HOME%\bin (ou $GROOVY_HOME/bin) au PATH du système
Java
Groovy
Intégration Java-Groovy
Facile à apprendre parce que la syntaxe de Groovy est basée sur celle de Java
Groovy peut être interprété ou bien compilé en bytecode Java (.class)
On peut appeler du code Java depuis Groovy et inversement ; pour appeler du code Groovy depuis Java, il faut avoir la librairie groovy-all-*.jar dans le classpath
Plusieurs commandes disponibles : groovy, groovyc, groovysh, groovyConsole
Intégration avec Ant : utiliser la tâche Ant <groovyc/>
Avec Maven, vous pouvez utiliser le projet GMaven (http://groovy.codehaus.org/GMaven)
Groovy dans les nuages ! Groovy web console http://groovyconsole.appspot.com/ (sur Google App Engine)
Dans les IDE IntelliJ IDEA, Eclipse, NetBeans ; pour démarrer un projet Java/Groovy dans NetBeans : menu « Fichier | Nouveau projet… », puis sélectionner le projet « Groovy-Java Demo » dans la catégorie « Exemples/Groovy »
Démo avec GroovyConsole
Grails
Griffon
Gracelets
A propos de Grails
Grails (http://grails.org/) est un framework d'application web open source agile ; basé sur le langage dynamique Groovy, Grails rend le développement d'applications web simple et rapide en appliquant des principes tels que « Convention over Configuration » et « Don’t Repeat Yourself ».
Grails s'appuie sur de nombreux outils ou framework Java reconnus tels que Spring (conteneur IoC, http://www.springsource.org/), Hibernate (outil de mapping objet/relationnel, https://www.hibernate.org/), en masquant leur complexité.
Installer Grails
Télécharger l’archive de Grails depuis http://www.grails.org/Download et l’extraire dans un répertoire local
Il suffit de positionner une variable d’environnement GRAILS_HOME vers le répertoire d’installation, et d’ajouter %GRAILS_HOME%\bin (ou $GRAILS_HOME/bin) au PATH du système
Eléments du langage
Classes et scripts
Sera considéré comme du script un code source Groovy qui n’est pas inclus dans une classe.
La version script de « Hello World ! » : println "Hello World !"
Parenthèses et point-virgule optionnels
Typage optionnel
Dans le cas du typage dynamique, on utilise de mot-clé def
Propriétés Groovy
Dans une classe Groovy vous pouvez utiliser des propriétés (au sens JavaBean), les méthodes accesseurs étant générées pour vous :
Cela fonctionne aussi sur les objets Java ; exemple :
class MaClasse {
String stringProp
}
def obj = new MaClasse()
obj.stringProp = 'Salut !' // appel à setStringProp('Salut !')
assert obj.stringProp == 'Salut !' // appel à getStringProp()
String s = 'Salut !'
// appel à s.getBytes() :
assert s.bytes == [83, 97, 108, 117, 116, 32, 33]
GDK
Groovy étend la JDK avec une extension appelée le GDK ou le Groovy JDK (http://groovy.codehaus.org/groovy-jdk/).
Quelques exemples sur la classe Object :
println obj.dump()
println obj.properties
println obj.class.methods.name
Invoquer une méthode de manière dynamique :
obj.invokeMethod(name, params)
obj."$name"(params)
obj.with { prop1 = 1 ; prop2 = 'Salut !' }
Chaînes de caractères
Guillemets simples pour les chaînes de caractères simples : def langage = 'Groovy'
Guillements doubles pour les chaînes de caractères GString qui supportent l’expansion de variables : def nomComplet = "$prenom $nom"
Versions multi-lignes (' ou ") :
def adresse = """
$nom ${prenom}
39, avenue de Nice
06600 Antibes
"""
Quelques exemples
Avec indexation (range Groovy) :
def nomComplet = "Bertrand Goetzmann"
def prenom = nomComplet[0..7]
def fichier = "rapport.pdf"
def extension = fichier[-3..-1]
def nom = 'odelia technologies'
assert nom - 'odelia ' == 'technologies'
def str = "Yoda dit : t'aider je le puis !"
assert str.split(' ').reverse().join(' ') == "! puis le je t'aider : dit Yoda"
Lists
Maps
Ranges
Les listes ressemblent à des tableaux mais sont de type java.util.List avec de nouvelles méthodes
assert [1,2,3,4] == (1..4)
assert [1,2,3] + [1] == [1,2,3,1]
assert [1,2,3] << 1 == [1,2,3,1]
assert [1,2,3,1] - [1] == [2,3]
assert [1,2,3] * 2 == [1,2,3,1,2,3]
assert [1,2,3,1].unique().size() == 3
assert [1,2,3,1].count(1) == 2
assert [1,2,3,4].min() == 1
Les maps sont semblables aux listes mais en ayant un type arbitraire comme clé au lieu d’un entier ; la syntaxe en est très proche :
def map = [a:0, b:1]
assert map['a'] == 0
map.c = 2
Avec la closure each :
map.each { entry -> println "$entry.key - $entry.value" }
Ce sont des intervalles qui des ont des limites gauche et droite
(1..3).each { print "$it "; sleep 1000 } // ou for (it in 1..<4) {…}
println "Soleil !"
assert (2..<5).contains(3)
assert !(2..<5).contains(5)
assert ('z'..'x').toList() == ['z', 'y', 'x']
Les objets Date peuvent être utilisés dans les ranges :
def aujourdhui = new Date()
def hier = aujourdhui-1
(aujourdhui..hier).each { println it }
GPath
Appeler une propriété sur une liste, renvoie une liste de la propriété pour chaque élément de la liste.
class Personne {
String nom
int age
}
class Ressource {
String nom
int valeur
}
def res = new Ressource(nom: 'Imprimante', valeur: 1000)
def liste = [new Personne(nom: 'odelia', age: 20), res]
assert liste.nom == ['odelia', 'Imprimante']
liste << new Personne(nom: 'Nathanaël', age: 11)
liste -= res
assert liste.age.findAll { it > 18 } == [20]
Une closure Groovy est bout de code anonyme pouvant prendre des arguments, renvoyer une valeur et utiliser des variables ou des méthodes déclarées dans la portée qui l'englobe.
Syntaxe : { [arguments->] instructions }
Une closure correspond à un type dérivé de du type Groovy Closure. Elle peut être passé comme argument de méthode, affectée à un attribut de classe ou une variable locale etc.
Closures
def carre = { num -> num * num }
assert carre(3) == 9
def traitement(num, Closure operation)
assert traitement(5, carre) == 25
Si une closure est le dernier argument d’une méthode, on peut écrire :
assert traitement(3) { it*it*it } == 27
Les closures sont utilisées partout (itérateurs, callbacks, threads, définition de méthode dynamique, etc.) !
[1,2,3].each { println it*2 }
assert [1,2,3,4,5].findAll { it > 3 } == [4,5]
new File('fichier.txt').eachLine { println it }
exemples
XML
Lire
Ecrire
Lire un document XML avec la classe XmlSlurper
Lire les dix premières entrées du fil d’actualité du site
groovy.blogs() (http://www.groovyblogs.org/) :
def url= 'http://www.groovyblogs.org/feed/rss'
def rss = new XmlSlurper().parse(url)
rss.channel.item.title[0..9]*.text()
Ecrire un document XML avec la classe MarkupBuilder
La classe MarkupBuilder permet de produire un document XML en utilisant des structures de contrôle, ainsi qu’une syntaxe déclarative.
def builder = new groovy.xml.MarkupBuilder()
builder.html {
head(title: 'odelia technologies')
body {
10.times {
p('Bienvenue au Riviera JUG')
}
}
}
Scriptom
Démonstration avec MS SAPI et Word
Scriptom (http://groovy.codehaus.org/COM+Scripting) est un module Groovy encapsulant la librairie JACOB (Java COM Bridge, http://sourceforge.net/projects/jacob-project/) pour manipuler des objets COM automation, avec une syntaxe plus directe.
Grape
Grape et la transformation Grab
Grape (Groovy Adaptable / Advanced Packaging Engine) est un module intégré à Groovy pour la gestion des dépendances dans les scripts Groovy.
L’intérêt est de pouvoir distribuer ses scripts Groovy sans les dépendances requises : celles-ci seront téléchargées, puis mises en cache si nécessaire, lors de l’exécution du script.
Il suffit d’indiquer les dépendances explicitement dans le script avec la transformation @Grab ou bien un appel à la méthode Grape.grab().
Grape recherche les librairies dépendantes dans des « repositories » Ivy et Maven.
Démonstration avec Jetty
Builders
Le langage Groovy comporte la notion de builder ; comme dans l’exemple de la classe MarkupBuilder, les builders permettent de définir des structures d’objets ou de données hiérarchiques que l’on peut facilement comprendre par simple lecture du code.
C’est comme si vous utilisiez un nouveau langage grâce à l’utilisation des closures, du Meta-Object Protocol (MOP), et des déclarations de Map.
AntBuilder
MarkupBuilder
La classe groovy.util.AntBuilder permet d’exécuter des tâches Ant de manière Groovy.
ant.echo 'Salut !'
ant.delete {
fileset(dir: "$easyb/rptdesigns", includes: '*.rptdesign')
}
Basé sur ce builder, le projet Gant (http://gant.codehaus.org/) est un outil de « build », pendant Groovy de Ant.
GraphicsBuilder
GraphicsBuilder (http://groovy.codehaus.org/GraphicsBuilder) est un builder Groovy développé par Andres Almiray qui vise à faciliter la création de graphiques basés sur Java 2D.
Extrait de la documentation de GraphicsBuilder :
// turn on antialias
antialias( 'on' )
// create the Groovy star
star( ir: 40, or: 100, cx: 160, cy: 120, borderWidth: 4,
fill: [118,167,183] as Color ){
transformations{
scale( y: 0.6 )
}
}
SwingBuilder
Démonstration avec NetBeans
Autres builders
ObjectGraphBuilder (http://groovy.codehaus.org/ObjectGraphBuilder), pour la création de graphes d’objet
HTTPBuilder (http://groovy.codehaus.org/modules/http-builder/doc/index.html) pour les requêtes HTTP
JmxBuilder (http://code.google.com/p/groovy-jmx-builder/) permet l’exposition de POJO et de POGO sur Java Magement Extension
MetaBuilder (http://docs.codehaus.org/display/GROOVY/MetaBuilder) est un builder de builders !
DSL
De la prose M. Jourdain ?
T
Avec un DSL on va pouvoir * :
utiliser un langage plus expressif
éviter de surcharger du code métier avec du code purement technique
partager un langage commun entre les développeurs et les experts métiers, si bien que ceux-ci :
pourront apporter leur connaissance dans la logique métier d’une application
séparer de manière plus claire la logique métier du code de l’application
* tiré de « Practical Groovy Domain-Specific Languages » par Guillaume Laforge,
http://www.slideshare.net/glaforge/practical-groovy-domainspecific-languages-guillaume-laforge-usi-2009
DSL de manipulations d'unités
Implémentation de référence de la JSR 275: Units Specification, la librairie JScience (http://www.jscience.org/) permet de manipuler en particulier des unités de mesure.
Exemple en Java montrant l’addition de deux masses exprimées en Kg, avec la librairie JScience :
import static javax.measure.unit.SI.*;
import javax.measure.*
import org.jscience.physics.amount.*;
Amount m3 = Amount.valueOf(3, KILO(GRAM));
Amount m2 = Amount.valueOf("2 kg");
Amount sum = m3.plus(m2);
Tiré de l’article « A Domain-Specific Language for unit manipulations », de Guillaume Laforge, http://groovy.dzone.com/news/domain-specific-language-unit-
Ajout d'unité aux nombres
Groovy permettant d’ajouter des propriétés aux nombres, l’implémentation du DSL autorise cette écriture :
println 2.kg
Ici on accède à la propriété kg de 2, et cette propriété est de type Amount :
assert 2.kg.class.name == 'org.jscience.physics.amount.Amount'
Surcharge d'opérateur
Groovy autorisant la surcharge des opérateurs, l’implémentation du DSL a redéfinie les opérateurs arithmétiques.
Par exemple :
assert 3.cm * 2 + 12.m == 1206.cm
L’article va plus loin et explique comment arriver à exprimer des unités composées comme km/h ou m/s, et à opérer des conversions d’une unité vers une autre.
BDD avec easyb
easyb (http://easyb.org/) est un framework BDD (Behavior Driven Development) pour la plate-forme Java ;
un tel framework permet d’exprimer en langage naturel le comportement et l’objectif du code à développer, tout en permettant son test et sa documentation !
Avec easyb, les « comportements » sont décrits dans des fichiers Groovy, utilisant un DSL défini par le framework ; leur « exécution » peut être déclenchée via une classe d’easyb en ligne de commande, par Ant, ou encore Maven 2.
Exemple de scénario
scenario "Salutation", {
given "une salutation", {
salut = 'Salut'
}
and "le monde entier", {
suite = 'tout le monde !'
}
when "le message complet est formé", {
message = "$salut $suite"
}
then "la taille du message est correcte", {
message.size().shouldBeEqualTo 21
}
and
then "le message est une salutation au monde entier", {
message.shouldBeEqualTo 'Salut tout le monde !'
}
}
Plus de description
Scénario "todo"
A placer en début de scénario :
description "Cette description n'est pas obligatoire"
narrative "description supplémentaire non obligatoire", {
as_a "respsonsable produit"
i_want "un code sans bogue"
so_that "les clients seront satisfaits"
}
scenario "voici un scénario en cours", {
given "une nouvelle forme de salutation"
when "le message de salutation est créé"
then "le message est bien transmis"
}
Exemple de documentation générée par easyb : file:///D:/easyb/reports/html/report.html
Démonstration
odelia technologies
http://www.odelia-technologies.com
http://www.grailsworks.com
GrailsWorks
Riviera JUG, le 15 juillet 2009More presentations by Bertrand Goetzmann
GroovyHTML5
Bertrand Goetzmann on
GroovyHTML5 consiste en un DSL (Domains-Specific Language) Groovy, un fichier modèle HTML5, et en un script Groovy, pour générer une page web capable d'exécuter une ...
Popular presentations
Ideas for Prezi (PreziHelp.com)
PreziHelp.com :) on
Here are a few suggestions I have for Prezi.com, along with some popular user suggestions. I illustrated these ideas with examples of what these features ...
More popular prezis in Explore>