Enterprise-class DSLs in Groovy & Grails

Alberto Brandolini - alberto.brandolini@avanscoperta.it – Grails-IT
Javaday Roma III Edizione – 24 gennaio 2009 1

About me
Strategic IT consultant Trainer
- Skills Matter, ...

Articoli
- Mokabyte, …

Blogger
- Ziobrando’s Lair

“animatore” di Community
- Grails-IT - DDD-IT
Alberto Brandolini - alberto.brandolini@avanscoperta.it – Grails-IT
Javaday Roma III Edizione – 24 gennaio 2009 2

A cosa serve un DSL?
Un DSL è uno strumento per la condivisione di informazioni specializzato per uno specifico contesto
- dominio del problema - ruoli coinvolti - ambito di applicazione
Mettere la foto di un addetto all’atterraggio

- Facilita la condivisione di informazioni (precise e prive di ambiguità) all’interno di un gruppo - si tratta di uno strumento per migliorare l’efficienza della comunicazione
Alberto Brandolini - alberto.brandolini@avanscoperta.it – Grails-IT
Javaday Roma III Edizione – 24 gennaio 2009 3

… un classico esempio di DSL

Alberto Brandolini - alberto.brandolini@avanscoperta.it – Grails-IT
Javaday Roma III Edizione – 24 gennaio 2009 4

it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Un Domain Specific Language nasce per coprire un’esigenza di comunicazione in un contesto5specifico indirizzando alcuni elementi della comunicazione: l’impossibilità di utilizzare determinati canali (in questo caso l’audio).alberto.Alberto Brandolini .brandolini@avanscoperta. la necessità di comunicare con maggiore rapidità e precisione. la necessità di essere sintetici .

ma ciò che può avere impatto sul nostro modo di produrre software è rappresentato dal DSL specifico del dominio applicativo. In un classico contesto di progetto sono presenti diversi ruoli che fanno uso d diversi linguaggi. Esistono DSL specificati per determinati compiti.alberto. .brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Un DSL è comunque uno strumento di comunicazione: perchè sia efficace la comunicazione deve 6 coinvolgere almeno due soggetti che condividano informazioni.Ecosistema di progetto Domain Expert Analyst Specification Architect Tester Code Developer DBA Alberto Brandolini . ovvero della lingua parlata dall’esperto di dominio.

ovvero della lingua parlata dall’esperto di dominio.Ecosistema di progetto DSL Domain Expert Analyst Specification Architect Tester Code Developer DBA Alberto Brandolini . .alberto. In un classico contesto di progetto sono presenti diversi ruoli che fanno uso d diversi linguaggi.brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Un DSL è comunque uno strumento di comunicazione: perchè sia efficace la comunicazione deve 6 coinvolgere almeno due soggetti che condividano informazioni. Esistono DSL specificati per determinati compiti. ma ciò che può avere impatto sul nostro modo di produrre software è rappresentato dal DSL specifico del dominio applicativo.

Esistono DSL specificati per determinati compiti.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Un DSL è comunque uno strumento di comunicazione: perchè sia efficace la comunicazione deve 6 coinvolgere almeno due soggetti che condividano informazioni.alberto. ma ciò che può avere impatto sul nostro modo di produrre software è rappresentato dal DSL specifico del dominio applicativo. In un classico contesto di progetto sono presenti diversi ruoli che fanno uso d diversi linguaggi.brandolini@avanscoperta. . ovvero della lingua parlata dall’esperto di dominio.Ecosistema di progetto DSL ? Domain Expert Analyst Specification Architect Tester Code Developer DBA Alberto Brandolini .

Esistono DSL specificati per determinati compiti.Ecosistema di progetto DSL ? Domain Expert Analyst UML Specification Architect Tester Code Developer DBA Alberto Brandolini .brandolini@avanscoperta. ovvero della lingua parlata dall’esperto di dominio. ma ciò che può avere impatto sul nostro modo di produrre software è rappresentato dal DSL specifico del dominio applicativo.alberto. In un classico contesto di progetto sono presenti diversi ruoli che fanno uso d diversi linguaggi. .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Un DSL è comunque uno strumento di comunicazione: perchè sia efficace la comunicazione deve 6 coinvolgere almeno due soggetti che condividano informazioni.

. ovvero della lingua parlata dall’esperto di dominio.Ecosistema di progetto DSL ? Domain Expert Analyst UML Specification Architect Tester Java Code Developer DBA Alberto Brandolini . In un classico contesto di progetto sono presenti diversi ruoli che fanno uso d diversi linguaggi. Esistono DSL specificati per determinati compiti.alberto.brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Un DSL è comunque uno strumento di comunicazione: perchè sia efficace la comunicazione deve 6 coinvolgere almeno due soggetti che condividano informazioni. ma ciò che può avere impatto sul nostro modo di produrre software è rappresentato dal DSL specifico del dominio applicativo.

it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Un DSL è comunque uno strumento di comunicazione: perchè sia efficace la comunicazione deve 6 coinvolgere almeno due soggetti che condividano informazioni.Ecosistema di progetto DSL ? Domain Expert Analyst UML Specification Java Architect Tester Java Code Developer DBA Alberto Brandolini . . ma ciò che può avere impatto sul nostro modo di produrre software è rappresentato dal DSL specifico del dominio applicativo.brandolini@avanscoperta. Esistono DSL specificati per determinati compiti. ovvero della lingua parlata dall’esperto di dominio.alberto. In un classico contesto di progetto sono presenti diversi ruoli che fanno uso d diversi linguaggi.

Ecosistema di progetto DSL ? Domain Expert Analyst UML Specification Java Architect Tester Java SQL Code Developer DBA Alberto Brandolini . ovvero della lingua parlata dall’esperto di dominio. ma ciò che può avere impatto sul nostro modo di produrre software è rappresentato dal DSL specifico del dominio applicativo. Esistono DSL specificati per determinati compiti. In un classico contesto di progetto sono presenti diversi ruoli che fanno uso d diversi linguaggi.alberto.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Un DSL è comunque uno strumento di comunicazione: perchè sia efficace la comunicazione deve 6 coinvolgere almeno due soggetti che condividano informazioni.brandolini@avanscoperta. .

possiamo 7 avvicinare mondi diversi.Avviciniamo i contesti Domain Expert Analyst Specification Architect Tester Code Developer DBA Alberto Brandolini . Possiamo avere maggiore controllo sulla corrispondenza tra il codice applicativo e le specifiche e ridurre molto del fardello di overhead e sincronizzazione legato alla presenza di due “viste” sulla stessa applicazione.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Potendo intervenire sulla forma dell’applicazione e sulla lingua utilizzata al suo interno. .brandolini@avanscoperta.alberto.

brandolini@avanscoperta. Possiamo avere maggiore controllo sulla corrispondenza tra il codice applicativo e le specifiche e ridurre molto del fardello di overhead e sincronizzazione legato alla presenza di due “viste” sulla stessa applicazione.alberto.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Potendo intervenire sulla forma dell’applicazione e sulla lingua utilizzata al suo interno.Avviciniamo i contesti Domain Expert Analyst Specification qui può succedere qualcosa di interessante Architect Tester Code Developer DBA Alberto Brandolini . . possiamo 7 avvicinare mondi diversi.

.alberto. . che risulta più leggibile e privo di fronzoli (basti pensare alle acrobazie necessarie per gestire i BigDecimal o le Date.brandolini@avanscoperta.scrittura di test più veloce ..DSL in Enterprise Application . A chi giova? .scrittura di test allargata a ruoli tradizionalmente esclusi Alberto Brandolini .codice applicativo più conciso e self-explaining .possibilità di controllare la più rapidamente la correttezza e/o la corrispondenza alle specifiche .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Quindi è interessante notare che il focus si sposta sul codice di test: abbiamo qualche vantaggio 8 significativo a livello di codice applicativo.scrivere codice che si possa leggere e capire a colpo d’occhio.

Infine (ed è la zona in cui si colloca Groovy) c’è la possibilità di allargare le possibilità espressive del linguaggio stesso.. … … Espansione delle possibilità espressive del linguaggio C++. ma la verbosità tecnologica di Java ha ostacolato questa direzione. .Different approcci ali DSL Vari approcci al problema: Parser/interpreti interni all’applicazione Scrittura di codice self-explaining Domain Driven Design. Altri tentativi sono stati legati alla possibilità di rendere il codice più accessibile. Alberto Brandolini . si è fatto ricorso ad 9 interpreti/parser dedicati. fluent interfaces Generazione specializzata di codice applicativo Intentional Software. Un’altra strada è quella legata alla generazione di codice a partire da una specifica espressa in una sorta di DSL (quindi realizzando l’applicazione in due fasi) separate..alberto. sfruttandone le possibilità di espansione. . Groovy.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Dove l’esigenza di conformarsi ad un SL già esistente era particolarmente forte. MDA. che permettessero l’uso del DSL nelle applicazioni.brandolini@avanscoperta.

coercition dei tipi numerici .alberto.brandolini@avanscoperta. senza arrivare alla complicazione di un parser dedicato. Matte infatti a disposizione una serie di strumenti legati alle sue caratteristiche di linguaggio dinamico che permettono di raggiungere risultati interessanti.overloading degli operatori . la cui struttura non era 10 sufficientemente flessibile. .DSL in Groovy Groovy introduce nuovi strumenti che aprono scenari sulla JVM: .object orientation completa .strumenti di metaprogrammazione .… piccole “chicche” sparse qua e la.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Groovy in questo senso rappresenta un passo in avanti notevole rispetto a Java.risoluzione dinamica dei metodi . Alberto Brandolini .

partendo dal foglio bianco (?) Alberto Brandolini . esaminiamo la possibilità di definire11 un piccolo dialetto legato alle operazioni finanziarie. gestendo quindi una “tipica” classe Money .alberto.brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Come primo esempio delle possibilità offerte da Groovy.Aritmetica Domain Specific Vogliamo esplorare le possibilità di scrittura di queste componenti offerte da Groovy Approccio white-box.Value Object riutilizzabile .Domain Class in Groovy .Money: obiettivi .

i due concetti sono in larga parte ortogonali.alberto. rendono estremamente conveniente affrontare il problema in quest’ottica. Gli strumenti offerti da Groovy al riguardo. secondo la classificazione di DDD. .brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Money. 12 Non c’è una corrispondenza precisa tra VO e DSL. rappresenta un classico esempio di Value Object. tuttavia buona parte dei DSL “general purpose” quindi legati a più domini applicativi sono basati su concetti che ricadono in questa categoria.DDD Value Object In Domain Driven Design un Value Object è un oggetto caratteristico del dominio applicativo: immutabile condivisibile privo di identità specifica La presenza dei Value Object è un elemento caratterizzante dei Rich Domain Model Alberto Brandolini .

con l’obiettivo di verificare costi e benefici di una “riscrittura” in Groovy .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Come esempio di riferimento prendiamo quindi l’implementazione di Money.brandolini@avanscoperta. definita dalla libreria 13 Time and Money.alberto.Time and Money Libreria Java open source “emanazione” di Domain Driven Design Tipi di dato riutilizzabili in svariati dominii alcuni problemi ricorrenti già affrontati: precisione del calcolo finanziario. usabilità delle date persistenza dei tipi di dato Maggiore espressività e chiarezza Alberto Brandolini .

0000000000000002220446049250313080847263336181640625> Alberto Brandolini .) rispetto a BigDecimal.. quindi anche l’autoboxing di java 5 non ci aiuta più di tanto. legata al fatto che BigDecimal NON è un tipo primitivo.Java “blocca la strada” BigDecimal non è un tipo numerico primitivo Operatori aritmetici da ridefinire Cambiamento di tipo tutt’altro che fluido Comportamento non sempre “user friendly” Come sono arrivato a questa situazione? java.brandolini@avanscoperta..) con lo stesso argomento! .AssertionError:
expected:<EUR
4>
but
was: <EUR
4... In particolare va rimarcato che BigDecimal ha un comportamento diverso nel caso sia invocato come new BigDecimal(.valueOf(.lang.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 La scrittura di una componente relativamente semplice.alberto. ha però in Java qualche complicazione in più 14 del previsto.

euros(10) Money twentyEuros = Money. .euros(20) assert twentyEuros == tenEuros + tenEuros assert twentyEuros == tenEuros * 2 Alberto Brandolini . altre risultano obsolete dalle possibilità offerte dalla meta programmazione. Molti metodi erano relativi a problematiche che in Groovy sono assolte direttamente dalla piattaforma.una buona notizia La scrittura della classe.alberto.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Tenendo ferme le caratteristiche definite dalla suite di test la scrittura del codice si è rivelata 15 molto più agevole.. a parità di test superati.. tanto in lunghezza.. L’overloading degli operatori premette già di trattare Money come un tipo primitivo.brandolini@avanscoperta. che in complessità. ha richiesto circa la metà del codice: Sintassi più concisa gestione dei BigDecimal molto smooth (via coercition) Alcuni metodi di utilità non più necessari Zucchero sintattico decisamente demodè Non solo… l’overloading degli operatori permette di scrivere: Money tenEuros = Money.

The comparable bug junit.framework. in effetti era un bug Groovy usa compareTo() dietro le quinte se si invoca ‘==’ su un Comparable Alberto Brandolini . ma dovremo verificare il comportamento con le prossime versioni del linguaggio. ma che sarà corretta prima o poi. Si tratta in realtà di 16 un’anomalia “benigna” di Groovy.00> Scompaiono anche i problemi nella gestione della precisione… (sembra troppo facile…) .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Qualche piccola sorpresa legata ad un problema “atteso” ma non presentatosi. Nel nostro caso l’implementazione corrente fa al caso nostro...alberto.AssertionFailedError:
 expected:<EUR
10>
but
was:<EUR
10. .brandolini@avanscoperta.

it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 … Quanto fato fino adesso è già piuttosto interessante.Creazione delle istanze di Money . la 17 metaprogrammazione in Grovy ci permette di manipolare le classi Java e Groovy.alberto. ma possiamo fare di meglio.Money . spingendole oltre l’immaginazione dei progettisti originari.reversibilità delle operazioni E’ necessario intervenire più in profondità per rendere la cosa più interessante Entra in gioco la ExpandoMetaClass Alberto Brandolini . .continued .brandolini@avanscoperta.

Expando Meta Class
EMC permette di aggiungere nuovi comportamenti alle classi già esistenti, a run time, senza modificarne il codice

Currency currency BigDecimal amount plus(...) minus(...) ...

Currency currency BigDecimal amount multiply(..) getReference()

Alberto Brandolini - alberto.brandolini@avanscoperta.it – Grails-IT
Javaday Roma III Edizione – 24 gennaio 2009

In particolare ci interesserà l’operatore ‘.’ corrispondente al metodo getReference, che simula 18 l’invocazione di un metodo getter su una property che non esiste nella classe originaria ma che abbiamo definito nella corrispondente MetaClass

I soldi iniziano a girare...
assert 20.EUR == 10.EUR + 10.EUR assertEquals 45.EUR, 9.EUR * 5 assertEquals 45.EUR, 5 * 9.EUR assertEquals 4.EUR, 36.EUR / 9 assertEquals 4, 36.EUR / 9.EUR assert 4.EUR == 1.60.EUR * 2.5 assertEquals 4.EUR, 1.60.EUR * 2.5 assertEquals assertEquals assertEquals assertEquals 250.EUR, (10.EUR + 15.EUR) * 10 25.EUR, (100.EUR + 150.EUR) / 10 2.5.EUR, (10.EUR + 15.EUR) / 10 250.EUR, 10 * (10.EUR + 15.EUR)

Alberto Brandolini - alberto.brandolini@avanscoperta.it – Grails-IT
Javaday Roma III Edizione – 24 gennaio 2009

In Groovy tutto è un oggetto, quindi anche gli interi ed i decimali lo sono. 19 Fornendo una Closure di valutazione innescata dalla ricerca di una property sulle classi numeriche, ed associandola alla MetaClass dele classi numeriche possiamo intercettare la valutazione della notazione postfissa e piegarla alle nostre esigenze.

...proviamo a spingerci oltre...

assertEquals 250.€,

10.€ * 25

Funziona! :-)
assertEquals 250.£, 10.£ * 25

Errore di compilazione :-(
assertEquals 250.$, 10.$ * 25

...Pure peggio :-(
Alberto Brandolini - alberto.brandolini@avanscoperta.it – Grails-IT
Javaday Roma III Edizione – 24 gennaio 2009

E’ abbastanza interessante notare che l’ipotetico passo successivo ci viene però sbarrato dalla 20 struttura del linguaggio, in maniera asimmetrica rispetto ala valuta utilizzata. In particolar modo per il tradizionale ruolo del simbolo ‘$’ come operatore. … non resta che passare alla moneta unica!

Però, così facendo, finisco per attribuire alla classe Number responsabilità che non le competono, violando uno dei principi della OOP

Alberto Brandolini - alberto.brandolini@avanscoperta.it – Grails-IT
Javaday Roma III Edizione – 24 gennaio 2009

Stiamo definendo nuovi modi per creare istanze della classe Money, ma stiamo distribuendo il codice 21 di pertinenza nelle gerarchie della classi numeriche che dovrebbero restare agnostiche rispetto a Money. Le classi della famiglia Number non vengono toccate direttamente, però non stiamo lavorando in modalità OOP “canonica”

reversibilità delle operazioni Il foglio bianco è il sogno di ogni programmatore. senza operare in modalità white-box Alberto Brandolini ..Legacy e Black Bok . La dura realtà .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 La prova effetuata su Money.brandolini@avanscoperta. ma non è forse realistica. è interessante.maggiore espressività su librerie Java .. vediamo che si può fare in modalità: . In un contesto reale non sempre 22 godiamo del privilegio di poter “riscrivere tutto in groovy”.alberto. Vorremmo avere le stesse possibilità espressive.è il legacy.

non parlo. .alberto.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 23 non vedo.brandolini@avanscoperta. non sento.Alberto Brandolini .

util.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 24 .Date nelle prossime versioni di Java Supporto out-of-the box per Hibernate supporto out-of-the box per JSP Alberto Brandolini .brandolini@avanscoperta.alberto.Joda Time Libreria con funzionalità avanzate per Date e Time Candidata alla sostituzione di java.

brandolini@avanscoperta.Date ed Intervalli con Groovy (Duration.Date ed Intervalli con Time and Money .Joda Time .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 25 . ha senso rivolgersi all’esistente.) .JScience Alberto Brandolini . etc.alberto.Black Box approach Prendendo in esame qualcosa di più complesso. In ambito DSL alcune aree di maggior complessità risultano già coperte: .

valueOf(“2 Kg”). KILO(GRAM)).calcoli type-safe Amount m3 = Amount.JScience Libreria con supporto per: .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 26 .valueOf(3.alberto.brandolini@avanscoperta.unità di misura (SI) .quantità . Alberto Brandolini . Amount m2 = Amount.

brandolini@avanscoperta. per cui sarabbe bene che fosse il più possibile disaccoppiata dal codice applicativo.Il punto della situazione Alberto Brandolini . . in 27 particolare per le aree dove la sintassi del inguaggo java si dimostra particolarmente infelice (le date sono un esempio lampante).it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Ho molti potenziali candidati a diventare DSL utili all’interno del mio contesto applicativo.alberto. ma decisamente complicata in termini di debugging. D’altra parte l’implementazione dei DSL è semplice in termini di righe di codice. Ciò spingerebbe verso una modularizzazione ed un uso estensivo dei DSL.

D’altra parte l’implementazione dei DSL è semplice in termini di righe di codice.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Ho molti potenziali candidati a diventare DSL utili all’interno del mio contesto applicativo. in 27 particolare per le aree dove la sintassi del inguaggo java si dimostra particolarmente infelice (le date sono un esempio lampante).brandolini@avanscoperta. .Il punto della situazione Molti DSL già disponibili “off the shelf” :-) Alberto Brandolini .alberto. per cui sarabbe bene che fosse il più possibile disaccoppiata dal codice applicativo. Ciò spingerebbe verso una modularizzazione ed un uso estensivo dei DSL. ma decisamente complicata in termini di debugging.

D’altra parte l’implementazione dei DSL è semplice in termini di righe di codice. .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Ho molti potenziali candidati a diventare DSL utili all’interno del mio contesto applicativo.Il punto della situazione Molti DSL già disponibili “off the shelf” :-) possibilità espressive interessanti :-) Alberto Brandolini .brandolini@avanscoperta. Ciò spingerebbe verso una modularizzazione ed un uso estensivo dei DSL. per cui sarabbe bene che fosse il più possibile disaccoppiata dal codice applicativo. in 27 particolare per le aree dove la sintassi del inguaggo java si dimostra particolarmente infelice (le date sono un esempio lampante).alberto. ma decisamente complicata in termini di debugging.

Ciò spingerebbe verso una modularizzazione ed un uso estensivo dei DSL. . D’altra parte l’implementazione dei DSL è semplice in termini di righe di codice.brandolini@avanscoperta. per cui sarabbe bene che fosse il più possibile disaccoppiata dal codice applicativo.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Ho molti potenziali candidati a diventare DSL utili all’interno del mio contesto applicativo.alberto. in 27 particolare per le aree dove la sintassi del inguaggo java si dimostra particolarmente infelice (le date sono un esempio lampante). ma decisamente complicata in termini di debugging.Il punto della situazione Molti DSL già disponibili “off the shelf” :-) Debugging dei DSL :-( possibilità espressive interessanti :-) Alberto Brandolini .

brandolini@avanscoperta. D’altra parte l’implementazione dei DSL è semplice in termini di righe di codice.Il punto della situazione Molti DSL già disponibili “off the shelf” :-) possibilità espressive interessanti :-) Debugging dei DSL :-( I DSL agiscono sulle stesse Classi chiave :-/ Alberto Brandolini . . in 27 particolare per le aree dove la sintassi del inguaggo java si dimostra particolarmente infelice (le date sono un esempio lampante).alberto.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Ho molti potenziali candidati a diventare DSL utili all’interno del mio contesto applicativo. per cui sarabbe bene che fosse il più possibile disaccoppiata dal codice applicativo. Ciò spingerebbe verso una modularizzazione ed un uso estensivo dei DSL. ma decisamente complicata in termini di debugging.

ma decisamente complicata in termini di debugging. D’altra parte l’implementazione dei DSL è semplice in termini di righe di codice.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Ho molti potenziali candidati a diventare DSL utili all’interno del mio contesto applicativo.alberto. in 27 particolare per le aree dove la sintassi del inguaggo java si dimostra particolarmente infelice (le date sono un esempio lampante). Ciò spingerebbe verso una modularizzazione ed un uso estensivo dei DSL.brandolini@avanscoperta. .Il punto della situazione Molti DSL già disponibili “off the shelf” :-) possibilità espressive interessanti :-) Sovrapposizioni fra i differenti dialetti :-/ Debugging dei DSL :-( I DSL agiscono sulle stesse Classi chiave :-/ Alberto Brandolini . per cui sarabbe bene che fosse il più possibile disaccoppiata dal codice applicativo.

Alberto Brandolini . .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Gli effetti della sovrapposizione degli interventi sulle stesse classi chiave possono infatti essere 28 sorprendenti e presentarsi in aree applicative molto lontane da dove il problema è stato effettivamente introdotto.brandolini@avanscoperta.alberto.

posso scrivere i miei DSL!! Alberto Brandolini .brandolini@avanscoperta. .Groovy è bestiale.alberto.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Gli effetti della sovrapposizione degli interventi sulle stesse classi chiave possono infatti essere 28 sorprendenti e presentarsi in aree applicative molto lontane da dove il problema è stato effettivamente introdotto.

. Alberto Brandolini ..quasi quasi me ne faccio uno anche io.Groovy è bestiale.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Gli effetti della sovrapposizione degli interventi sulle stesse classi chiave possono infatti essere 28 sorprendenti e presentarsi in aree applicative molto lontane da dove il problema è stato effettivamente introdotto.. posso scrivere i miei DSL!! Fico! .alberto.brandolini@avanscoperta...

brandolini@avanscoperta.alberto... .Groovy è bestiale..it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Gli effetti della sovrapposizione degli interventi sulle stesse classi chiave possono infatti essere 28 sorprendenti e presentarsi in aree applicative molto lontane da dove il problema è stato effettivamente introdotto. Alberto Brandolini .quasi quasi me ne faccio uno anche io.. posso scrivere i miei DSL!! Grande! posso riscrivere la grammatica del linguaggio!!! Fico! .

.Groovy è bestiale.brandolini@avanscoperta... posso scrivere i miei DSL!! Grande! posso riscrivere la grammatica del linguaggio!!! Fico! .quasi quasi me ne faccio uno anche io.alberto.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Gli effetti della sovrapposizione degli interventi sulle stesse classi chiave possono infatti essere 28 sorprendenti e presentarsi in aree applicative molto lontane da dove il problema è stato effettivamente introdotto.. Alberto Brandolini . Credono di essere capaci solo loro? Mo’ gli faccio vedere.. ..

it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Gli effetti della sovrapposizione degli interventi sulle stesse classi chiave possono infatti essere 28 sorprendenti e presentarsi in aree applicative molto lontane da dove il problema è stato effettivamente introdotto.alberto. Credono di essere capaci solo loro? Mo’ gli ho quest’errore faccio vedere.brandolini@avanscoperta. Alberto Brandolini . ....Groovy è bestiale... strano.quasi quasi me ne faccio uno anche io... posso scrivere i miei DSL!! Grande! posso riscrivere la grammatica del linguaggio!!! Hey! Fico! ..

Ovviamente supponendo che questo siano adeguatamente testati e supportati così da poterci effettivamente concentrare solo sul codice applicativo con in più le nuove potenzialità espressive.Separazione netta delle responsabilità Alberto Brandolini .Multiple DSL . .brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Vorremmo quindi la possibilità di disporre di un punto di controllo centralizzato per coordinare più 29 DSL a granularità fine.Fare convivere Un unico punto di innesco configurabile per più DSL più DSL nello stesso contesto DSL Modulari e componibili applicativo .alberto.

.DSL Descriptor Repository di delle caratteristiche specifiche del nostro DSL parole chiave operatori operazioni di setUp Alberto Brandolini .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Un primo elemento di questo nuovo approccio è la definizione d un descrittore del DSL che esponga le 30 caratteristiche specifiche del nostro DSL in formato standard.alberto.brandolini@avanscoperta.

) minus(....brandolini@avanscoperta. mentre le classi caratteristiche del DSL (Money) sono in grado di definire da sole il proprio comportamento.Scenario Money <<Interface>> DSLDescriptor getPostfix Operation Corretta allocazione delle responsabilità tra la classe ed il descrittore Money Currency currency BigDecimal amount plus(.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 In uno scenario come quello di money. MoneyDSLDescriptor Attribute Attribute Operation Operation Riscruttura del codice Interazione con i tipi primitivi ExpandoMetaClass Number Currency currency BigDecimal amount multiply(... il descrittore si limita a coordinare le operazioni sulle 31 classi esterne al subdominio (nel nostro caso la classe Number)..) getReference() Alberto Brandolini . .alberto..) .

.Scenario Time and Money Libreria complessa e già testata Maggiore ricorso alla EMC <<Interface>> DSLDescriptor getPostfix Operation CalendarDate plus(.) .. .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Nel caso Time & Money... String getReference ExpandoMetaClass Number Currency currency BigDecimal amount multiply(.) minus(....) .brandolini@avanscoperta.alberto. per i metodi non direttamente esposti da queste. e funge anche da 32 repository delle closure di valutazione delle classi del sottodominio delle date.. il nostro descrittore contiene una logica più complessa. TimeAndMoneyDSLDescriptor Attribute Attribute Operation Operation TimeInterval plus(...) minus(....) getReference() Alberto Brandolini .

alberto.priorità nell’ordine della risoluzione .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Al centro di questo scenario si collocherà il nostro coordinatore.brandolini@avanscoperta.registrazione e de-registrazione dei DSL Alberto Brandolini . di gestione dei conflitti tra operatori utilizzati da più dialetti.sovrapposizione degli operatori . 33 Dotato di risoluzione della priorità di valutazione.DSLEngine Un ruolo di coordinatore centralizzato per l’attivazione simultanea di più DSL Si aprono nuovi problemi: . e delle funzionalità di registrazione e de-registrazione dei DSL .

<<Interface>> DSLEngine Operation Operation <<Interface>> DSLDescriptor getPostfix Operation Separazione delle responsabilità: Engine come punto di coordinamento Descriptor come componente pluggabile AbstractDSLDescriptor priority Operation Operation MoneyDSLDescriptor Attribute Attribute Operation Operation TimeDSLDescriptor Attribute Attribute Operation Operation QuantityDSLDescriptor Attribute Attribute Operation Operation JodaTimeDSLDescriptor Attribute Attribute Operation Operation Alberto Brandolini .brandolini@avanscoperta.alberto.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 34 .

. .it – Grails-IT Perchè è interessante combinare più DSL? 35 Perchè in determinate circostanze..alberto. USD. M. in questo caso combinando Money e Quantity abbiamo una grammatica abbastanza significativa. l’unione di più componenti semplici può risultare significativa..brandolini@avanscoperta. MoneyDSLDescriptor Attribute Attribute Operation Operation QuantityDSLDescriptor Attribute Attribute Operation Operation Javaday Roma III Edizione – 24 gennaio 2009 Alberto Brandolini . GBP k...DSL Multipli .perché limitarci ad uno solo quando possiamo combinarne più di uno? <<Interface>> DSLEngine Operation Operation <<Interface>> DSLDescriptor getPostfix Operation EUR.

k. la maggiore espressività si raggiunge componendo frammenti di DSL separati assert 20.DSL Compositi A volte.brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Che permette una notazione sintetica dei grandi numeri combinando due grammatiche definite 36 indipendentemente l’una dall’altra.alberto.EUR == 10. .EUR * 2000 Alberto Brandolini .

EUR * 2000 Qu Alberto Brandolini .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Che permette una notazione sintetica dei grandi numeri combinando due grammatiche definite 36 indipendentemente l’una dall’altra.EUR == 10.brandolini@avanscoperta.alberto.k. la maggiore espressività si raggiunge componendo frammenti di DSL separati assert 20.DSL Compositi A volte. an tit yD SL .

EUR * 2000 yD an tit Qu Mo SL Alberto Brandolini .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Che permette una notazione sintetica dei grandi numeri combinando due grammatiche definite 36 indipendentemente l’una dall’altra.alberto.k.DSL Compositi A volte.brandolini@avanscoperta. la maggiore espressività si raggiunge componendo frammenti di DSL separati assert 20.EUR == 10. ne yD S L .

integrabile con svariate tecnologie . etc.basato su Groovy .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 37 .migliore curva di apprendimento dal mondo Java .La risposta a Ruby on Rails sulla JVM .brandolini@avanscoperta.Grails Framework per lo sviluppo rapido di applicazioni Web (ma non solo) .alberto. Quartz.si appoggia su librerie Java note e provate (Spring.) .infrastruttura spesso già installata Alberto Brandolini . Hibernate.

per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di 38 dominio.brandolini@avanscoperta.alberto.Grails Alberto Brandolini .

Grails te n-c ea ai cr om d as l s Alberto Brandolini .alberto.brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di 38 dominio. per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi .

per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi .brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di 38 dominio.alberto.Grails te n-c ea ai cr om d class Persona { String nome String cognome String e-mail Date dataNascita … } as l s Alberto Brandolini .

alberto. per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi .brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di 38 dominio.Grails te n-c ea ai cr om d class Persona { String nome String cognome String e-mail Date dataNascita … } as l s createcontroller Alberto Brandolini .

alberto.brandolini@avanscoperta.Grails te n-c ea ai cr om d class Persona { String nome String cognome String e-mail Date dataNascita … } as l s createcontroller class PersonaController { def list = { … } def create = { … } … } Alberto Brandolini . per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di 38 dominio.

Grails te n-c ea ai cr om d class Persona { String nome String cognome String e-mail Date dataNascita … } as l s createcontroller class PersonaController { def list = { … } def create = { … } … } Persone Id nome cognome eMail dataNascita Alberto Brandolini . per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi .alberto.brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di 38 dominio.

Grails te n-c ea ai cr om d class Persona { String nome String cognome String e-mail Date dataNascita … } as l s cr e e-vi eat w createcontroller class PersonaController { def list = { … } def create = { … } … } Persone Id nome cognome eMail dataNascita Alberto Brandolini . per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di 38 dominio.alberto.brandolini@avanscoperta.

alberto. per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi .Grails te n-c ea ai cr om d class Persona { String nome String cognome String e-mail Date dataNascita … } as l s cr e e-vi eat w createcontroller class PersonaController { def list = { … } def create = { … } … } Persone Id nome cognome eMail dataNascita Alberto Brandolini .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di 38 dominio.brandolini@avanscoperta.

per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di 38 dominio.Grails Entity class Persona { String nome String cognome String e-mail Date dataNascita … } te n-c ea ai cr om d as l s cr e e-vi eat w createcontroller class PersonaController { def list = { … } def create = { … } … } Persone Id nome cognome eMail dataNascita Alberto Brandolini .brandolini@avanscoperta.alberto.

it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di 38 dominio.alberto. per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi .Grails Entity class Persona { String nome String cognome String e-mail Date dataNascita … } te n-c ea ai cr om d as l s cr e e-vi eat w createcontroller class PersonaController { def list = { … } def create = { … } … } Value Object class Money { Currency currency BigDecimal amount … } Id nome Persone cognome eMail dataNascita Alberto Brandolini .brandolini@avanscoperta.

alberto. per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi .Grails Entity class Persona { String nome String cognome String e-mail Date dataNascita … } te n-c ea ai cr om d as l s cr e e-vi eat w createcontroller class PersonaController { def list = { … } def create = { … } … } ? Value Object class Money { Currency currency BigDecimal amount … } Id nome Persone cognome eMail dataNascita Alberto Brandolini .brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di 38 dominio.

alberto. per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi .brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di 38 dominio.Grails Entity class Persona { String nome String cognome String e-mail Date dataNascita … } te n-c ea ai cr om d as l s cr e e-vi eat w createcontroller class PersonaController { def list = { … } def create = { … } … } ? Value Object class Money { Currency currency BigDecimal amount … } ? Id nome Persone eMail dataNascita cognome Alberto Brandolini .

La gestione di eventuali tipi di dato ricorrenti è delegata a Hibernate via Gorm Alberto Brandolini .il dominio applicativo nasce in corrispondenza 1-1 con il database sottostante .localizzazione della logica applicativa nelle classi di dominio .alberto.brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 39 .Value Object in Grails Grails nasce privo del concetto di Value Object: .

Grails Scaffolding .GORM .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 40 .che delega la gestione agli User Type di Hibernate Alberto Brandolini .alberto.che però riconosce e gestisce di default solo i tipi primitivi .Ed il nostro DSL? Il supporto ai tipi di dato definiti dall’utente passa attraverso: .brandolini@avanscoperta.

Grails Scaffolding Così com’è Grails non ci permette di trarre il meglio dal DSL e dai tipi di dato che lo caratterizzano. . La generazione delle pagine e dello strato di persistenza non ha infatti le informazioni necessarie per generare pagine e database così come avviene per le classi di dominio basate sui dati primitivi.

alberto. .Widget riutilizzabile .integrato nel processo di scaffolding Componente di presentation che mirato sulle caratteristiche specifiche del nostro oggetto Grails deve essere in grado di riconoscere le istanze del nostro oggetto ed integrarle nel proprio processo di creazione della view Alberto Brandolini .brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Il nostro obiettivo è ora quello di verificare i punti di espansione e customizzazione offerti dalla 42 piattaforma per allargare le potenzialità di Grails anche al nostro DSL.Obiettivi .

integrazione conl’ambiente di sviluppo non eccelsa .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 43 .sintassi ed API di basso livello .Tag Libraries in Java La scrittura di una tag library in Java è un’operazione abbastanza punitiva .alberto.… varie ed eventuali Alberto Brandolini .processo di registrazione delle taglibraries .brandolini@avanscoperta.

brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 44 Fortunatamente abbiamo scoperto chi è l’autore delle specifiche :-) .alberto.Alberto Brandolini .

it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 ‐ contestualmente
crea
anche
il
 In grails la gestione delle tag libraries è largamente semplificata: 45 . .alberto.si tratta di un’operazione gestita diretamente dal framework.brandolini@avanscoperta.Tag Libraries >grails create-taglib ‐ grails
crea
il
sorgente
della
 nostra
Tag
Library
nella
cartella
 taglib corrispondente
test
nella
 cartella
/test/integration Alberto Brandolini . che provvede anche a creare i test.

permettendo di referenziarle direttamente da codice..amount) } Alberto Brandolini . value:attrs.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Inoltre la gestione dei namespaces è opzionale: di default il namespace è condiviso con le tag di 46 sistema..name}.currency".amount".Tag Libraries in Grails -Illusione di un unico spazio condiviso: -possibile referenziare altri tags direttamente all’interno del nostro codice -sintassi estremamente semplice -tag già registrati def money = { attrs -> . .value. value:attrs.alberto. out << currencySelect(name:"${attrs.value.currency) out << textField(name:"${attrs.name}.brandolini@avanscoperta.

brandolini@avanscoperta. é sufficiente andare a modificare il template offerto da Grails. Alberto Brandolini .alberto. Writer) generateController(GrailsDomainClass..it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Una volta definito il nostro componente grafico per il rendering.. . String. .-.template
 contiene le direttive di Grails per lo Scaffolding !"#$"%&$'()%*("+.(" DefaultGrailsTemplateGenerator .Extending Grails Scaffolding <<Interface>> GrailsTemplateGenerator setResourceLoader(ResourceLoader) generateViews(GrailsDomainClass. il nostro obiettivo è quello di renderlo 47 parte del processo di scaffolding di Grails. Writer) RenderEditor. String) setOverwrite(boolean) generateView(GrailsDomainClass. String) generateController(GrailsDomainClass...

GORM Tipi persistenti riutilizzabili Integrati nel processo di scaffolding Alberto Brandolini .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Per quanto riguarda la gestione della persistenza gestita da GORM.alberto. di fatto stiamo interagendo quasi 48 direttamente con Hibernate.brandolini@avanscoperta. .

Scrittura degli User Type semplificata dalle caratteristiche dei Value Object Discriminazione delle strategie di persistenza sulla base della classe class BankingAccount { String name String bank String iban Money currentBalance Currency currency static hasMany = [operations:BankingOperation.alberto. Si tratta di un’operazione inizialmente tediosa che può essere notevolmente semplificata ricordando che si tratta generalmente di Value Object con la caratteristica dell’immutabilità. .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Sarà necessario disporre di Hibernate User Type corrispondenti ai tipi di dato caratteristici del nostro 49 DSL.brandolini@avanscoperta. statements:Statement] static embedded = ['currentBalance'] static mapping = { columns { currentBalance type:MoneyCurrencyUserType } } Alberto Brandolini .

. Test ed ancora Test: … e magari se rimane tempo.. qualche altro test Alberto Brandolini . non dobbiamo inventarli L’utente ha (quasi) sempre ragione Keep it Simple Stupid: Non aggiungiamo nulla che non serva Test.alberto.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 Groovy offre una soluzione di compromesso interessante sul panorama dei DSL e Grails ne permette 50 l’integrazione in maniera tutto sommato agevole. .considerazioni finali Non reinventare la ruota: Alcuni dialetti già disponibili off-the shelf I linguaggi interessanti esistono già.brandolini@avanscoperta..

alberto.Domande? Alberto Brandolini .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 51 .brandolini@avanscoperta.

brandolini@avanscoperta.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 52 .alberto.Riferimenti Alberto Brandolini .

org/ http://grails.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 53 .alberto.org Alberto Brandolini .brandolini@avanscoperta.codehaus.Riferimenti http://groovy.

warneronstine.com/blog/articles/ 2008/04/24/groovy-dsl-roundup http://peterbacklund.de Alberto Brandolini .it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 54 .sourceforge.fr/weblog/ http://www.joda.com/ http://www.brandolini@avanscoperta.jakusys.net/ http://glaforge.Riferimenti JScience: http://jscience.alberto.org/ Time and Money: http:// timeandmoney.org/ Joda Time: http://www.blogspot.free.

alberto.mokabyte.yahoo.blogspot.com/group/Grails-IT/ Mokabyte: http://www.Riferimenti Grails-IT: http://it.it http://ziobrando.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 55 .wikidot.brandolini@avanscoperta.groups.com Alberto Brandolini .com http://albertobrandolini.

com/p/diesel/ Alberto Brandolini .alberto.google.it – Grails-IT Javaday Roma III Edizione – 24 gennaio 2009 56 .Open Source it! Sorgenti presto su: http://code.brandolini@avanscoperta.

Sign up to vote on this title
UsefulNot useful