Вы находитесь на странице: 1из 58

���������������������������� �����������

���������������
����������������������
����������� ��������������������� �������
���������������������������������������������������������������������������������������������������
������������������������������������������������
������������������������������������������������������������������������������������������������������������������������������������� ��������������������������������������������
����������������������������������������������������������������������������������������� ����������� �������
��������������������������������������������������
���������������������������������������������������������������������������������������
�� ������� ������ ������������ ���� ��������� ����� ����������� ��� ������ ���
����������������������������������������������������������������������
����������������������������������������������������������������������������
��������������������������������������������������������������������������
��������������������������������������������������
������������������������������������������������������������������������������

�����������������������������������������������������������������������������

�������������������������������������������������������������������������������
�����������������������
������������������������������������������������������������������������������ ������������������������������������������������������������

��������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������

����������������������������������������������������������������

���� ��� ������� ���������� �������������� ����� ����������� ���������� ���� ��� ������ ����������� ���� ��������� ���������� ������ ���� �������� �� ��������������������������������������������������������������
���������������������������������������������������������������������������������������������������������������������������������������
������������������������������������������������������������
���������������������������������������������������������������������
��������������������������������������������������������������������������������������������������� ��������������������������������������������������������������

����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
���������������������������������������������������������������������������������������

�������� ������� ������� ������������ ���������� ���� ���� ����� ����������� �������
������ ���� �������� ��� ���� �� ������ ��������� ����� �� ���������� ����������� ���� ��� ��������� ��� ���������� ��� ������������ ���� �����
������� ������������������������������� �� ����� ����������������������� ����������������������������������������������������
����������
www.infomedia.it EDITORIALE

JAVA Journal JavaFx: si


ricomincia?
BIMESTRALE - ANNO 1 - N.4

DIRETTORE RESPONSABILE
MARIALETIZIA MARI
(MMARI@INFOMEDIA.IT)

DIRETTORE ESECUTIVO
MICHELE SCIABARRÀ
(MICHELE.SCIABARRA@JAVAJOURNAL.IT)

EDITORIAL BOARD
UGO LANDINI, STEFANO SANNA, Avete mai “giocato” con una applet? Se siete programmatori Java della prima ora, la
F A B I O S T A R O , TO N Y M O B I L Y risposta non può che essere: ovviamente!
REDAZIONE
Ma non molti sono così… “anziani”. Considerando che la vita media di un
MIRELLA DI GIROLAMO
programmatore è di circa cinque anni (poi si diventa team leader, project manager
COLLABORATORI e così via, cioè... sempre meno codice e sempre più attività commerciale e di
ANDREA COLLEONI management), la maggior parte dei programmatori Java in attività ha cominciato
JACOPO GIUDICI con J2EE, quindi dopo il 2000; e così molti non hanno avuto occasione di “toccare
M A R C O PA N C O T T I con mano” le famose applet.
FE D E R I C O PA P A R O N I
STEFANO SANNA
ROBERTO SIDOTI Oserei dire: per fortuna! Perché, a parte le prime implementazioni in cui tutto filava
FA B I O S T A R O liscio, a partire dalla famosa guerra dei browser Microsoft-Netscape, sviluppare delle
ANDREA ZOLEO applet era un vero incubo in termini di compatibilità. E così lo spazio vitale delle
applicazioni Web lato client è stato lentamente conquistato da Flash, che ha da
sempre avuto il pregio di essere molto leggero e molto orientato ai grafici. Mentre
Java ha conquistato il suo spazio vitale nel mondo server. Almeno finché lo spazio
dei grossi server Internet di Sun non è stato rosicchiato da Linux. Ma questa è
GRUPPO EDITORIALE INFOMEDIA SRL un’altra storia.
V I A V A L D E R A P. 1 1 6
5 6 0 3 8 PO N S A C C O ( P I ) I T A L I A
Il mondo cambia, ma spesso tende a un ritorno alle origini. E infatti oggi si parla
TE L 0 5 8 7 7 3 6 4 6 0 F A X 0 5 8 7 7 3 2 2 3 2
E-MAIL INFO@INFOMEDIA.IT tanto di rich client e di applicazioni GUI che si installano dalla rete. E verrebbe da
S I T O W E B W W W. I N F O M E D I A . I T dire: Ma no? Che novità! Infatti avverto un fortissimo senso di déjà vu.
DIREZIONE
N A T A L E FI N O (NFINO@INFOMEDIA.IT) Ad ogni modo, abbiamo in campo da un lato Flash, che cerca di estendersi ovunque
con Flex e Apollo, e propone un Javascript super potenziato (da sembrare quasi
CONTATTI Java); dall’altro Microsoft che con il Silverlight e .NET propone una soluzione, a tutti
gli effetti concorrente di Flash, che a dire di Microsoft è interoperabile tra le varie
TE C H N I C A L B O O K piattaforme (sarà... vedremo).
(BOOK@INFOMEDIA.IT)

MARKETING & ADVERTISING E nel mezzo Java che fa? Francamente, non mi è chiarissimo. Quello che è certo
SEGRETERIA: 0587736460
(MARKETING@INFOMEDIA.IT)
è che è stato creato JavaFx, che è sempre Java (come tecnologia, JVM, ecc.), ma
utilizza un linguaggio Java semplificato, tanto da sembrare JavaScript, e con molte
AMMINISTRAZIONE caratteristiche che lo rendono allettante per i grafici (dalle demo si nota che ha una
(AMMINISTRAZIONE@INFOMEDIA.IT)
sintassi che rende molto semplice creare applicazioni grafiche sofisticate, stile Flash
SEGRETERIA appunto).
(INFO@INFOMEDIA.IT)

GRAFICA La sensazione è che si stia ricominciando con la battaglia delle applet, con una
(GRAFICA@GRUPPOINFOMEDIA.IT) versione di Java che vuole competere con Flash. A rinforzare questa sensazione
l’annuncio che il prossimo Java runtime sarà modulare, e comprenderà solo “quello
UFFICIO ABBONAMENTI che serve”.
TE L 0 5 8 7 7 3 6 4 6 0 F A X 0 5 8 7 7 3 2 2 3 2
ABBONAMENTI@INFOMEDIA.IT
W W W. I N F O M E D I A . I T Ad oggi, scaricare JavaRuntime per Windows, per esempio, è un download da 20
MB, mentre quello di Flash è un download di 2 MB. L’obiettivo del nuovo runtime
JAVA E TUTTI I MARCHI DERIVATI Java è di “pesare poco”, pochi megabyte (quanti, di preciso, è da vedere).
SONO MARCHI O MARCHI REGISTRATI
DI SUN MICROSYSTEMS, INC. NEGLI In sintesi, mi sembra che l’obiettivo sia proprio rendere Java comparabile con Flash,
U S A E I N A L T R I PA E S I . I L G R U P P O e riproporre, 10 anni dopo, l’idea originale che ha portato al successo di Java: le
EDITORIALE INFOMEDIA È INDIPEN- applet!
DENTE DA SUN MICROSYSTEMS, INC.

JAVA JOURNAL È UNA RIVISTA DEL Michele Sciabarrà


GRUPPO EDITORIALE INFOMEDIA SRL Direttore Esecutivo
DIREZIONE E AMMINISTRAZIONE: Java Journal
V I A V A L D E R A P. 1 1 6 - P O N S A C C O ( P I )
R E G I S T R A Z I O N E P R E S S O I L TR I B U N A L E
DI PISA N.19/06 DEL 5/9/2006

n.4 - settembre/ottobre 2007 3


JAVA Journal numero 4

SOMMARIO Settembre/Ottobre 2007

Speciale Object/Relational Mapping


Introduzione a Hibernate
di Marco Pancotti 8
iBatis: il più nostalgico degli ORM
di Roberto Sidoti 14
JPA: JAVA Persistence API - Prima parte
di Fabio Staro 20

Educational
XP e dintorni
di Andrea Zoleo 32

Focus
Database con SuperWaba per PDA e Smartphone
di Jacopo Giudici 40
Grafici nelle applicazioni JAVA
di Federico Paparoni 48

Rubriche
Orizzonti Enterprise
Tutto ciò che è tendenza nel mondo JEE
di Fabio Staro 29

Community Watch
Intervista al JAVA User Group Sardegna Onlus
di Stefano Sanna 55

n.4 settembre/ottobre 2007


IN VETRINA

Java Persistence with JavaScript & DHTML Practical JBoss®


Hibernate - 2nd Edition Cookbook, Second Edition Seam Projects
di C. Bauer di D. Goodman di J. Farley
Manning O’ Reilly Apress
980 pp - euro 52,95 604 pp - euro 45,00 229 pp - euro 46,40
ISBN 9781932394887 ISBN 9780596514082 ISBN 9781590598634

Now You Know EJB 3 iPhone :


Treo 680 Smartphone in Action The Missing Manual
di P. Ames di D. Panda, R. Rahman e D. Lane di D. Pogue
Addison Wesley O’ Reilly O’ Reilly
160 pp - euro 25,50 712 pp - euro 44.95 304 pp - euro 22,30
ISBN 9780321453488 ISBN 9781933988344 ISBN 9780596513740

The Web’s Awake: Smartphone Operating Professional Microsoft


An Introduction to the Field of System Concepts with Smartphone Programming
Web Science and the Concept of Symbian OS: di B. Yang, P. Zheng e L. M. Ni
Web Life A Tutorial Guide Jonh Wiley
di P. D. Tetlow di M. J. Jipping 494 pp - euro 50,70
John Wiley John Wiley ISBN 9780471762935
239 pp - euro 44,50 354 pp - euro 57,40
ISBN 9780470137949 ISBN 9780470034491

JAVA JOURNAL > n.4 settembre/ottobre 2007


>> 6
JAVA JOURNAL 4

Professional Java JDK 6 Edition iBATIS in Action, Edition 1 Walls: Spring in Action
di W. C. Richardson et al. di C. Beginet al. di C. Walls e R. Breidenbach
John Wiley Manning Manning
741 pp - euro 41,50 384 pp - euro 41,00 650 pp - euro 45,00
ISBN 9780471777106 ISBN 9781932394825 ISBN 9781933988139

Scrivi a book@infomedia.it specificando nell’oggetto della e-mail:


IN VETRINA Java Journal n. 4
oppure inviaci il coupon al numero di fax 0587/732232
Potrai acquistare i libri qui riportati con uno SCONTO ECCEZIONALE
del 10% anche se acquisti solo un libro
oppure del 20% se acquisti 3 libri

JAVA JOURNAL 4
speciale Object/Relational Mapping JAVA Journal

Introduzione a
Hibernate
Scrivere un breve testo su Hibernate è tutt’altro che facile, in quanto il prodotto è
estremamente ricco di funzionalità e di caratteristiche, ognuna delle quali meriterebbe un
approfondimento a sé.

>> di Marco Pancotti (mpancotti@javajournal.it)

Q uesto articolo è una introduzione


“a volo di rondine” su ciò che Hi-
bernate può offrire a chi sviluppa
applicazioni Java in cui la persi-
stenza degli oggetti è un elemen-
to determinante. Seguiranno, nei
prossimi numeri di Java Journal, una serie di articoli
in cui, passo dopo passo, si vedrà, in dettaglio, come
installare Hibernate, come utilizzarlo per mappare

ORM produce SQL sulla base di metadati associa-
ti alla classe da rendere persistente.

Hibernate richiede un certo sforzo di apprendi-


mento, in quanto affronta un tema complesso in
modo professionale. Le ottimizzazioni possibili
sia in lettura sia in scrittura, l’uso di Annotation
proprietarie che possono affiancare quelle proprie
dello standard JPA, la disponibilità di cinque di-
dei Domain Model complessi e come ottimizzarne le verse possibilità di accesso ai dati, l’uso di tecni-
prestazioni. che di caching e la presenza di opzioni specifiche
per il supporto alle applicazioni Web fanno di Hi-
bernate un prodotto sofisticato, che richiede, per
Il problema del mapping Object/Relational poter essere sfruttato appieno, un certo studio.

Il problema della mappatura oggetto/relazione è un • Hibernate ha una flessibilità tale da poter essere
tema vasto ed interessante, ma trascende lo scopo di utilizzato sia in un contesto in cui si può disegna-
questo primo articolo, che vuole invece concentrar- re il modello dati partendo dal modello ad ogget-
si sulla soluzione che Hibernate propone. Per questo ti, sia in un contesto in cui si deve fare i conti con
motivo in questo contesto ci limitiamo ad osserva- un modello dati preesistente. Lo scenario ideale
re che: per l’impiego di Hibernate è comunque quello in
cui un articolato Domain Model, ricco di classi e
• Hibernate è un vero e proprio O/R Mapper, non di associazioni tra classi, deve essere reso persi-
un wrapper (com’è ad esempio Rails), o un Data stente in totale indipendenza rispetto al database
Mapper (come è Ibatis). Le differenze sono sottili utilizzato, al contesto tecnologico (sistema opera-
ma importanti. Un wrapper, ad esempio, richiede tivo, network, ecc.) e all’interfaccia di accesso ai
che la progettazione avvenga in termini di model- dati (Web classico, RIA, Swing o nuovi ambienti
lo relazionale e che il Domain Model sia derivato come Flex, Silverlight o JavaFX). Per semplici ap-
dal data model, mentre un ORM permette un di- plicazioni, dove non vi è necessità di supportare
segno ad oggetti indipendente da cui si è in grado diversi database e dove si deve gestire una man-
successivamente di derivare, in modo automati- ciata di classi persistenti, è probabile che Hiber-
co, il modello relazionale ideale. Un Data Mapper, nate rappresenti un mezzo suicidio e che una so-
invece, richiede che l’accesso al database venga luzione basata su JDBC possa risultare più ade-
specificato in termini di codice SQL, mentre un guata.

8 n.4 - settembre/ottobre 2007


JAVA Journal Object/Relational Mapping speciale

La soluzione Hibernate al problema del mapping O/R file di configurazione dal nome hibernate.cfg.xml. La confi-
gurazione riportata qui di seguito è la più semplice possi-
Hibernate è un tool open source per il mapping object/ bile:
relational il cui intendimento è garantire agli utilizzatori
benefici in termini di produttività, manutenibilità, presta- <hibernate-configuration>
zioni e indipendenza dal produttore del RDBMS. <session-factory>
Hibernate è nato dallo sforzo di Gavin King, ben presto <property name=”hibernate.connection.driver_
supportato da Christian Bauer e da altri sviluppatori. Nel class”>com.mysql.jdbc.Driver</property>
2005 JBoss ha acquisito i diritti su Hibernate ed ha ingag- <property name=”hibernate.connection.url”>
giato i principali membri del gruppo di lavoro. Oggi Hiber- jdbc:mysql://localhost/jjhtut</property>
nate, in seguito all’acquisizione da parte di JBoss, fa par- <property name=”hibernate.connection.username”>
te dell’offerta di RedHat, anche se il gruppo di sviluppo ha myname</property>
mantenuto una totale indipendenza in termini di licen- <property name=”hibernate.connection.password”>
cing, disponibilità e supporto. mypass</property>
Hibernate si posiziona al top dell’offerta nell’ambito degli <property name=”dialect”>org.hibernate.dialect.
strumenti per la gestione della Java Persistence. Il gruppo MySQLDialect</property>
di sviluppo Hibernate ha partecipato alla definizione dello <!-- Mapped classes -->
standard EJB 3.0 influenzandone in modo evidente le scel- <mapping class=”org.jjh.Person”/>
te, pur mantenendo soluzioni di mapping e di tuning pro- <mapping class=”org.jjh.Organization”/>
prietarie che permettono un superamento dei limiti impo- …
sti dalla stretta aderenza agli standard JPA. </session-factory>
Hibernate è nato come tool Java, ma ne è stata sviluppa- </hibernate-configuration>
ta una versione per l’ambiente .NET, denominata NHiber-
nate. La release 1.2 di NHibernate, disponibile dai primi di
Maggio del 2007, comprende caratteristiche che attestano
NHibernate molto vicino ad Hibernate per Java.

Configurare un’applicazione basata su Hibernate


Hibernate è un tool
La configurazione di un’applicazione in cui si vuole utiliz- open source per il
zare Hibernate è piuttosto semplice. Il classpath dell’appli-
cazione deve includere una serie di file jar, tra cui i prin-
cipali inclusi nei package Hibernate Core e Hibernate Annota- mapping
tions scaricabili dal sito Hibernate, che sono:

• hibernate3.jar
object/relational
• hibernate-annotations.jar
• ejb3-persistence.jar
• hibernate-commons-annotations.jar

Oltre ai jar principali, è necessario che il classpath com-


prenda anche una serie di dipendenze, che sono: In altre parole, la precedente configurazione dichiara che:

• antlr.jar • per la connessione è utilizzato il driver JDBC MySql


• asm.jar • il database a cui si è connessi è sotto localhost e si chia-
• asm-attrs.jar ma jjhtut
• c3p0.jar • le credenziali di accesso sono myname con password
• cglib.jar mypass
• commons-collections.jar • il dialetto da utilizzare nella creazione delle istruzioni
• commons-logging.jar SQL è quello di MySql
• dom4j.jar • le classi Java mappate sul database sono org.jjh.Person e
• jta.jar org.jjh.Organization

Tutti i jar citati sono reperibili nella directory lib di Hiber- Il file di configurazione può essere arricchito di diversi
nate Core. altri parametri. Interessanti, tra gli altri, sono quelli che
permettono di creare o aggiornare automaticamente il da-
Se si utilizza l’IDE Eclipse è conveniente scaricare ed in- tabase sulla base del mapping; quelli che permettono di
stallare anche il plugin compreso in Hibernate Tools. Una visualizzare in console il codice SQL generato automati-
volta impostato il classpath è necessario che in corrispon- camente da Hibernate quando esegue i comandi; e quelli
denza della root della propria applicazione sia definito un destinati alla configurazione di pool di connessioni JDBC e

n.4 - settembre/ottobre 2007 9


speciale Object/Relational Mapping JAVA Journal

della cache. Terminato il setup di base, si può cominciare a SQL che viene generato, molte delle Annotation proprie-
definire il mapping. tarie sono dedicate ad un tuning che ha, come conseguen-
za, la generazione di un SQL più conforme ai desideri del-
lo sviluppatore. Questa attività di tuning può riguardare,
Uso delle Annotation per la mappatura del modello a tra l’altro:
classi su un DB relazionale
• il contenuto del codice SQL generato e l’opportunità di
Hibernate, nei suoi primi anni di vita, ha utilizzato un me- eseguire o meno le istruzioni di UPDATE in determina-
todo di mapping basato su file di configurazione XML. te circostanze;
Questo metodo, peraltro tuttora pienamente supportato, • il tipo di lock ottimistico da implementare nella gestio-
è stato affiancato, a partire dalla disponibilità di Java 5, ne degli aggiornamenti;
dal mapping basato su Annotations. Le Annotation utilizza- • l’impiego di speciali istruzioni WHERE nelle letture;
te da Hibernate sono quelle definite all’interno dello stan- • il comportamento “a cascata” nel caso di cancellazione
dard JSR 220 (Java Persistence API, o JPA) arricchite da di una entità “padre” rispetto alle entità associate;
una serie di Annotation proprietarie, che sono spesso uti- • la gestione di indici legati ad una o più proprietà;
li, se non indispensabili, per ottenere il massimo dal pro- • l’adozione di codice utente per la persistenza di una en-
prio database. tità diverso da quello normalmente adottato da Hiber-
Chi volesse rimanere aderente allo standard JPA dovreb- nate (ad esempio per utilizzare stored procedure, LDAP
be limitarsi ad usare le Annotation standard; ma il no- o altri approcci);
stro consiglio, se si vuole sfruttare appieno Hibernate, è • l’utilizzo di uno dei generatori di chiavi primarie messi
di studiare con attenzione anche le estensioni, anche per- a disposizione da Hibernate nel caso il database utiliz-
ché è probabile che presto entrino a far parte dello stan- zato non ne fornisca uno adeguato;
dard stesso. • l’adozione di formule per calcolare valori come se fos-
Poiché in questo “speciale ORM” vi è un articolo specifi- sero campi virtuali;
camente dedicato allo standard JPA, non ripeteremo qui • l’utilizzo di UserType, cioè di tipi definiti dall’utente
la spiegazione del significato di Annotation come @Enti- che richiedono particolari accorgimenti nel gestire la
ty, @Id, @Column e via dicendo, perfettamente corrispon- loro persistenza.
denti a quanto previsto dallo standard.
Nel codice che segue, in ogni caso, si può vedere un sempli- Sono disponibili molte altre Annotation specifiche di Hi-
cissimo mapping Hibernate definito tramite Annotation. bernate, troppe per essere citate integralmente in questo
articolo. La loro presenza permette allo sviluppatore un
@Entity controllo molto elevato del tool Hibernate, quando ciò è ri-
public class Flight implements Serializable { chiesto, evitando la frustrazione tipica di chi si è affidato
Long id; ad uno strumento nella speranza di guadagnare in sempli-
String destination; cità e rapidità di sviluppo per poi scoprire di dover subire
limitazioni inaccettabili in termini di funzionalità e pre-
@Id stazioni.
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }

La gestione delle transazioni


@Column(length=50)
Public getDestination(){Return destination;} Utilizzando Hibernate, la problematica della gestione delle
Public void setDestination(destination) transazioni può essere affrontata in due modi:
{ this.destination=destination;)
} • includere il controllo della transazione all’interno del
proprio codice, esplicitando così dove inizia e dove fini-
Ricordiamo invece che un ORM come Hibernate genera sce una transazione, per quali eccezioni eseguire le ca-
automaticamente le istruzioni SQL necessarie per eseguire tch e per quali rimandare allo strato software superio-
le letture e le scritture delle classi rese persistenti. Nel co- re;
dice Java, di conseguenza, ci si limiterà ad eseguire sem- • delegare il controllo della transazione ad un container,
plici istruzioni come magari basato su Spring o su EJB3. In questo caso, il
proprio codice si limita ad eseguire l’istruzione di ac-
get(Class, id) cesso al database, mentre il container controlla la tran-
sazione e ne gestisce le eccezioni.
o
In apparenza, il secondo metodo appare più sofisticato: ma
save(object) non dimentichiamo che esiste una scuola di pensiero per
cui il cuore della logica di un’applicazione gestionale sta
mentre la loro trasformazione nelle istruzioni SELECT o proprio nel controllo delle transazioni. Per chi è di questa
UPDATE è delegata ad Hibernate. Per evitare che lo svi- opinione il primo metodo è l’unico da seguire.
luppatore perda completamente il controllo del codice Hibernate, come tutti gli ORM aderenti allo standard JPA,

10 n.4 - settembre/ottobre 2007


JAVA Journal Object/Relational Mapping speciale

permette di implementare un locking ottimistico basato


sul versioning o sul timestamp. Nel primo caso Hibernate, • Processo: riguarda i dati condivisibili da più transazioni,
ad ogni UPDATE, incrementa automaticamente una pro- anche in modo concorrente, ma all’interno di una sin-
prietà numerica identificata dall’Annotation @Version. Nel gola macchina;
secondo caso la proprietà è invece di tipo Timestamp e l’ag-
giornamento consiste nella memorizzazione dell’istante in • Cluster: riguarda i dati condivisibili tra più transazioni
cui è avvenuto l’UPDATE. potenzialmente situate su diverse macchine connesse
tra loro in rete.

L’ottimizzazione delle prestazioni

Hibernate è dotato di una ricca serie di opzioni destinate a

Hibernate si posiziona
garantire elevate prestazioni alle applicazioni che lo utiliz-
zano per la gestione della persistenza.

al top dell’offerta
La strategia di fetch e la possibilità di tuning della
stessa
nell’ambito degli
Una prima serie di opzioni è dedicata alla possibilità di de-
strumenti per la
finire in dettaglio quando e come un’entità, e le entità ad
essa associate, sono lette dal database. Si tratta di un pun-
gestione della Java
to critico nell’utilizzo di un ORM, in quanto il codice uten- Persistence
te si limita, tramite un’istruzione

get(Class, id)

o
Il caching sfugge alle standardizzazioni JPA o EJB, per cui
load(Class, id) ogni fornitore di interfacce di persistenza propone la pro-
pria soluzione. Hibernate implementa una sofisticata ar-
a dichiarare cosa vuole leggere; mentre la traduzione di chitettura di caching a due livelli. Il primo livello di ca-
questa lettura in termini SQL è delegata all’ORM stesso. ching è predefinito e si occupa del caching transazionale. Il
La criticità emerge in modo prepotente quando la classe secondo livello di cache è configurabile come cache di pro-
target è piena di associazioni ad altre classi, siano esse re- cesso o di cluster. Questa cache è “pluggable” (è possibile
lazioni molti a uno (ManyToOne) sia uno a molti (OneTo- decidere se e come attivarla), può fare riferimento ad una
Many). Un cattivo disegno del mapping, in questi casi, può o più classi persistenti, ed è configurabile in funzione del
far decadere in modo irrimediabile le prestazioni, facendo fatto che ci si aspetti un’attività transazionale più o meno
rimpiangere una classica soluzione JDBC. frequente sulla classe messa in cache e del fatto che si vo-
Con Hibernate non si corre questo pericolo, in quanto l’uso glia garantire un livello più o meno alto di “isolamento”
adeguato delle sue parametrizzazioni, tutte esplicitabili agli oggetti presenti in cache. La cache di secondo livello
tramite Annotation, permette un forte controllo del codi- può essere implementata, a scelta dell’utente, usando uno
ce SQL generato. dei vari prodotti supportati da Hibernate (dal più sempli-
Nei casi più critici è sempre possibile richiedere che una ce EHCache fino al sofisticato JBoss Cache passando da
particolare lettura sia effettuata utilizzando un codice SQL OSCache e SwarmCache). La configurazione della cache
scritto “a mano” o tramite l’utilizzo di una stored proce- può essere pilotata da apposite Annotation proprietarie di
dure. Hibernate, unite, quando necessario, alla configurazione
del prodotto utilizzato.
Una corretta configurazione della cache, insieme ad una
Il caching strategia di dimensionamento e di alimentazione preven-
tiva della stessa all’avvio dell’applicazione, può condurre a
Uno dei motivi per cui si possono preferire le soluzio- significativi incrementi di performance e di scalabilità di
ni ORM rispetto al semplice uso di JDBC è che le prime un’applicazione Hibernate, soprattutto in ambito Web.
permettono di implementare una strategia di caching dei
dati, trasparente all’applicazione ma in grado di minimiz-
zare l’accesso al database manager. Il caching può essere La flessibilità nella scelta della strategia di accesso ai
realizzato a tre livelli: dati

• Transazionale: riguarda i dati propri della transazione o Hibernate propone un ampio ventaglio di possibilità di ac-
del gruppo di transazioni (conversation) in corso; l’ac- cesso ai dati persistenti.
cesso a questa cache non può essere concorrente;

n.4 - settembre/ottobre 2007 11


speciale Object/Relational Mapping JAVA Journal

HQL e JPA QL si deve far carico del problema della correttezza del codice
generato, così come degli eventuali problemi di portabilità
Il primo metodo si chiama HQL (Hibernate Query Langua- su altri database.
ge) che è un’estensione del linguaggio standard JPA deno-
minato QL. Una tipica istruzione HQL è del tipo:
Hibernate nelle applicazioni Web
from Person as p where p.name=’Marco’
Un’applicazione Web moderna, soprattutto in un conte-
Come si può osservare, vi è una forte somiglianza con SQL, sto Java, è normalmente disegnata a più livelli. Il layer più
anche se ci si riferisce a classi e proprietà e non a tabelle e basso, quello della persistenza, è il regno di Hibernate. Il
campi. Un uso professionale di HQL permette di ottenere layer Persistenza basato su Hibernate è normalmente com-
tutto ciò che, normalmente, si chiede a SQL, con il vantag- posto da:
gio di ricevere in output liste di oggetti immediatamente
utilizzabili nel proprio codice Java, e non dei semplici Re- • Un Domain Model adeguatamente annotato
sultSet. • Un DAO base, riutilizzato in più punti dell’applicativo
per i più semplici comandi di lettura e aggiornamento
dei dati
Query by Criteria • Da DAO specifici, che implementano istruzioni di ricer-
ca e gestione per le classi più complesse, che richiedo-
Capita spesso, che in un applicativo si debba costruire una no strategie particolari di query o di aggiornamento dei
query “al volo”, sulla base dello stato corrente, in quanto dati.
si desidera poter decidere a runtime che cosa ricercare, e
sulla base di quali criteri di selezione. Per fare questo si po- I DAO (che altro non sono che degli insiemi di metodi per
trebbe delegare al codice Java la creazione della stringa di l’accesso al database), siano essi standard o specifici, sono
ricerca concatenando le stringhe “from”, “where”, “and” poi utilizzati dallo strato superiore del software, normal-
e via dicendo, per ottenere un comando adatto alla ricerca mente denominato “layer Servizi”. Il layer Servizi imple-
che si vuole effettuare. Questo metodo è però scomodo e menta gli “use case” di gestione del database attivati dalla
poco adatto alla programmazione ad oggetti. GUI o dalle applicazioni di tipo batch. Uno “use case” di
Per ovviare a questo limite, Hibernate mette a disposizio- inserimento di un ordine cliente, ad esempio, può essere
ne un’interfaccia Java che permette di definire una query gestito da una classe di tipo “service” denominata Order-
creando degli oggetti di tipo Criteria all’interno dei quali è Fulfillment che, a sua volta, utilizza un OrderDAO, un Custo-
possibile, sempre in modo dinamico, specificare i dettagli merDAO, un PaymentDAO, ecc.
dell’interrogazione da creare. L’uso di questa architettura permette di concepire, svilup-
Benché l’uso di questa tecnica sia più raro rispetto all’uso pare ed implementare dei Domain Model persistenti for-
di HQL, la presenza delle Query by Criteria può risultare temente indipendenti dal software sottostante (database
molto comoda in determinate circostanze. manager, sistema operativo, rete, ecc.) e da quello sovra-
stante (GUI, layer Servizi, ecc.), che siano di facile docu-
mentazione e manutenzione.
Query by Example

Le Query by Exemple sono molto simili alle Quey by Crite- Il test di applicazioni basate su Hibernate
ria, ma il dettaglio dell’interrogazione è specificato utiliz-
zando delle classi che contengono degli “esempi” dei dati Il test dello strato di persistenza basato su Hibernate è
da utilizzare come filtri di ricerca. molto più semplice rispetto a quello che normalmente si
L’esecuzione della ricerca ritorna, come risultato, gli ogget- progetta per applicazioni non basate su un ORM. L’uso
ti della stessa classe “compatibili” con l’esempio fornito. delle Annotation, infatti, rende inutile la verifica della
È evidente che questa possibilità può essere preziosa nel- consistenza tra classe Java e tabella usata per la persisten-
le classiche ricerche “libere” dove l’utente deve compilare za. Allo stesso tempo la correttezza del codice SQL utilizza-
uno schermo da usare come “template” per un’interroga- to per l’accesso al database è garantito da Hibernate stes-
zione complessa. so e non richiede ulteriori attenzioni. Il test si concentra
quindi, nella maggioranza dei casi, sulla verifica delle pre-
stazioni e della scalabilità dell’applicazione, alla ricerca di
SQL nativo eventuali problemi risolvibili tramite l’ottimizzazione delle
Annotation o la semplificazione del modello.
Vi sono casi, per quanto rari, in cui tutte le possibilità offer-
te da Hibernate per il tuning delle query si rivelano insuffi-
cienti rispetto all’obiettivo che si vuole ottenere. In questo L’uso di Hibernate con database già configurati
caso il tool permette di creare una query utilizzando istru- (legacy)
zioni SQL native, anche proprie del dialetto SQL imple-
mentato dal DBMS di riferimento. Hibernate sviluppa tutta la sua potenza quando si può par-
Ovviamente, quando decide di usare SQL nativo, l’utente tire da un Domain Model concepito solo in funzione del-

12 n.4 - settembre/ottobre 2007


JAVA Journal Object/Relational Mapping speciale

la sua rappresentatività del problema affrontato, senza le progettare l’interfaccia utente in termini di Conver-
preoccupazioni legate al data model. sation (sequenza di richieste logicamente collegate tra
Nella realtà, purtroppo, si deve spesso fare i conti con mo- loro). Seam si colloca in un contesto EJB3 arricchen-
delli dati preesistenti, da utilizzare all’interno della propria dolo di funzionalità destinate alla semplificazione della
applicazione, senza una reale possibilità di cambiamento. scrittura di GUI Web.
Hibernate è in grado di essere utile anche in questa circo-
stanza, in quanto il suo sistema di Annotation può descri-
vere anche le situazioni più complesse, garantendo il map- Conclusioni
ping richiesto tra un database legacy e il proprio modello
ad oggetti. Al termine di questa prima carrellata, possiamo afferma-
re che:

I componenti complementari a Hibernate • Hibernate è un prodotto molto ambizioso, in continua


crescita in termini di funzionalità e flessibilità che si
Quando si parla di Hibernate, normalmente, si fa riferi- colloca al vertice delle possibili scelte di un ORM in
mento al prodotto Hibernate Core insieme a Hibernate Anno- ambito Java.
tations. Ma l’offerta è ancora più ricca, e si completa con i
seguenti prodotti: • Usando Hibernate e le sue Annotation, sia standard
sia proprietarie, possiamo descrivere con semplicità il
• Hibernate EntityManager. Implementa l’interfaccia mapping delle proprie classi senza perdere in termini
di programmazione e le regole del ciclo di vita definite di potenza e rappresentatività delle situazioni più com-
dalle specifiche EJB3. Utilizzando l’EntityManager si plesse.
può quindi adottare uno standard di programmazione
EJB3 anche all’interno di un semplice application con- • In caso di necessità, Hibernate permette di ripiegare su
tainer come Tomcat. un codice SQL scritto “a mano” dal progettista dell’ap-
plicazione, anche se, grazie alla sofisticazione delle An-
• Hibernate Tools. Si tratta di una serie di tools notation proprietarie, si tratta di una caratteristica che
utilizzabili all’interno di un plugin Eclipse o come co- ha scarse probabilità di dover essere utilizzata.
mandi Ant che facilitano la creazione della configura-
zione Hibernate (hibernate.cfg.xml), la visualizzazione • L’utilizzo di Hibernate non solo non comporta perdi-
dello schema persistente, la creazione e l’aggiornamen- te di prestazioni ma, in un contesto di Domain Model
to dello schema del database sulla base delle specifiche complesso dove è sfruttabile il caching di secondo livel-
di mapping ed altro ancora. lo, si possono avere significativi vantaggi rispetto alle
soluzioni basati sul semplice JDBC.
• Hibernate Validator. Fornisce un insieme standard
di Annotation utilizzabili per la validazione dei dati, • Hibernate apre la strada in modo semplice all’utilizzo
come ad esempio @NotNull, @Email, @CreditCard- di tecnologie avanzate come quelle di full-text search o
Number, @Max, @Range, ecc. L’utilizzo di queste An- di clustering multi-database.
notation permette di definire a livello di Domain Mo-
del delle regole di validazione che possono poi essere
utilizzate in diversi punti dell’applicazione. Bibliografia e riferimenti

• Hibernate Search. Permette di sfruttare la tecnologia [1] Christian Bauer e Gavin King, “Java Persistence with Hi-
Lucene di indicizzazione e di “full text search” all’in- bernate”, Manning Publications Co. (2007). È un testo
terno del Domain Model persistente. Tramite una serie pubblicato da qualche mese al confronto del quale ogni
di Annotation vengono creati e mantenuti gli indici ne- altro libro in circolazione è, al momento, obsoleto op-
cessari per poter poi eseguire ricerche di tipo free-text pure incompleto.
in modo ottimizzato all’interno delle proprietà di tipo [2] www.hibernate.org - Il sito di Hibernate.
testo. Poiché viene utilizzato Lucene, l’indicizzazio-
ne avviene indifferentemente dal fatto che il databa-
se manager fornisca una specifica tecnologia a questo
scopo.
Note Biografiche
• Hibernate Shards. Permette di rendere persistente
Marco Pancotti ha iniziato la sua carriera nel 1982, in una delle
un Domain Model su più database, anche posizionati maggiori società internazionali di Business Consulting. Dopo
su diversi nodi della rete, in modo trasparente all’ap- aver diretto una società di software ha cominciato, a partire dai
plicazione. primi anni 90, ad operare come consulente direzionale in ambi-
to IT. È autore di una metodologia per la certificazione di qua-
lità del software basata sull’applicazione della norma ISO 9126
• JBoss Seam. Seam è un framework che si pone come e di un metodo di valutazione della qualità di siti Web orienta-
ponte tra Hibernate e JSF, allo scopo di favorire la scrit- ti all’eBusiness. È membro del Comitato Tecnico OASIS per la
definizione dello standard UBL e realizza applicazioni basate
tura di sofisticate applicazioni Web in cui sia possibi- sugli standard ebXML/UBL.

n.4 - settembre/ottobre 2007 13


speciale Object/Relational Mapping JAVA Journal

iBatis: il più
nostalgico degli
ORM
L’utilizzo degli ORM (Object Relational Mapping tool) consente di raggiungere il livello di
astrazione desiderato e facilita ulteriormente la gestione dei dati durante il processo di
sviluppo.

>> di Roberto Sidoti (rsidoti@javajournal.it)

D
a molti anni ormai, ci si è accorti che bernate, è sempre l’SQL a ricoprire il ruolo principa-
le operazioni per interagire con un le nella gestione dei dati; però molti passaggi impo-
database sono spesso ripetitive e che sti dalle API JDBC sono stati semplificati ed affidati
quindi il livello di astrazione di JDBC a file XML di configurazione. Possiamo già immagi-
non è quello ottimale. Gli sviluppato- nare che questo approccio soddisfi sia i DBA (che nei
ri Java traggono spesso profitto dal- progetti di dimensioni medio-grandi possono tenere
l’impiego di framework open source nella loro attivi- sotto controllo l’SQL utilizzato) sia gli architetti fun-
tà di sviluppo e design. Molte volte questi framework zionali (che possono contare su API ben disegnate e
hanno condizionato anche l’evoluzione del linguag- pensate per ridurre le possibilità di errore degli svi-
gio stesso: basti pensare all’influenza che ha avuto luppatori). Infatti, chi ha avuto a che fare con JDBC
Hibernate nella definizione delle Java Persistence sa benissimo che le operazioni da effettuare sono
API (JPA). Hibernate è sicuramente l’ORM che ha spesso ripetitive; la gestione dei dati in molti casi si
conquistato la leadership in quanto a diffusione ed riduce a poche righe di codice, mentre le restanti ope-
utilizzo nei progetti Java; però c’è da sottolineare che razioni sono dovute a:
non è l’unico che ha riscosso successo. Tra i proget-
ti open source, che si occupano di rendere la vita più • Gestire le connessioni e le transazioni;
agevole agli sviluppatori quando hanno a che fare
con un database relazionale, iBatis è uno di quelli più • Estrarre da oggetti Java i parametri per le query
utilizzati e vanta una curva di apprendimento prati- SQL;
camente piatta. In questo articolo ne presenteremo le
caratteristiche principali e incominceremo a vederlo • Creare i PreparedStatement;
all’opera basandoci su un esempio pratico.
• Convertire i risultati ottenuti dai ResultSet negli
oggetti Java appropriati.
Perchè scegliere iBatis?
Ecco che iBatis ha pensato di minimizzare tali opera-
iBatis (Figura 1) è un framework non così evoluto zioni attraverso la definizione di una serie di pattern
e distante da quello che è l’approccio JDBC. Infatti, concentrati in un framework denominato DataMap-
al contrario di altri framework, come ad esempio Hi- per (oppure SqlMapClient). Questo framework, infatti,

14 n.4 - settembre/ottobre 2007


JAVA Journal Object/Relational Mapping speciale

FIGURA 1 Il sito ibatis.apache.org

prevede diverse tipologie di gestione delle connessioni al … // getter e setter


DB nonché il supporto delle più diffuse API per la gestione }
delle transazioni.
I pattern proposti si occupano in modo molto elegante sia In particolare l’id sarà la chiave primaria della tabella,
del mapping tra i VO (JavaBean) dell’applicazione ed i pa- mentre il campo nomeScaffale rappresenta il nome/etichetta
rametri da utilizzare nei PreparedStatement, sia del processo dello scaffale; infine piano e colonna servono a definire la
inverso, ossia del mapping tra i ResultSet e gli oggetti Java. posizione del farmaco nello scaffale. Invece, possiamo de-
La base dell’utilizzo del DataMapper è costituita dall’impie- finire una modellazione del farmaco rappresentata dalla
go di uno o più file XML che contengono le query SQL che seguente classe Java:
si vogliono eseguire, ed i mapping appena discussi.
public class FarmacoVO {
private String id=null;
private String nome=null;
Full immersion
private String descrizione=null;
Definiamo un’applicazione d’esempio che ci aiuterà a ca- private int quantita=0;
pire le caratteristiche principali di questo tool. Data la na- private PosizioneVO posizione=null;
tura didattica dell’esempio, le soluzioni proposte si presta- … // getter e setter
no senza dubbio a migliorie ed integrazioni. Supponiamo }
di dover gestire la collocazione dei farmaci all’interno di
uno o più scaffali. Avremo, quindi, essenzialmente a che Come prima, l’id sarà la chiave primaria della corrispon-
fare con le entità farmaco e con le relative posizioni occu- dente tabella del DB; il nome rappresenta il nome del far-
pate all’interno degli scaffali. Una posizione ha le seguen- maco, il campo quantità memorizza le unità presenti. Il
ti proprietà: campo posizione serve a memorizzare la posizione in cui è
possibile reperire il farmaco. Ora che sappiamo quali dati
public class PosizioneVO { dobbiamo gestire nell’applicazione, incominciamo a vede-
private String id=null; re come funziona iBatis. Per prima cosa serve un file XML
private String nomeScaffale=null; che definisca la gestione della connessione, delle transa-
private int piano=0; zioni e di tutti gli aspetti di configurazione per un utilizzo
private int colonna=0; efficiente del DB:

n.4 - settembre/ottobre 2007 15


speciale Object/Relational Mapping JAVA Journal

La sezione sqlMap definisce un elenco di file XML in cui


<sqlMapConfig> sono contenute le query SQL ed i mapping ad esse asso-
<settings useStatementNamespaces=”true” /> ciati. Nel nostro caso sono stati specificati due file, ognu-
no abbinato alla gestione di uno dei JavaBean precedente-
<transactionManager type=”JDBC”> mente definiti.
<dataSource type=”SIMPLE”>
<property name=”JDBC.Driver” value=”org.
File di mapping
hsqldb.jdbcDriver”/>
<property name=”JDBC.ConnectionURL” I file di mapping vengono caricati dal framework in base
value=”jdbc:hsqldb:file:/roby/ all’ordine definito nel file di configurazione, che abbiamo
private/software/dev/java/iBatisCafe/data/ chiamato SqlmapConfig.xml. Essenzialmente, contengono le
iBatisCafe”/> query SQL utilizzate per scrivere e leggere i dati; ogni query
<property name=”JDBC.Username” è etichettata con una stringa il cui valore può essere uti-
value=”sa”/> lizzato all’interno del codice Java per invocare l’enunciato
<property name=”JDBC.Password” value=””/> SQL in questione. Il loro utilizzo non è tutto qui: infatti, si
<property name=”JDBC.DefaultAutoCommit” occupano sia di mappare gli oggetti Java sui parametri dei
value=”true” /> PreparedStatement utilizzati, sia di trasformare i ResultSet
</dataSource> in oggetti che modellano il dominio dell’applicazione.
</transactionManager>
<sqlMap namespace=”posizione”>
<sqlMap resource=”posizione.xml”/>
<sqlMap resource=”farmaco.xml”/> <select id=”read” parameterClass=”java.lang.
String”
</sqlMapConfig> resultClass=”cafe.farma.data.vo.
PosizioneVO”>
All’interno del tag sqlMapConfig sono definite tre sezioni: select * from posizione where id=#value#
settings, transactionManager e sqlMap. La prima prevede la di- order by nomescaffale
chiarazione di un insieme di attributi opzionali che servo- </select>
no ad ottimizzare l’oggetto sqlMap che si istanzierà da codi-
ce Java. La semantica dell’attributo useStatementNamespaces <insert id=”create” parameterClass=”cafe.
sarà chiarita successivamente. Il tag transactionManager ser- farma.data.vo.PosizioneVO”>
ve per la configurazione del gestore delle transazioni. L’at- insert into posizione(id,nomescaffale,
tributo type specifica quale tipo gestore si vuole utilizzare; piano,colonna)values(#id#,#nomeScaffale#,#piano#,
lo si può valorizzare o con il nome di una classe (utile per #colonna#)
eventuali personalizzazioni del framework) o con tre alias: </insert>
JDBC, JTA o EXTERNAL. Il primo specifica che le transa-
zioni sono gestite direttamente con le primitive messe a <update id=”update” parameterClass=”cafe.
disposizione da JDBC. Il secondo permette di agganciarsi farma.data.vo.PosizioneVO”>
alle Java Transaction API di Sun, l’ultimo valore può essere update posizione set
utilizzato quando si vuole affidare la gestione delle transa- nomescaffale=#nomeScaffale#,
zioni ad un layer esterno a iBatis. piano=#piano#,
Il tag dataSource, e tutti i tag da esso contenuti, servono a colonna=#colonna#
definire la gestione delle connessioni al DB e quindi il tipo where id=#id#
di connection pool da utilizzare. Il framework mette a dispo- </update>
sizione tre valori da poter assegnare all’attributo type:
<delete id=”delete” parameterClass=”java.lang.
• SIMPLE specifica che sarà utilizzata una soluzione pro- String”>
prietaria ed è la soluzione ideale quando iBatis non è delete from posizione
abbinato a nessun container J2EE; where id=#id#
</delete>
• DBCP consente di sfruttare l’omonima libreria open
source di Apache; <select id=”list” parameterClass=”cafe.farma.
data.vo.PosizioneVO”
• JNDI permette di agganciarsi tramite JNDI alla gestio- resultClass=”cafe.farma.data.vo.
ne delle connessioni messe a disposizione da un con- PosizioneVO”>
tainer esterno. select * from posizione
where nomescaffale like #nomeScaffale# and
È importante notare che la proprietà JDBC.DefaultAutoCommit piano=#piano# and colonna=#colonna#
valorizzata a true evita la gestione da codice delle transazio- </select>
ni; pertanto tutte le operazioni di scrittura sul DB saranno
oggetto di commit automatico da parte del framework. </sqlMap>

16 n.4 - settembre/ottobre 2007


JAVA Journal Object/Relational Mapping speciale

Il parametro passato come input all’enunciato insert non


è più una classe Java definita da un attributo parameter-
Class, ma, come possiamo notare, è definito dall’attribu-
to parameterMap. Quest’ultimo deve essere definito prima
del suo utilizzo.

<parameterMap id=”farmacoINS” class=”caf


e.farma.
data.vo.FarmacoVO”>
<parameter property=”id” />
<parameter property=”nome” />
<parameter property=”descrizione” />
<parameter property=”quantita” />
<parameter property=”posizione.id” />
</parameterMap>

L’attributo id definisce la stringa con cui il parameterMap


è referenziabile all’interno del file farmaco.xml. I tag pa-
rameter definiscono il mapping e l’ordine con cui vengo-
no riprodotte le proprietà dell’oggetto in questione nel-
l’enunciato SQL che lo utilizza; in particolare, queste
proprietà andranno a sostituirsi ai “?”. Vediamo adesso
come iBatis si comporta per l’operazione inversa, ossia
FIGURA 2 Il progetto visto da Eclipse come mappa oggetti composti a partire da un ResultSet
avuto come risultato di una Select.

La semantica dei vari tag XML è molto intuitiva: il tag sql- <resultMap id=”farmacoRM” class=”cafe.farma.data.
Map prevede un attributo namespace; esso, insieme ai va- vo.FarmacoVO”>
lori degli attributi id dei tag contenuti, compone la stringa <result property=”id” column=”farmaco_id”/>
con cui è possibile referenziare da codice i diversi enun- <result property=”nome” column=”farmaco_nome”/>
ciati SQL. Il tag select prepara il framework all’esecuzio- <result property=”descrizione” column=”farmaco_
ne dell’omonimo comando SQL; in particolare parameter- descrizione”/>
Class definisce il tipo dell’oggetto passato come parametro <result property=”quantita” column=”farmaco_
alla query. Lo stesso valore è mappato dalla stringa #va- quantita”/>
lue# nella query contenuta nel tag. #value# è un partico- <result property=”posizione.id”
lare mapping utilizzato per tutti gli oggetti istanze di classi column=”posizione_id”/>
contenute nel package java.lang. Invece, osservando il tag <result property=”posizione.nomeScaffale”
update possiamo notare che gli oggetti, il cui valore dell’at- column=”posizione_nomescaffale”/>
tributo parameterClass non è una classe di java.lang, abbia- <result property=”posizione.colonna”
no una forma di mapping diversa. Infatti, nella query di column=”posizione_colonna”/>
update è possibile far riferimento a tutti i campi dell’ogget- <result property=”posizione.piano”
to secondo la sintassi #<campo-Getter>#, dove <campo- column=”posizione_piano”/>
Getter> indica il campo dell’oggetto deducibile con il corri- </resultMap>
spondente getter. Nei tag select si rende necessario l’utiliz-
zo dell’attributo resultClass; esso definisce il mapping tra il <select id=”read” parameterClass=”java.lang.
ResultSet risultato della Select e gli oggetti che si desidera String”
avere come output. resultMap=”farmacoRM”>
select farmaco.id as farmaco_id,
farmaco.nome as farmaco_nome,
farmaco.descrizione as farmaco_
Mapping avanzato
descrizione,
Il file farmaco.xml presenta qualche difficoltà in più, in farmaco.quantita as farmaco_quantita,
quanto l’oggetto FarmacoVO contiene un oggetto istanza posizione.id as posizione_id,
di PosizioneVO. Per semplicità, prenderemo in esame solo le posizione.nomescaffale as posizione_
operazioni di create e read. nomescaffale,
posizione.colonna as posizione_colonna,
<insert id=”create” parameterMap=”farmacoINS”> posizione.piano as posizione_piano,
insert into farmaco(id,nome,descrizione, from farmaco,posizione
quantita,posizione_id) values (?,?,?,?,?) where farmaco.id=#value# and
</insert> farmaco.posizione_id=posizione.id
order by nome

n.4 - settembre/ottobre 2007 17


speciale Object/Relational Mapping JAVA Journal

</select> public PosizioneVO read(String id) throws


SQLException{
Il tag select specifica la query SQL da utilizzare per la lettura PosizioneVO vo =null;
di un farmaco, utilizzando come parametro di input l’id. La vo =(PosizioneVO)this.sqlMap().
novità è rappresentata dal resultMap che definisce la moda- queryForObject(“posizione.read”,id);
lità con cui mappare il risultato della ricerca. Infatti il tag return vo;
resultMap introduce, per mezzo dei tag result, una lista di }
coppie di attributi (property, column) che servono a trasfor- public void update(PosizioneVO vo) throws
mare le colonne risultato della ricerca nelle proprietà del- SQLException{
l’oggetto istanziato (Figura 2). this.sqlMap().update(“posizione.update”,
vo);
}
Ancora DAO
public void delete(PosizioneVO vo) throws
Supponiamo di voler manipolare i dati per mezzo di classi SQLException{
che definiscono dei DAO (Data Access Object) ad essi as- this.sqlMap().delete(“posizione.delete”,
sociati. Prima, però, è obbligatoria una precisazione: iBatis vo.getId());
contiene già delle API per la definizione dei DAO; nell’ulti- }
ma versione se ne sconsiglia l’uso e si consiglia di utilizzare public ArrayList<PosizioneVO> list(PosizioneVO
quelle fornite dal Framework Spring che prevede delle API vo) throws SQLException{
per iBatis molto curate ed efficienti. Quindi, l’implementa- ArrayList<PosizioneVO> list=null;
zione proposta di seguito serve solo a dare un taglio pratico list=(ArrayList<PosizioneVO>) this.sqlMap()
e didattico alla presentazione delle API di iBatis. .queryForList(“posizione.list” , vo);
Incominciamo a definire una super classe per i nostri return list;
DAO: }
}
public abstract class BaseIBatisDAO {
private static SqlMapClient sqlMap=null; In questo frammento di codice possiamo notare la facilità
protected SqlMapClient sqlMap(){ di utilizzo delle API di iBatis. È sufficiente utilizzare uno
return sqlMap; dei metodi messi a disposizione dalla classe SqlMapClient,
} comporre la stringa che individua la query nel file di map-
ping ed il gioco è fatto. Questa classe è ricca di metodi
public BaseIBatisDAO() throws Exception{ utilizzabili per eseguire i vari tipi di query SQL. Nell’esem-
if(sqlMap==null){ pio, possiamo trovare i metodi insert, update, delete, queryFo-
Reader reader; rObject e queryForList. Tralasciando i primi tre, che specifi-
reader = Resources.getResourceAsReader cano l’utilizzo degli omonimi enunciati SQL, gli ultimi due
(“SqlMapConfig.xml”); introducono l’utilizzo di una Select SQL. Il primo dei due
sqlMap = SqlMapClientBuilder. specifica che il risultato della Select deve essere un solo og-
buildSqlMapClient(reader); getto; mentre il metodo queryForList specifica che il risulta-
} to della query definita nel file XML può ritornare una lista
} di oggetti.
}

Questa superclasse serve ad istanziare un oggetto Sql- iBatis e le transazioni


MapClient e a metterlo a disposizione delle sue sottoclassi.
Questo oggetto viene costruito a partire da un java.io.Reader Finora non abbiamo visto all’opera le API di iBatis che si
ottenuto utilizzando il file SqlMapConfig.xml analizzato in occupano di gestire le transazioni; infatti, nel caso della
precedenza. classe PosizioneDAO non compare mai l’invocazione di pri-
Prendiamo in esame uno dei due DAO di cui dovrebbe es- mitive di commit e rollback. Tutto ciò è dovuto al fatto che
sere fornita la nostra applicazione; dal punto di vista didat- in fase di configurazione nel file SqlMapConfig.xml abbiamo
tico ne basta uno, perché l’implementazione dei due DAO specificato l’auto commit delle operazioni su DB:
è pressoché identica.
<property name=”JDBC.DefaultAutoCommit”
public class PosizioneDAO extends BaseIBatisDAO{ value=”true” />
public PosizioneDAO() throws Exception {
super(); Supponiamo adesso di voler gestire a mano le transazioni:
} questa situazione è molto ricorrente nei casi reali in cui si
public void create(PosizioneVO vo) throws vuole racchiudere sotto un’unica transazione non più sin-
SQLException{ gole operazioni su DB, ma sequenze articolate e complesse
this.sqlMap().insert(“posizione.create”, di transazioni. La prima cosa da fare è di impostare a fal-
vo); se la proprietà JDBC.DefaultAutoCommit. Fatto ciò, vediamo
} come potrebbe presentarsi un metodo che prevede l’inse-

18 n.4 - settembre/ottobre 2007


JAVA Journal Object/Relational Mapping speciale

rimento di due oggetti di tipo PosizioneVO garantendone la Conclusioni


transazionalità.
In questo articolo abbiamo visto i principi di utilizzo di iBa-
public void create(PosizioneVO vo1,PosizioneVO tis e abbiamo abbozzato un esempio pratico per render-
vo2) throws SQLException { ci conto della potenza e della facilità di utilizzo di questo
try { framework. Ovviamente non tutte le funzionalità di iBatis
this.sqlMap().startTransaction(); non sono state snocciolate in questo articolo. Alcuni aspet-
this.sqlMap().insert(“posizione.create”,vo1); ti come il caching, il “lazyloading” e la possibilità di ese-
this.sqlMap().insert(“posizione.create”,vo2); guire query dinamiche non sono stati presi in considera-
this.sqlMap().commitTransaction(); zione, ma tuttavia concorrono a fare di questo framework
}finally{ uno strumento semplice e potente per l’interazione con
this.sqlMap().endTransaction(); basi di dati relazionali.
}
}

Note Biografiche
Anche in questo iBatis si distingue per la sua semplicità;
con startTransaction si demarca l’inizio di una transazione, Roberto Sidoti è Ingegnere Informatico, in passato si è occupato
di servizi VoIP; attualmente lavora come Functional Designer
poi con commitTransaction si effettua il commit delle opera- per Herzum Software, una multinazionale di consulenza spe-
zioni effettuate sul DB. Comunque, alla fine va chiusa la cializzata nello sviluppo di componenti SOA per applicazioni
transazione con endTransaction; nel caso qualcosa non ab- Enterprise.
bia funzionato le operazioni di rollback sono effettuate au-
tomaticamente dal framework.

n.4 - settembre/ottobre 2007 19


speciale Object/Relational Mapping JAVA Journal

JPA: Java
Persistence API
prima parte
Sun Microsystems ha eseguito una radicale rivisitazione della tecnologia di persistenza dei dati
e la nuova specifica, JPA, è una chiara semplificazione che si immette nel solco tracciato dalle
soluzioni per la persistenza più diffuse, tra cui Hibernate, TopLink della Oracle e JDO.

>> di Fabio Staro (fstaro@javajournal.it)

G
li Entity Bean 2.x sono stati la tecno- cifica JPA per la persistenza e l’object relational map-
logia “ufficiale” in ambito Java EE ping, sono classi Java alle quali può essere associato
per la persistenza dei dati. Tuttavia un contesto di persistenza sia in un ambiente managed,
la complessità presente nello svilup- ossia gestito da un Application Server, sia in un am-
po e nel deployment ha fatto prefe- biente non managed, ossia Java standard, senza al-
rire a questi alternative più sempli- cun Application Server. Dalla specifica JPA leggiamo
ci, flessibili e performanti. Nel precedente numero esplicitamente:
di Java Journal abbiamo introdotto la specifica degli
EJB versione 3.0, e in particolare ci siamo soffermati “This document is the specification of the Java API for the
sugli EJB di tipo session stateless. Abbiamo evidenziato management of persistence and object/relational mapping
come per i nuovi EJB la Sun abbia eseguito una rein- with Java EE and Java SE”.
gegnerizzazione della tecnologia, apportando sì nuo-
ve caratteristiche, ma soprattutto introducendo una Questa differenza architetturale caratterizza i nuo-
notevole semplificazione. vi entità, oltre ad una notevole semplificazione nella
In questo articolo ci soffermeremo sui nuovi entity programmazione e nel deployment e a nuove carat-
bean, evidenziando la radicale differenza architettu- teristiche. In questo primo articolo su JPA definiamo
rale presente tra gli entity 3.0 e le precedenti versioni una entity class, il concetto del contesto di persistenza e la
2.x e 1.x. Se fino alla versione 2.1 gli entity bean sono gestione delle relazioni. Nel prossimo articolo appro-
a tutti gli effetti degli EJB legati necessariamente ad fondiremo la gestione dell’ereditarietà ed il supporto
un container EJB, i nuovi entity, descritti nella spe- alle query statiche e dinamiche. Prima di iniziare, os-
serviamo che JPA è una specifica, e pertanto posso-
no esistere diversi provider che la implementano. Tra
questi i più noti sono Hibernate e TopLink.

JPA è una specifica, Una semplice biblioteca


e pertanto possono L’applicazione software che desideriamo realizzare è
esistere diversi provider volutamente semplice, al fine di approfondire l’API e
l’architettura JPA, eliminando qualsiasi complessità
che la implementano applicativa legata ad un particolare dominio di inte-
resse. La Figura 1 riporta il diagramma Entità-Rela-
zioni (ER) di un semplice repository per i libri di una
biblioteca.

20 n.4 - settembre/ottobre 2007


JAVA Journal Object/Relational Mapping speciale

FIGURA 1 Diagramma Entità Relazioni

Osservando la figura, possiamo notare che le entità princi- sione 5.0 [1], con il database MySQL versione 5.0.27 [2] e
pali nel diagramma sono quattro: con il provider JPA Hibernate [3].

• la tabella CASA_EDITRICE, Definizione di un entity


• la tabella INDIRIZZO,
• la tabella LIBRO, Un entity, nella accezione della specifica JPA, è un POJO
• la tabella AUTORE. (acronimo di Plain Old Java Object), ossia è una semplice
classe Java (che non deve implementare interfacce parti-
Le relazioni che intercorrono tra le entità sono le seguen- colari o estendere classi di un particolare framework) i cui
ti: attributi mappano le colonne di una tabella e, in partico-
lare, una istanza della classe rappresenta un ben preciso
• una casa editrice ha un solo indirizzo (relazione 1 a 1) record di una tabella (questo perché una classe entity deve
e può, a sua volta, pubblicare molti libri (relazione 1 a dichiarare una primary key). Il mapping tra la classe entity e
molti); una tabella è semplificato attraverso l’uso delle annotazioni.
Lo stralcio di codice che segue mostra la classe CasaEditrice
• un libro a sua volta appartiene ad una e una sola casa opportunamente annotata:
editrice (relazione molti a uno), e può essere stato
scritto da vari autori @Entity(name=”CasaEditriceEntity”)
; @Table(name=”CASA_EDITRICE”)
• un autore, a sua volta, può scrivere diversi libri (rela- public class CasaEditrice implements
zione molti a molti). Serializable
{
Attraverso un processo di realizzazione del tipo bottom-up, …
ossia partendo dal disegno del database e derivando da @Id
questo il modello delle classi, è possibile modellare le enti- @GeneratedValue(strategy=GenerationType.AUTO)
tà di dominio ottenendo il diagramma delle classi riporta- @Column(name=”id_ce”)
to in Figura 2. Le classi mostrate nella Figura 2 non sono, private int identificativo;
ovviamente, le uniche classi dell’applicazione, ma rappre- private String ragioneSociale;
sentano le classi del modello dati e sono in definitiva le en- private String telefono;
tità che devono essere rese persistenti nel database. private String fax;
Le operazioni di business dell’applicazione sono modellate private String email;
attraverso degli EJB 3.0 di tipo session stateless. L’esempio ri- …
portato è stato verificato con l’application server JBoss ver- }

n.4 - settembre/ottobre 2007 21


speciale Object/Relational Mapping JAVA Journal

FIGURA 2 Il diagramma delle classi

Osserviamo in dettaglio il codice riportato. Attraverso l’an- bella. Pertanto una entity class deve avere una primary key.
notazione @Entity, presente nel package javax.persistence Nel codice della classe CasaEditrice l’attributo identificativo
informiamo il provider dei servizi JPA che la classe CasaE- è la chiave primaria dichiarata ed è identificata attraverso
ditrice è una classe entity. L’attributo facoltativo name con- l’annotazione @Id. In casi complessi, la chiave primaria di
sente di specificare un nome attraverso il quale è possibile una entity class può essere un intero oggetto. JPA attraverso
referenziare la classe entity nelle query. Se l’attributo name l’annotazione @IdClass consente di dichiarare una classe
non è specificato assume il valore di default, che è il nome come chiave primaria.
non qualificato della classe. L’ultima annotazione nel codice precedente è l’annotazio-
Attraverso l’annotazione @Table possiamo informare il ne @GeneratedValue. Attraverso questa annotazione è pos-
provider dei servizi JPA su quale tabella presente nel data- sibile definire la regola di generazione per una chiave pri-
base relazionale è mappata dalla entity class (notiamo che è maria. Per esempio, avendo scritto:
possibile specificare oltre all’attributo name, anche gli attri-
buti schema e catalog per meglio “identificare” la tabella). strategy=GenerationType.AUTO
L’annotazione @Column consente di mappare un attribu-
to della classe su una colonna della tabella. Nel codice pre- il provider JPA assume che la regola di generazione del va-
cedente l’attributo identificativo della classe CasaEditrice è lore della chiave primaria dipenda dal database utilizzato.
mappato sulla colonna id_ce della tabella CASA_EDITRI- Ad esempio, con il database MySQL una strategia di ge-
CE. È importante sottolineare che se non avessimo specifi- nerazione impostata al valore AUTO indica che la colonna
cato la annotazione @Column, come è stato fatto ad esem- sulla tabella è del tipo AUTO_INCREMENT. Altri possibili
pio per gli attributi ragioneSociale, telefono, fax ed email, si ha valori presenti nella enumerazione GenerationType sono:
la mappatura automatica dell’attributo di classe su una co-
lonna omonima della tabella (un esempio di configuration • SEQUENCE,
by exception). In effetti, per indicare al provider dei servizi • IDENTITY,
JPA che un attributo di una entity class non deve essere reso • TABLE.
persistente questo deve essere annotato con l’annotazione
@Transient. I valori SEQUENCE e IDENTITY indicano l’uso di una se-
Precedentemente abbiamo evidenziato come una istanza quence nel database o di una colonna identità come stra-
di una entity class rappresenti un preciso record di una ta- tegia di generazione della chiave primaria, mentre il valo-

22 n.4 - settembre/ottobre 2007


JAVA Journal Object/Relational Mapping speciale

re TABLE indica che il provider JPA deve assegnare valori sincronizzazione che avviene al commit della transazione.
univoci usando una tabella del database. In effetti è possibile affermare che l’istanza della entity class
è nello stato managed (più avanti dettaglieremo maggior-
mente il ciclo di vita di una entity class). L’istanza rimane
Il Persistence Context nello stato managed fino a quando non termina il persisten-
ce context o fino a quando l’istanza non è esplicitamente ri-
La logica di business della applicazione di esempio è mo- mossa.
dellata attraverso EJB 3.0 di tipo session stateless. Per esem- Il persistence context associato ad un EntityManager può es-
pio, l’EJB GestoreCasaEditriceBean ha una serie di metodi per sere di due tipi (dichiarati nella enumerazione Persitence-
la gestione di una casa editrice. Di seguito riportiamo uno ContextType):
stralcio del codice:
• TRANSACTION;
@Stateless (name=”CasaEditrice”) • EXTENDED;
@TransactionManagement(TransactionManagementType.
CONTAINER) Un persistence context di tipo TRANSACTION termina quan-
public class GestoreCasaEditriceBean implements do si conclude la transazione all’interno della quale sono
GestoreCasaEditrice eseguite le operazioni. Da quel momento in poi tutte le
{ istanze delle entity class non sono più nello stato managed,
… e pertanto non vi è sincronizzazione tra le modifiche che
@PersistenceContext(type=PersistenceContext- avvengono sulla istanza in memoria ed il database. Un per-
Type.TRANSACTION,unitName=”GestioneBiblioteca”) sistence context di tipo EXTENDED termina quando viene ri-
private EntityManager manager = null; mossa dal container l’istanza dell’EJB di tipo stateful all’in-
terno della quale è dichiarato. Le istanze delle entity class, in
public boolean inserisci(CasaEditrice ce) tale contesto, rimangono nello stato managed durante le in-
{ vocazioni successive dei metodi di uno stateful session EJB.
try
{
manager.persist(ce);
Ciclo di vita di un entity
}
catch(Exception e) Il diagramma degli stati riportato in Figura 3 sintetizza il
{ ciclo di vita di un entity. L’Entity Manager distingue quattro
return false; diversi stati durante la vita di un entity:
}
return true; • New;
} • Managed;
• Detached;
public CasaEditrice getCasaEditrice(int • Removed.
identificativo)
{ Quando viene creata, una istanza della classe entity si tro-
return manager.find(CasaEditrice.class, va nello stato new, ossia l’istanza è presente in memoria
identificativo); ma non è associata ad un contesto di persistenza. Pertanto, le
} variazioni dei valori degli attributi dell’istanza non sono
… sincronizzate con il database. Un entity nello stato new,
} dopo l’invocazione sull’Entity Manager di una operazione
di persist(), transita nello stato managed e diviene associata
Osservando il codice sopra riportato osserviamo che le ope- ad un contesto di persistenza, avendo una ben precisa identi-
razioni di persist() (di fatto una operazione di insert sul da- tà di persistenza determinata dalla corrispondente chiave
tabase) e di find() (operazione di ricerca) sono invocate su primaria. In questo stato, le variazioni dei valori degli attri-
un oggetto EntityManager iniettato nel bean GestoreCasaE- buti dell’istanza sono sincronizzate con il database quando
ditriceBean dal container EJB. L’annotazione @Persistence- la transazione è sottoposta al commit o quando il processo
Context consente di dichiarare il contesto di persistenza (si di sincronizzazione viene richiesto direttamente attraver-
veda anche più avanti dove parliamo del deployment del- so il comando flush(). Un’istanza nello stato managed tran-
l’applicazione). Il contesto di persistenza è la connessione sita nello stato detached quando termina il contesto di persi-
tra le istanze delle entity class che risiedono in memoria e stenza. Nello stato detached l’istanza ha ancora una identità
il database sottostante, ed è gestito attraverso una nuova di persistenza ma, non essendo più associata con un contesto
API, l’interfaccia EntityManager sempre presente nel packa- di persistenza, non sincronizza variazioni dei suoi attributi
ge javax.persistence. con il database. Infine, una istanza della entity class, a fron-
Attraverso il metodo persist() aggiungiamo una istanza di te di una operazione di remove(), transita dallo stato ma-
una entity class al persistence context e da quel momento in naged allo stato removed. In questo stato l’istanza è ancora
poi tutte le modifiche che avvengono sullo stato della entity associata ad un contesto di persistenza, ma viene schedulata
class sono schedulate per la sincronizzazione sul database, un’operazione di cancellazione sul database per il record

n.4 - settembre/ottobre 2007 23


speciale Object/Relational Mapping JAVA Journal

FIGURA 3 Ciclo di vita di un entity

da questa rappresentato. solo record in relazione con un altro record. Nel model-
lo dei dati dell’esempio è la relazione che esiste tra una
Di seguito riportiamo i metodi principali presenti nell’in- casa editrice e il suo indirizzo;
terfaccia dell’Entity Manager, direttamente inerenti al ci-
clo di vita di un entity: • Uno a molti: la relazione indica che un particolare re-
cord è in relazione con molti altri record. Nel modello
public interface EntityManager dei dati dell’esempio è la relazione che intercorre tra
{ una casa editrice e i libri da questa pubblicati. Infatti,
… una casa editrice pubblica molti libri;
// Fa transitare un’istanza nello stato
managed e persistente • Molti a uno: la relazione indica che molti record sono
public void persist(Object entity); in relazione con un solo particolare record. Nel model-
lo dei dati dell’esempio è la relazione tra i libri e la casa
// Esegue il merge dello stato di un entity in editrice che li pubblica;
un contesto di persistenza.
public <T> T merge(T entity); • Molti a molti: la relazione indica che molti record sono
in relazione con molti altri record. Nel modello dei dati
// Rimuove un’istanza dal database dell’esempio è la relazione che esiste tra un libro e i
public void remove(Object entity); suoi autori. Infatti, un libro può essere scritto da più
autori, e un autore, viceversa, può scrivere vari libri.
// Controlla se un dato entity è presente nel
contesto di persistenza corrente Inoltre, le relazioni possono essere unidirezionali o bidirezio-
public boolean contains(Object entity); nali. Nel caso unidirezionale solo l’entità proprietaria della re-
… lazione è a conoscenza della relazione, mentre in una rela-
} zione bidirezionale entrambe le entità ne sono a conoscenza.
Ad esempio, nel diagramma delle classi riportato in Figu-
ra 2 la relazione che esiste tra una casa editrice e il suo in-
La gestione delle relazioni dirizzo è stata modellata come unidirezionale, e pertanto,
data una casa editrice è possibile ricavare il suo indirizzo e
Il supporto per la gestione delle relazioni è presente fin non il viceversa; mentre la relazione tra una casa editrice e
dalla specifica 2.0 degli EJB di tipo Entity. Con gli EJB 3.0 i libri da questa pubblicati è modellata come bidirezionale
la gestione delle relazioni è stata notevolmente semplifica- in quanto, data una casa editrice, è possibile ricavare i libri
ta attraverso l’uso delle annotazioni. I tipi di relazione che da questa pubblicati, e dato un libro, è possibile conoscere
è possibile modellare tra le entity class sono: la casa editrice che lo ha pubblicato.
Iniziamo con l’analizzare uno stralcio del codice sorgente
• Uno a uno: la relazione indica che vi è esattamente un della classe CasaEditrice dove è presente la relazione uno a

24 n.4 - settembre/ottobre 2007


JAVA Journal Object/Relational Mapping speciale

uno unidirezionale con la classe Indirizzo: l’elemento cascade per default non vi è alcuna propagazione
delle operazioni di persistenza tra le entità correlate. L’ele-
@Entity(name=”CasaEditriceEntity”) mento fetch nella annotazione @OneToOne può assumere i
@Table(name=”CASA_EDITRICE”) valori presenti nella enumerazione javax.persistence.FetchTy
public class CasaEditrice implements Serializable pe che sono:
{

@OneToOne(cascade=CascadeType.ALL,fetch=FetchT
ype.EAGER,targetEntity=Indirizzo.class)
@JoinColumn(name=”indirizzo”, referencedColumn
Name=”id_ indirizzo”)
private Indirizzo indirizzo = null;

public Indirizzo getIndirizzo() {


Una entity class deve
return indirizzo;
} avere una primary key
public void setIndirizzo(Indirizzo indirizzo)
{
this.indirizzo = indirizzo;
}

}

La relazione uno a uno che esiste tra una casa editrice e il • EAGER;
suo indirizzo è dichiarata attraverso l’annotazione @One- • LAZY;
ToOne. Prima di esaminare nel dettaglio gli elementi casca-
de, fetch e targetEntity valorizzati nella dichiarazione del- In una relazione uno a uno, il valore di default dell’ele-
la annotazione, analizziamo l’annotazione @JoinColumn. mento fetch è EAGER, mentre sarà LAZY nelle relazioni
Questa annotazione, consente di definire la colonna che uno a molti e molti a molti. Il valore EAGER per l’elemen-
funge da foreign key (ossia da chiave esterna). In particola- to fetch indica che le entità correlate vengono caricate as-
re, attraverso l’elemento name dell’annotazione è possi- sieme (una sorta di caricamento anticipato); viceversa, il
bile specificare il nome della colonna che è la foreign key, valore LAZY indica che le entità correlate vengono caricate
mentre con l’elemento referencedColumnName si specifica il solo quando è necessario (una forma di caricamento diffe-
nome della colonna (presente nella tabella correlata) refe- rito). La scelta della modalità di caricamento delle entità
renziata dalla foreign key. L’elemento cascade presente nel- ha un impatto rilevante sulle prestazioni dell’applicazione.
l’annotazione @OneToOne può assumere i valori definiti La modalità di caricamento EAGER è generalmente meno
nella enumerazione javax.persistence.CascadeType e sono: efficiente, in quanto comporta il caricamento in memoria
dell’intera mappa delle relazioni. Ad esempio, osserviamo
• ALL; il diagramma delle classi e il diagramma Entità/Relazioni
• PERSIST; del nostro esempio: se per tutte le entità correlate la politi-
• MERGE; ca di caricamento fosse impostata al valore EAGER, allora
• REMOVE; una semplice query di ricerca di una casa editrice compor-
• REFRESH; terebbe il caricamento anche dell’indirizzo e, soprattutto,
di tutti i libri da questa pubblicati; e per ogni libro si avreb-
Specificare be il caricamento degli autori. Si intuisce facilmente che
impostare tutte le relazioni al valore EAGER porta facil-
cascade={CascadeType.ALL} mente ad un degrado delle prestazioni! Se si sta operando
su un insieme di entità all’interno di un persistence context
è equivalente ad aver specificato attivo, come politica di caricamento è normalmente più ef-
ficiente il valore LAZY. Inoltre, è possibile, attraverso l’uso
cascade={CascadeType.PERSIST, CascadeType.MERGE, delle fetch join (argomento che approfondiremo nel prossi-
CascadeType.REMOVE, CascadeType.REFRESH} mo articolo), personalizzare la modalità di caricamento delle
entità con un maggiore livello di granularità (di fatto, caso
L’elemento cascade indica il tipo di operazione che deve es- per caso, attraverso query specifiche). Nello precedente
sere “propagata” sulla entità correlata. Ad esempio, se l’en- stralcio di codice l’annotazione @OneToOne è anche carat-
tità correlata (che nel nostro esempio è la classe Indirizzo) terizzata dall’elemento facoltativo targetEntity. Attraverso
assume il valore PERSIST, questa viene resa persistente questo elemento è possibile specificare la classe dell’entità
sul database nel momento in cui si invoca il metodo per- correlata, che nel codice riportato è la classe Indirizzo. Il più
sist() dell’Entity Manager per l’entità owner della relazione delle volte questo elemento può essere omesso, poiché la
(nel nostro caso la classe CasaEditrice). Se non si specifica classe dell’entità correlata viene ricavata dal provider JPA

n.4 - settembre/ottobre 2007 25


speciale Object/Relational Mapping JAVA Journal

dall’analisi del tipo dell’attributo di relazione (nel prece- mappedBy. Attraverso questo elemento indichiamo la pro-
dente stralcio di codice, l’elemento targetEntity può essere prietà owner della relazione, che nell’esempio è l’attributo
in effetti omesso). Tuttavia, l’elemento targetEntity è neces- casaEditrice presente nella classe della entità correlata, la
sario se, ad esempio, come tipo dell’attributo di relazione classe Libro. Nella dichiarazione della annotazione @One-
non si specifica la classe dell’entità correlata ma, ad esem- ToMany è omesso l’elemento targetType, in quanto, grazie
pio, l’interfaccia da questa implementata. all’uso dei generics, è possibile dichiarare esplicitamente il
La classe CasaEditrice ha una relazione bidirezionale uno a tipo dell’insieme di oggetti correlati ad una casa editrice
molti con la classe Libro. Di seguito riportiamo uno stralcio (Collection<Libro>).
del codice sorgente della classe Libro: Per concludere la panoramica sui tipi di relazioni, analiz-
ziamo la relazione bidirezionale molti a molti tra le entità
@Entity(name=”LibroEntity”) Libro e Autore. Di seguito è riportato uno stralcio del codice
@Table(name=”LIBRO”) della classe Libro:
public class Libro implements Serializable
{ @Entity(name=”LibroEntity”)
… @Table(name=”LIBRO”)
@ManyToOne(cascade=CascadeType.ALL, public class Libro implements Serializable
fetch=FetchType.EAGER) {
@JoinColumn(name=”casaEditrice”, …
referencedColumnName=”id_ce”) @ManyToMany(mappedBy=”libri”,
private CasaEditrice casaEditrice = null; cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private Set<Autore> autori = null;
public CasaEditrice getCasaEditrice() {
return casaEditrice; public Set<Autore> getAutori()
} {
public void setCasaEditrice(CasaEditrice return autori;
casaEditrice) { }
this.casaEditrice = casaEditrice;
} public void addAutore(Autore autore) {
… if (null==autori) autori=new
} HashSet<Autore>();
if (!autori.contains(autore))
e della classe CasaEditrice: {
autori.add(autore);
@Entity(name=”CasaEditriceEntity”) autore.addLibro(this);
@Table(name=”CASA_EDITRICE”) }
public class CasaEditrice implements Serializable }
{ …
… }
@OneToMany(mappedBy=”casaEditrice”,
cascade=CascadeType.ALL, fetch=FetchType.EAGER) e della classe Autore:
private Collection<Libro> libri = null;
@Entity(name=”AutoreEntity”)
public Collection<Libro> getLibri() { @Table(name=”AUTORE”)
return libri; public class Autore implements Serializable
} {
public void addLibro(Libro libro) { …
if (this.getLibri() == null) @ManyToMany(cascade=CascadeType.ALL,
this.libri = new ArrayList<Libro>(); fetch=FetchType.EAGER)
libro.setCasaEditrice(this); @JoinTable(name=”LIBRO_AUTORE”,
this.getLibri().add(libro); joinColumns={@JoinColumn(name=”autore_
} id”,referencedColumnName=”id_autore”)},
… inverseJoinColumns={@JoinColumn (name=”libro_
} id”, referencedColumnName=”id”)}
private Set<Libro> libri = null;
Osserviamo il codice della classe Libro. La relazione mol-
ti a uno con la classe CasaEditrice è esplicitata attraverso public void addLibro(Libro libro)
l’uso dell’annotazione @ManyToOne. Poiché la relazio- {
ne tra le due entità è bidirezionale, osservando il codice if (null == libri) libri=new
della classe CasaEditrice notiamo, come si può intuire, la HashSet<Libro>();
presenza dell’annotazione @OneToMany. In questa classe, if (!libri.contains(libro))
oltre agli elementi cascade e fetch, è dichiarato l’elemento {

26 n.4 - settembre/ottobre 2007


JAVA Journal Object/Relational Mapping speciale

Analizziamo i tag XML di una persistence unit:

• <description>: un testo opzionale

Il supporto per la • <provider>: nome qualificato della classe del provider,


nel nostro caso Hibernate, che implementa la specifica
JPA;
gestione delle relazioni • <transaction-type>: attributo del tag <persistence-unit>.
JTA è il valore di default altrimenti può assumere il va-
lore RESOURCE_LOCAL;
è presente fin dalla • <jta-data-source>: nome JNDI del datasource;
• <non-jta-data-source>: nome JNDI del datasource;
specifica 2.0 degli EJB • <mapping-file>: file XML, in alternativa alle annota-
zioni, dove specificare le regole di mapping per le entity
class;
di tipo Entity • <jar-file>: archivio dove cercare le entity class disponibi-
li per la persistence unit;
• <class>: le classi disponibili per la persistence unit;
• <exclude-unlisted-classes>: se questo elemento è presen-
te solo le entity class o gli archivi definiti con i tag map-
ping-file, jar-file e class sono disponibili nella persistence
unit;
• <properties>: proprietà specifiche del provider JPA.
libri.add(libro);
libro.addAutore(this);
}
Conclusioni
}
In questo primo articolo abbiamo trattato i fondamenti
public Collection<Libro> getLibri() della specifica JPA. Nel prossimo articolo parleremo del-
{ la gestione dell’ereditarietà e delle query statiche e dina-
return libri; miche.
}

}
Riferimenti

La relazione molti a molti è esplicitata attraverso l’uso del- [1]: http://www.jboss.com/


l’annotazione @ManyToMany. Osserviamo che nella classe [2]: http://www.mysql.com/
Autore attraverso la annotazione @JoinTable è possibile spe- [3]: http://www.hibernate.org/
cificare la tabella associativa che di fatto realizza la relazio-
ne nello schema Entità/Relazioni di Figura 1.
Bibliografia:

Il deployment dell’applicazione [4] R. P. Sriganesh, G. Brose, M. Silverman


“Mastering Enterprise JavaBeans 3.0”, Wiley Publishing,
Le entity class sono raccolte in persistence unit. Una persisten- Inc., 2006.
ce unit è una unità logica di entity class, con i metadati per
il mapping e le configurazioni specifiche per il database ed [5] R. R. Kodali, J. Wetherbee e P. Zadrozny
il provider JPA. Una persistence unit è definita in un file de- “Beginning EJB 3 Application Development”, Apress, 2006.
scrittore chiamato persistence.xml che deve essere presente
nella cartella META-INF di un archivio jar o di un archivio
war o ear. Di seguito riportiamo il file persistence.xml del-
l’esempio della gestione della biblioteca:

<persistence>
Note Biografiche
<persistence-unit name=”GestioneBiblioteca”>
<jta-data-source>java:/theDataSource</jta- Jacopo Giudici si occupa di applicazioni per il Web, di RFID e di
domotica su piattaforme J2ME, J2EE e .NET. Progetta e tiene
data-source> corsi di formazione aziendali sulla sicurezza delle reti informa-
<provider>org.hibernate.ejb.HibernatePersistence tiche e sulla programmazione Java per ambienti distribuiti.Ha
</provider>
lavorato per Microsoft, BottegaVerde, CONAD, Confartigiana-
to e ha pubblicato una collana di 6 libri con DeAgostini Scuola
</persistence-unit> sui Sistemi Elettronici-Informatici per il triennio degli istituti
</persistence> tecnici superiori.

n.4 - settembre/ottobre 2007 27


ORIZZONTI
FREESPEECH ENTERPRISE Login Topic

Tutto ciò che è tendenza nel


mondo JEE
>> di Fabio Staro (fabio.staro@javajournal.it)

Un “mezzo di trasporto”… per SOA: l’Enterprise § il protocollo di interazione;


Service Bus § l’interfaccia del servizio;

Nel precedente numero abbiamo definito una architettura a Il primo punto è possibile in quanto i consumatori (requester)
servizi (SOA) e alcune tecnologie correlate a questo paradigma ed i fornitori (provider) di un servizio non sono accoppiati in
di sviluppo (Web Service e BPEL). In questo numero introdu- una relazione punto a punto, ma l’interazione è mediata dallo
ciamo il concetto di Enterprise Service Bus (ESB), evidenziando- Enterprise Service Bus. Ad esempio, un servizio può essere eroga-
ne il ruolo, fondamentale, in una infrastruttura enterprise co- to da uno o più fornitori e questi possono essere aggiunti o ri-
struita sul modello SOA. mossi in modo trasparente al consumatore del servizio. L’astra-
zione rispetto al protocollo di interazione (protocol switch) è
Un ESB è un prodotto di integrazione che funge da collante tra i possibile in quanto i partecipanti ad una interazione non de-
fornitori di servizi ed i consumatori in un ambiente eterogeneo sia vono necessariamente condividere il medesimo protocollo di
per le tecnologie sia per i protocolli di comunicazione (Figura 1). At- comunicazione. Per esempio, un messaggio può essere invia-
traverso l’uso di un ESB è possibile “astrarre”: to nel bus come richiesta di tipo Web service, basata sul proto-
collo SOAP su HTTP, e poi la richiesta è risolta da un fornitore
§ la localizzazione e l’identità dei fornitori dei servizi; che comunica attraverso il protollo RMI (Java Remote Method

FIGURA 1 Architettura di un Enterprise Service Bus, mediatore tra i requester ed i provider di servizi.

29 n.4 - settembre/ottobre 2007


FREEORIZZONTI
SPEECH ENTERPRISE Login Topic

Invocation). Il terzo punto, ossia l’astrazione rispetto alla in- § notifica un messaggio ai diversi listener registrati (interazione
terfaccia di un servizio, è possibile poiché i fornitori di un ser- del tipo publish-subscribe);
vizio ed i consumatori di questo non devono necessariamen- § gestisce la sicurezza nelle comunicazioni (autorizzazione del-
te condividere la medesima interfaccia. L’Enterprise Service Bus le richieste, encryption e decryption del contenuto dei messag-
“riconcilia” e “media” le differenze, trasformando i messag- gi, ecc.).
gi inviati al bus in una forma corretta per il fornitore del ser-
vizio. Ad esempio, attraverso una trasformazione XSLT è pos- Inoltre, un ESB, mediando la comunicazione tra i fornitori ed i
sibile trasformare un messaggio che soddisfa lo schema di un consumatori, può garantire servizi di monitoring, auditing au-
consumatore in un messaggio che rispetti lo schema di un for- tomatico, affidabilità nella consegna dei messaggi, ecc.
nitore del servizio. Concludendo: le soluzioni di Enteprise Application Integra-
tion (EAI) sono state, anche nel recente passato, caratterizza-
Ma quali sono i servizi minimi che deve fornire un Enterprise te da soluzioni basate su tecnologie non standard e proprietarie
Service Bus? (vendor lock-in). Viceversa, un Enterprise Service Bus è un prodot-
to per l’integrazione basato su standard di mercato (JMS, JMX,
Questi possono essere facilmente ricordati grazie all’acronimo SOAP, WSDL, XSLT, XQuery, XPath, ecc.) e su un’architettura
TRANS definito da Jeff Hanson [1]. TRANS sta per: orientata ai servizi. Tuttavia, la Java Community propone un ul-
teriore e sostanziale salto di qualità. Attraverso la proposta della
§ Transforming; specifica JBI (Java Business Integration) [2], è possibile creare
§ Routing; una serie di componenti che possono essere usati con un qual-
§ Augmenting; siasi ESB aderente allo standard. In sintesi, JBI definisce il con-
§ Notifying; tratto che esiste fra un ESB ed i componenti che l’ESB gestisce.
§ Securing. Nel prossimo numero ritorneremo a parlare della specifica JBI
e analizzeremo come potrà evolvere il modo di fare integrazio-
Infatti un Enterprise Service Bus: ne in ambito JEE.

§ trasforma i messaggi da un formato in un altro per soddisfa-


re l’interfaccia esposta dal provider di servizi; Bibliografia
§ gestisce il routing dei messaggi verso i diversi fornitori, ga-
rantendo allo stesso tempo la qualità del servizio (QoS,
acronimo di quality of service); [1]: Jeff Hanson, Implementing an Enterprise Service Bus in Java
§ arricchisce (augmenting) il contenuto di un messaggio con in- http://www.devx.com/Java/Article/28127
formazioni provenienti da sorgenti dati esterne (per esem- [2]: JSR 208: Java Business Integration
pio un database); http://jcp.org/en/jsr/detail?id=208)

n.1 - novembre/dicembre 2006 30


educational JAVA Journal

Xp e dintorni
Troppo spesso lo sviluppo del software è un’attività caotica. Per ovviare a ciò sono nati i metodi
ingegneristici, spesso troppo articolati e burocratici. L’esigenza di approcci più agili ha portato alla
Extreme Programming (XP). Da alcuni percepita in contrapposizione al RUP, in origine ha
diviso il cosmo degli sviluppatori tra entusiasti e scettici.
Ma forse le cose non sono così semplici e distinte…

>> di Andrea Zoleo (azoleo@javajournal.it)

I
n questo articolo vedremo come si è giunti alla La reazione
nascita delle metodologie agili di sviluppo ed in
particolare all’Extreme Programming (XP). Da- Il concetto di metodo ingegneristico (plan-driven)
remo un rapido sguardo ai principi e ai valori, consiste in una procedura disciplinata nella realizza-
alle pratiche e alle fasi che contraddistinguo- zione di un progetto software che persegue il fine di
no questa metodologia di sviluppo. Infine, con- rendere questa attività maggiormente prevedibile ed
fronteremo l’XP con altre metodologie: l‘intramon- efficiente.
tabile RUP (Rational Unified Process), la metodolo- Inizialmente si accostò il processo di sviluppo del
gia Iconix e la nascente CoRE (Community-oriented software a quelli caratteristici dell’ingegneria civi-
Real-time Engineering). le o meccanica. Questi metodi enfatizzavano l’im-
portanza di formulare un progetto preciso prima di
costruire. Questo approccio, quando riferito alla co-
In origine regnava il caos struzione del software, viene detto waterfall (a casca-
ta), in quanto tutto il processo, dalla progettazione
Il più primitivo fra i metodi di sviluppo è il cosiddet- alla messa in opera, viene percorso una sola volta. La
to code & fix (scrivi e correggi). Il software viene scrit- maggior parte dell’attività creativa è svolta dai pro-
to, eseguito e corretto senza seguire un processo di gettisti, mentre la fase di costruzione e di test può es-
sviluppo preciso (Figura 1). Di volta in volta si ri- sere portata avanti anche da personale non dotato di
solvono i problemi che si presentano puntando sol- una particolare capacità progettuale.
tanto ad avere un programma che svolge il compito Tuttavia, da questo approccio nasce una domanda
momentaneamente in esame. Mancando di una vi- fondamentale: si riesce, nella progettazione del sof-
sione di insieme, questo approccio è sostenibile per tware, ad ottenere un progetto che sia in grado di ri-
software di piccole dimensioni, ma non appena il si- durre la realizzazione del codice ad un’attività preve-
stema cresce, diventa più difficile aggiungere nuo- dibile? E se sì, la realizzazione di questo progetto è
ve funzionalità senza corrompere le vecchie o dover sufficientemente economica da essere vantaggiosa?
correggere i bachi che immancabilmente emergono. Nell’ingegneria civile, infatti, i costi e i tempi di pro-
In assenza di un metodo fondato su pratiche, anche gettazione sono nettamente minori rispetto a quel-
un programmatore esperto incorre in grossi proble- li di realizzazione dell’opera (in un rapporto di circa
mi non appena cerca di integrare il suo lavoro con uno a dieci).
quello di altri sviluppatori, o quando deve reagire al Ebbene, nello sviluppo del software le cose non van-
cambiamento dei requisiti del cliente. Per progetti di no affatto così. La fase di progettazione è, nella mi-
dimensioni apprezzabili diventa necessario un meto- gliore delle ipotesi, paragonabile per tempi e costi a
do di gestione del ciclo di vita di un progetto softwa- quella di realizzazione. Realizzare un progetto, an-
re che armonizzi gli aspetti di analisi dei requisiti, di che tramite strumenti specifici come quelli forniti
progettazione, di implementazione, di test, di collau- dall’approccio RUP, che tenga conto di tutte le pro-
do e di manutenzione del prodotto realizzato. In uno blematiche e le insidie di implementazione è presso-
scenario come questo, il codice eseguibile è solo uno ché impossibile. Inoltre, chiunque scriva del codice
dei prodotti, forse il più importante, ma di sicuro non di una certa qualità, sa come anche il singolo metodo
è l’unico. vada in qualche modo progettato localmente.

32 n.4 - settembre-ottobre 2007


JAVA Journal educational

Agilità

Per un lungo periodo di tempo si è


cercato di applicare i metodi inge-
gneristici, senza che si dimostras-
sero mai terribilmente efficienti.
Anzi, sono diventati ben presto
meno che popolari. Il loro aspetto
meno sopportabile è senza dubbio
la mole di scartoffie prodotte che
soffoca il progetto, fino al punto
di rallentarlo invece che agevolar-
lo. Questa massa di documenti di
progettazione è il risultato del ten-
tativo di progettare a priori tutti
gli aspetti di un’attività impreve-
dibile.
I metodi agili si pongono come
FIGURA 1 La filosofia alla base del metodo “code & fix” è ben compromesso fra l’assenza di un
raffigurata in questa vignetta. Si prova e riprova fino ad ottenere il
processo e l’eccesso di processo.
risultato cercato. Se l’obiettivo è critico, il prezzo da pagare è spesso
troppo alto. La nascita delle metodologie agili
coincide con il periodo di diffusio-
ne massiccia di Internet alla fine
degli anni 1990, quando la produzione del software ha su-
bito un drastico cambiamento, passando da un ciclo di vita
dell’ordine degli anni a quello dell’ordine dei mesi. I meto-
di agili sono meno orientati ai documenti di progettazione
Per un team di sviluppo, e si concentrano maggiormente sulla chiarezza del codice
e dei relativi commenti.
restare agganciato a Tuttavia sono altre due le differenze sostanziali dei metodi
agili rispetto ai metodi precedenti. La prima è che i meto-
tecnologie obsolete per di agili sono adattativi invece che predittivi. I metodi inge-
gneristici cercano di prevedere una larga parte del proces-
so di sviluppo del software con un buon dettaglio. Questa
la paura di provarne di previsione ha un valore tanto maggiore quanto maggiore
è la tendenza dei requisiti a restare immutati dal momen-
nuove, significa non to della progettazione a quello del rilascio. Per questa ra-
gione questi metodi tendono a resistere il più possibile al-
essere mai produttivo, l’aggiunta di cambiamenti dopo la fase di raccolta dei re-
quisiti.
ma sempre sulla rampa Tuttavia, come già menzionato da Kent Beck “Tutto cambia
nel software. I requisiti cambiano. La progettazione cambia. Gli
iniziale della curva di aspetti commerciali cambiano. La tecnologia cambia. I membri
del team cambiano. Il problema non è il cambiamento di per sé,

apprendimento. perché i cambiamenti avverranno; il problema, piuttosto, è l’ina-


bilità di far fronte ai cambiamenti quando essi avvengono”. L’im-
portanza di ammortizzare i cambiamenti si comprende
bene confrontando la Figura 2 (costi classici) e la Figura
3 (costi agili).
I metodi agili puntano a realizzare un processo di svilup-
po propenso ai cambiamenti, fino al punto di mutare sé
stesso se necessario. La seconda differenza è che i meto-
Queste e altre considerazioni simili portano ad un cambio di agili sono orientati alla persona invece che al processo.
radicale di prospettiva che suggerisce che il codice sorgente Lo scopo dei metodi ingegneristici è definire un processo
sia esso stesso un documento di progettazione. che funzioni indipendentemente da chi siano coloro che
La fase analoga alla costruzione in ingegneria civile sareb- lo praticano, al fine di renderlo robusto al cambiamento
be, dunque, per lo sviluppo del software, la compilazione e delle risorse umane impiegate. Al contrario, le metodolo-
il linking. Quindi, nello sviluppo del software la costruzio- gie agili asseriscono che non esiste processo che possa so-
ne è gratis: quasi tutto è progettazione creativa, quasi nulla stituire le competenze del gruppo di sviluppo. Il processo
è totalmente prevedibile. Non c’è molto spazio per il perso- deve limitarsi ad assistere e supportare il team nel miglior
nale con scarsa inclinazione alla progettazione. modo possibile.

n.4 - settembre-ottobre 2007 33


educational JAVA Journal

ti del team stesso. Questa comunicazione


deve essere mantenuta per tutta la durata
del progetto. Ad esempio, l’interazione fra
cliente e il team di sviluppo non deve inter-
rompersi dopo la fase di raccolta dei requisi-
ti.

§ Feedback. La verifica continua dei ri-


sultati ottenuti (e di quelli mancati) è un
aspetto fondamentale. Permette di tarare i
criteri di giudizio dei tempi e dei costi per le
fasi successive del progetto. Avvicina il pun-
to di vista del cliente e del team di sviluppo,
spingendoli a collaborare per la realizzazio-
ne di uno scopo comune, invece di arroc-
carsi su posizioni inamovibili e contrappo-
FIGURA 2 Diagramma dei costi “classici” ste. Evita che il team di sviluppo si allontani
dalla “retta via” sviluppando soluzioni che
hanno poco interesse per il cliente, e aiuta il
cliente a capire quali sono le richieste tecnologicamen-
La nascita dell’XP te ragionevoli e quali non lo sono.

Durante la prima fase di notorietà dei metodi agili, alla § Semplicità. Nel caso dei sistemi informatici, la semplici-
fine degli anni 1990, il metodo detto Extreme Programming tà non è solo un fattore che rende migliore un sistema
fu quello che raggiunse la maggiore popolarità. Le radici rispetto ad un altro. Spesso è un fattore determinante
dell’XP risalgono alla comunità Smalltalk, ed in partico- per il funzionamento del sistema. L’XP impone sempre
lare alla stretta collaborazione fra Kent Beck e Ward Cun- di mantenere i requisiti minimi necessari per coprire
ningham alla fine degli anni 1980. Entrambi raffinarono le le richieste del cliente. Ogni complessità aggiunta per
proprie strategie in numerosi progetti nei primi anni 1990, motivi teorici o estetici è un inutile orpello che prima o
estendendo le loro idee su uno sviluppo del software basa- poi ci si rivolterà contro. Ciò non vuole dire che l’XP ri-
to sulla adattabilità e sull’orientamento alla persona. fiuta l’approccio di una progettazione teorica, o che ri-
Kent continuò a coltivare queste idee fino all’approdo al pudia la ricerca di soluzioni eleganti.
progetto C3 della Chrysler. Questo progetto riscosse una
grande notorietà, in quanto 12 programmatori riuscirono § Coraggio. Un pizzico di spericolatezza non guasta! Nel-
a scrivere in due anni il sistema di paghe mensili del grup- lo sviluppo del codice, soprattutto dopo l’avvento della
po (che gestiva più di 10.000 paghe al mese) composto da grande rete, la vecchia prudenza a tutti i costi, sban-
1400 classi funzionali e 1700 classi di test. Questo progetto dierata come virtù da molti project manager, si rivela
fu identificato come il progetto che diede i natali alla me- spesso l’anticamera del fallimento. Per un team di svi-
todologia XP. luppo, restare agganciato a tecnologie obsolete per la
paura di provarne di nuove, significa non essere mai
produttivo, ma sempre sulla rampa iniziale della cur-
I cinque valori dell’XP va di apprendimento. Allo stesso modo, aver paura di
riscrivere porzioni consistenti di un sistema, una volta
L’XP si focalizza su cinque valori:

1. comunicazione;
2. feedback;
3. semplicità;
4. coraggio;
5. rispetto.

§ Comunicazione. La conoscenza è un bene


prezioso nella realizzazione di un pro-
getto software. Per “conoscenza” si in-
tende sia quella del problema da auto-
matizzare (tipica del cliente) sia quel-
la sulle tecnologie (propria del team di
sviluppo). È fondamentale, quindi, che
non resti isolata. Ciò vuol dire favorire la
comunicazione sia fra il cliente e il team
di sviluppo, ma anche fra gli elemen-
FIGURA 3 Diagramma dei costi “agili”

34 n.4 - settembre-ottobre 2007


JAVA Journal educational

1. esplorazione;
2. pianificazione;
3. iterazioni fino al rilascio;
4. produzione;
5. mantenimento fino alla
morte (del progetto, natu-
ralmente).

§ Nella fase esplorativa il


cliente scrive delle storie
(user-story, una versione ri-
dotta dei casi d’uso del RUP)
per presentare le funzioni
che vorrebbe fossero inclu-
se nel primo rilascio del si-
stema. Nel frattempo il team
di sviluppo testa e acquisisce
familiarità con le tecnologie
FIGURA 4 Ciclo di vita dell’XP e gli strumenti che (proba-
bilmente) dovrà utilizza-
re. Questa fase può durare
che si è individuata una soluzione migliore (leggi più da alcune settimane a un massimo di pochi (due/tre)
semplice o generale), è una politica che porta alla ro- mesi. Per storie particolarmente rischiose l’XP preve-
vina. Il successo delle tecnologie open-source ha ormai de l’utilizzo di spike architetturali, cioè di “piccoli pro-
dimostrato che la qualità del lavoro accorcia i tempi di grammi usa e getta” per sperimentare una certa solu-
sviluppo. Pensare che scrivere il codice più in fretta si- zione.
gnifichi scriverlo male, è una favola a cui credono solo
i project manager sopra menzionati. Coraggio signifi- § Nella fase di pianificazione, che dura circa un paio di
ca anche non aver paura di confrontare le proprie opi- giorni, i programmatori danno una prima stima dello
nioni con quelle degli altri, e soprattutto ricordare che sforzo richiesto per l’implementazione di ogni storia.
le regole esistono, ma possono anche essere cambiate, In base a ciò il cliente e il team raggiungono un accor-
qualora il team ne abbia valutato le conseguenze e ab- do sulla priorità delle storie e sul contenuto del primo
bia raggiunto una visione concorde. rilascio. Il cliente formalizza anche i test di accettazio-
ne delle storie.
§ Rispetto. Vi ricordate l’orientamento alla persona? Uno
degli aspetti dei metodi ingegneristici è di considerare § Durante le iterazioni fino al primo rilascio, le storie del
i membri di un team come “componenti” sostituibili. cliente vengono frammentate o raggruppate, a seconda
Secondo questi processi ci sono analisti, programma- dell’entità di ciascuna, fino a renderle compatibili con
tori, tester, manager, ecc. Gli individui non contano; iterazioni della durata di qualche settimana (da una
solo i ruoli che ricoprono sono presi in considerazione. ad un massimo di tre/quattro). Le storie vengono asse-
L’XP rifiuta completamente questa visione. Considera gnate a coppie di sviluppatori e l’iterazione comincia.
le qualità individuali un aspetto chiave nel team. Un La prima iterazione si occupa di costruire l’architettura
buon metodo di gestione di un progetto deve valoriz- per l’intero sistema, scegliendo come iniziali quelle sto-
zare le qualità di ciascuno, innalzare il morale, spinge- rie che coprono tutti gli aspetti architetturali. Il cliente
re tutti a dare il massimo (e a voler dare il massimo). decide quali storie vanno implementate nelle iterazio-
Del resto se ci si aspetta che i propri sviluppatori siano ni successive. I test funzionali sono creati del cliente e
dei componenti sostituibili invece che persone, le risor- vengono eseguiti alla fine di ogni iterazione. Il periodo
se valide si cercano un posto migliore, e ciò che resta è di un rilascio, può durare da tre settimane a tre mesi.
proprio ciò che si voleva: un ammasso di componenti La cosa fondamentale è che ogni rilascio produca un si-
sostituibili. stema funzionante che permetta al cliente di provare il
prodotto e fornire un parere. Alla fine dell’ultima itera-
Decidere che le persone vengono prima è una grossa deci- zione, il prodotto è pronto per la fase successiva.
sione per un’azienda. Tuttavia va segnalato che lo sviluppo
del software è un’attività creativa e male si adatta ai prin- § La fase di produzione richiede una serie ulteriore di test,
cipi del Taylorismo. compresi i controlli di efficienza prima che il prodotto
possa essere rilasciato al cliente. Durante questa fase
possono essere individuati ancora possibili cambia-
Le cinque fasi dell’XP menti, ed è necessario decidere se vanno inclusi in que-
sto rilascio o nel successivo. Durate questa fase la dura-
Il Ciclo di vita dell’XP (Figura 4) consiste di 5 fasi: ta delle iterazioni deve essere accorciata e deve durare

n.4 - settembre-ottobre 2007 35


educational JAVA Journal

al massimo una settimana. Le idee e i suggerimenti per stema in produzione informazioni utili ai rilasci suc-
le release successive vanno annotati e conservati. cessivi. Questo approccio ha lo scopo di mitigare il ri-
schio di un processo poco prevedibile com’è lo sviluppo
§ Dopo che è avvenuto il primo rilascio all’utente, il pro- di un sistema software.
getto XP deve essere sia mantenuto in produzione, sia
evoluto con nuove iterazioni verso rilasci successivi. In 3. Metafore. Il sistema è definito da una metafora o da un
questa fase di mantenimento è richiesto un ulteriore set di metafore fra il cliente e i programmatori. Queste
sforzo per dare un supporto continuo al cliente. Per- storie condivise guidano tutto lo sviluppo descrivendo
tanto lo sviluppo vero e proprio può essere rallentato. come deve funzionare il sistema. Le storie ricordano i
Questa fase rappresenta anche un buon momento per casi d’uso del RUP, anche se si differenziano da questi
inserire nuove figure nel team di sviluppo o per modi- per la brevità. Infatti, le storie puntano ad avere una
ficarne in generale la struttura. comprensibilità a 360 gradi, cioè paritetica per il clien-
te e per gli sviluppatori, più che ad una descrizione det-
§ La morte del progetto comincia quando il cliente non ha tagliata di tutti i possibili flussi di programma che il si-
più nuove storie da raccontare al team, ed il sistema stema può percorrere.
soddisfa il cliente per efficienza e affidabilità. Questo
è il momento per il team di scrivere la documentazio- 4. Semplicità. Viene enfatizzata la progettazione della so-
ne completa del prodotto, perché d’ora in poi le cose luzione più semplice in ogni momento. La complessità
non cambieranno più. Oltre all’eutanasia, comunque, inutile o il codice extra vengono rimossi alla partenza.
la morte può sopraggiungere anche perché il sistema Naturalmente, la semplicità assoluta non esiste, poi-
non ha mai raggiunto i requisiti del cliente, o è diven- ché alcuni processi o algoritmi sono intrinsecamente
tato troppo costoso svilupparlo. complessi. Quello a cui si deve tendere, dunque (anche
a costo di ritocchi successivi in fase di sviluppo), è per-
Nel ciclo di vita XP non esistono fasi di analisi e di design seguire sempre la più semplice delle soluzioni che via
distinte, come avviene invece nel RUP, ma sono fuse assie- via si delineano.
me alla fase di implementazione. Pertanto, il progetto evol-
ve insieme al codice. Ciò garantisce una notevole flessibili- 5. Test, test e ancora test. Molte delle pratiche adottate dal-
tà alle modifiche, ma tuttavia impone agli sviluppatori una l’XP si trovano già nel RUP o in altri metodi ingegne-
notevole capacità di progettazione, rendendo il metodo XP ristici. Tuttavia l’XP estremizza l’importanza di alcune
inadatto a team di programmatori inesperti. di esse. In particolare modo l’XP mette la pratica dei
test a fondamento del metodo di sviluppo. I test di unità
vengono scritti prima del codice stesso e vengono ese-
Le 14 pratiche dell’XP guiti di continuo. Questo approccio ha numerosi bene-
fici. Per prima cosa, il momento migliore per scrivere
Nelle successive revisioni che Kent fece del metodo XP, i un test è quando si sta per scrivere il codice da testare
cinque valori trattati nel paragrafo precedente vennero e si hanno ancora freschi in mente tutti gli aspetti del
trasformati in 14 pratiche. Queste pratiche discendono dai problema in esame. In secondo luogo, scrivere prima
valori già discussi e risultano esserne un’applicazione con- i test, costringe lo sviluppatore a concentrarsi su cosa
creta. Vediamo di elencarle e di dare, di ognuna, una bre- deve fare il software, prima che su come potrà farlo, e
ve spiegazione. forza alla programmazione per interfacce e disaccop-
piata. Infine, i test disponibili nelle fasi iniziali di un
1. Il gioco della pianificazione. Una stretta interazione tra il progetto consentono di manipolare il codice con mag-
cliente e il team di sviluppo. I programmatori stima- giore serenità, in quanto si dispone di uno strumento
no lo sforzo e le risorse necessarie per l’implementa- per verificare di continuo che i cambiamenti introdotti
zione delle storie del cliente, mentre il cliente stabilisce non compromettano le funzionalità del sistema.
l’ambito e la sequenza dei rilasci. È importante a que-
sto punto spiegare uno degli aspetti peculiari dell’ap- 6. Refactoring. Il codice del sistema viene continuamen-
proccio XP. In questa fase di negoziazione per l’imple- te ricostruito, rimuovendo duplicazioni, aumentando
mentazione delle storie, le variabili in gioco sono quat- il riutilizzo, introducendo interfacce, rafforzando con-
tro: costo, tempo, qualità e portata. Negli approcci classici venzioni sui nomi, ecc. Questa pratica è in stretta re-
il management o il cliente decidono i valori di tutte e lazione con quella della semplicità, anche se in questo
quattro queste variabili (purtroppo). In XP solo tre di caso è più corretto parlare di comprensibilità. L’attività
queste variabili sono decise a priori, la quarta è il grado di refactoring è spesso malvista dai project manager e
di libertà concesso al team di sviluppo, il quale può fis- dai programmatori inesperti, perché dà la sensazione
sarne il valore in funzione delle altre. di ritoccare un po’ dappertutto un codice che maga-
ri finalmente funziona. Al contrario, i programmatori
2. Rilasci frequenti. Piccole porzioni di sistema vengono più navigati, che non tollerano di considerare il siste-
portate in produzione rapidamente, almeno una vol- ma qualcosa che “va anche se non si sa come”, sono
ta ogni due o tre mesi. Nuove versioni sono quindi ri- spesso favorevoli ad un refactoring che consolidi i ri-
lasciate anche giornalmente, ma non più che mensil- sultati a fatica ottenuti sul campo. Del resto la maggior
mente. Il cliente e il gruppo di lavoro traggono dal si- parte del refactoring è un attività lunga ma ripetitiva,

36 n.4 - settembre-ottobre 2007


JAVA Journal educational

FIGURA 5 Schema della metodologia RUP

e se supportata da un buon tool di sviluppo può essere ca permette anche la crescita degli sviluppatori, soprat-
quasi completamente automatizzata. tutto quelli meno esperti, grazie all’interazione di cia-
scun membro del team con tutti gli altri.

8. Possesso comune. Ciascuno può cambiare qualsiasi parte


del codice in qualsiasi momento. Ad esempio, se qual-
cuno si accorge della possibilità di migliorare un meto-
Pensare che scrivere do o una classe, semplificandoli, deve farlo senza pro-
blemi, anche se non è lui il creatore di quella classe.
il codice più in fretta, Questa attività è agevolata dall’uso di uno stile stan-
dardizzato nella scrittura del codice ed è resa sicura
significhi scriverlo dall’adozione dei test di non regressione.

male è una favola a 9. Integrazione continua. Una nuova porzione di codice vie-
ne integrata nel repository contenente il codice del si-
stema non appena è pronta. Il sistema viene comple-
cui credono solo i tamente ricostruito e testato. Tutti i test devono essere
completati con successo affinché le modifiche apporta-
project manager sopra te vengano accettate.

menzionati 10. 40 ore alla settimana. Gli straordinari sono proibiti. Gli
sviluppatori devono lavorare al massimo 40 ore setti-
manali. Se vengono fatti straordinari, vanno conside-
rati come un problema (un baco nel processo). Se ne
studia la causa e si cerca di risolverla.

7. Programmazione in coppia. Due sviluppatori per ogni 11. Cliente sul posto. Il cliente deve essere presente e dispo-
computer. Questo permette di aumentare la qualità del nibile in qualunque momento per il team di sviluppo.
codice scritto, sottoponendolo ad una continua verifica Questo è uno degli aspetti più difficilmente attuabili
e discussione nel momento stesso in cui viene scritto. nella realtà dello sviluppo quotidiano del software, so-
Le coppie di programmatori dovrebbero essere cambia- prattutto nel caso (così comune in Italia) in cui si svi-
te spesso, in modo che ciascun programmatore si trovi luppi codice per grandi enti statali o per la Pubblica
a lavorare su tutte le sezioni del progetto. Questa prati- Amministrazione, dove le distanze fra i committenti e

n.4 - settembre-ottobre 2007 37


educational JAVA Journal

il team di sviluppo possono essere siderali. un ambiente comune di sviluppo e della lotta al documen-
to scritto, proprie dell’XP. Pur mantenendo le caratteristi-
12. Codice standardizzato. Sono dichiarate e seguite scrupo- che di testing spinto e di costruzione continua, accentra lo
losamente delle regole di scrittura del codice, in modo sviluppo del software attorno alla Community. Il gruppo
che i sorgenti abbiano un solo stile di codifica noto a di sviluppo, clienti compresi, è mantenuto costantemente
tutti. Questa regola non fa riferimento tanto all’aspet- coeso dalla continua interazione tramite appositi strumen-
to di formattazione del codice, quanto alle convenzioni ti attorno ad un sito ufficiale di sviluppo del progetto. Questo
sui nomi da dare alle variabili di classe, ai metodi, alla sito è per la maggior parte prodotto da strumenti automa-
assegnazione di variabili, piuttosto che all’uso innesta- tizzati a partire dallo stato corrente del codice sorgente e
to delle chiamate e così via. dei documenti che gli strumenti di collaborazione hanno
prodotto di giorno in giorno (FAQ, issue tracking, mailing
13. Spazio aperto. Una grande sala con piccoli cubicoli è pre- list, forum, groupware, ecc.). Chissà se più in là, dal ma-
feribile a numerosi uffici separati. Le coppie di svilup- trimonio di Iconix con CoRE, non nasca qualcosa di anco-
patori dovrebbero essere messe al centro dello spazio. ra più equilibrato e universale. Ma questa è una storia che
solo il futuro potrà raccontare.
14. Semplicemente regole (quella che preferisco). Il team
deve seguire delle regole, ma deve anche ricordare che
sono solo regole e possono essere ridiscusse e adatta- Bibliografia
te in qualsiasi momento. I cambiamenti devono, natu-
ralmente, essere concordi e il loro impatto deve essere [1] Kent Beck, “eXtreme Programming eXplained”, Addison-
previsto. Wesley, 1999, ISBN 0201616416.
[2] Ivar Jacobson, Grady Booch, James Rumbaugh, “The
Unified Software Development Process”, Addison-Wesley,
Conclusioni 1999, ISBN 0201571692.
[3] Rosenberg Doug, Scott, Kendall, “Applying Use Case
Per concludere, vorrei esporre alcune mie convinzioni ine- Driven Object Modeling with UML: An Annotated E-
renti alle metodologie di sviluppo. Abbiamo visto che nel Commerce Example”, Addison-Wesley, 2001, ISBN
corso degli anni si sono susseguite molte metodologie, 9780201730395.
spesso in profonda antitesi l’una con l’altra. Ciascuna di [4] Glenn Niemeyer, Jeremy Poteet, “Extreme Programming
esse ha introdotto, a proprio modo, qualcosa di innovati- with Ant”, SAMS, 2003, ISBN 0672325624.
vo; ma nessuna si è arrogata il ruolo di soluzione migliore [5] César F. Acebal, Juan M. Cueva Lovelle, “A new method
o definitiva. Alcune, tuttavia, rappresentano a mio parere of Software Development:eXtreme Programming”, UPGRA-
più di altre dei punti di riferimento: si tratta delle meto- DE, 2002, http://www.upgrade-cepis.org/issues/2002/2/
dologie RUP, XP, Iconix e CoRE. Vediamo quali sono i loro up3-2Acebal.pdf.
aspetti peculiari. [6] Pekka Abrahamsson, Outi Salo, Jussi Ronkainen,
La metodologia RUP (Figura 5) è probabilmente la più “Agile software development methods, review and analy-
completa per numero di artefatti e dettaglio nella gestio- sis”, JULKAISIJA-UTGIVARE-PUBLISHER, 2002,
ne dei vari workflow. Per questo motivo, può essere oggi 9513860094.
considerata come una metodologia limite, a cui attingere
quando si realizza la propria metodologia. Tuttavia un’ese-
cuzione completa delle pratiche RUP, appare oggi un’ope- Riferimenti
ra titanica, non più alla portata di nessuna azienda, consi-
derato il numero di nuove tecnologie e la velocità richiesta [7] http://www.extremeprogramming.org
nella messa in produzione dei sistemi odierni. Allo stesso [8] http://www.martinfowler.com/articles/
modo l’XP sta subendo oggi una simile sorte, anche se per newMethodology.html
motivi diametralmente opposti. Anch’esso sta diventando [9] http://www.agilealliance.org/
una tecnologia limite, dalla quale però non vengono attin- [10] “Software Design Using CRC Cards”
te le specifiche degli artefatti o dei workflow, ma i valori http://www.realtime-info.com
orientati alla persona, l’agilità e la pratica dei test e delle [11] “Lo sviluppo ruota intorno all’utente”
costruzioni automatiche continue. Anche l’XP, comunque, http://www.nwi.it/nwi_arretrati/p12a0101.htm
ha mostrato i suoi limiti poco realistici, soprattutto rela- [12] “Processi e metodologie di sviluppo”, MokaByte N.85
tivamente alla presenza continua del cliente, allo spazio http://www.mokabyte.it/2004/05/metod-2.htm
comune di lavoro e alla richiesta di motivazione continua
da parte di tutto il team. Da un alleggerimento del RUP è
nata Iconix che, mantenendo solo un piccolo numero degli
artefatti e dei workflow, ha ricondotto il processo ad una
dimensione compatibile con le odierne tempistiche di svi-
luppo. Allo stesso modo, da una mitigazione dell’approccio Note Biografiche
XP sta oggi affermandosi CoRE. Questa metodologia, pro- Federico Paparoni si occupa prevalentemente di sviluppo sulle
veniente dalle esperienze dello sviluppo open-source, al- piattaforme JavaME e JavaEE. Gestisce il portale JavaStaff.com
per la pubblicazione di notizie e articoli sul mondo Java.
leggerisce le richieste di presenza continua del cliente, di

38 n.4 - settembre-ottobre 2007


JAVA Journal focus

n.1 - novembre/dicembre 2006 35


focus JAVA Journal

Database con
SuperWaba
per PDA e
SmartPhone
In questo articolo verrà descritta la piattaforma SuperWaba e come utilizzarla per realizzare
un breve programma per gestire i PDB (Personal DataBase), ossia dei database utilizzabili
direttamente da un palmare o da uno SmartPhone.

>> di Jacopo Giudici (jgiudici@javajournal.it)

S
uperWaba è una piattaforma di svi- § Librerie di base ed estese: sono delle API che permet-
luppo software open-source per PDA tono lo sviluppo di applicazioni (anche commer-
(Personal Digital Assistant o più co- ciali). La libreria di Driver PDB (Personal DataBa-
munemente noti come palmari) e se), che verrà trattata in questo articolo, è una li-
SmartPhone, basata sui Java tool. breria open source che permette la costruzione di
SuperWaba deriva direttamente dal un motore database funzionante su PDA.
progetto Wabasoft, nato nel 2000, che si ripromet-
te di definire un linguaggio, una macchina virtuale, § Strumenti di sviluppo e di distribuzione: sono gli stru-
un formato di classi e un set di API per lo sviluppo menti adatti a sviluppare e installare le applicazio-
di programmi su periferiche portabili. Nonostante ni su diversi tipi di periferiche.
Waba non sia esattamente Java, la sua sintassi per-
mette ai programmatori Java di apprenderlo veloce- § Esempi e documentazione.
mente. Inoltre, l’SDK SuperWaba contiene una serie
di classi per lo sviluppo di applicazioni direttamen- Come è detto nel sito del progetto, le applicazioni
te in Eclipse, aiutando ulteriormente gli sviluppatori scritte con SuperWaba hanno molteplici vantaggi.
Java ad avvicinarsi alla piattaforma. Eccone alcuni:

§ Basso costo di creazione e mantenimento delle applicazio-


SuperWaba: l’SDK e i suoi vantaggi ni. Grazie al principio del “write once run anywhe-
re”, è molto semplice scrivere applicazioni per una
Al momento, il kit di sviluppo di SuperWaba (scarica- gamma più ampia di periferiche passando velo-
bile dal sito www.SuperWaba.com) consiste di: cemente, ad esempio, dalla piattaforma PDA agli
SmartPhone.
§ SWVM (SuperWaba Virtual Machine): una Virtual
Machine SuperWaba che utilizza il principio “Wri- § Minore costo di installazione delle applicazioni. La piat-
te once run anywhere”, ossia un principio base di taforma è completamente royalty-free e non ha
Java. costo di licenza per periferica. L’unico costo è la

40 n.4 - settembre/ottobre 2007


JAVA Journal focus

sottoscrizione annuale per i programmi distribuiti, un


servizio che offre aggiornamenti automatici della Vir-
tual Machine e il supporto per lo sviluppo.

§ Migliori prestazioni. Paragonato ad altre piattaforme


SuperWaba deriva dal
(il sito del progetto cita .NET Compact Framework e
J2ME) SuperWaba dimostra un miglior utilizzo della
memoria del dispositivo, unitamente a buone presta-
progetto Wabasoft, nato
zioni.
nel 2000, e implementa
L’installazione del sistema
Dopo l’accesso al sito, è richiesta una registrazione gratuita una macchina virtuale
per poter scaricare l’SDK SuperWaba e la Virtual Machine
adatta alla periferica sulla quale installare SuperWaba. Per
l’installazione dell’SDK e degli esempi forniti, sono dispo- per l’esecuzione
nibili un file eseguibile per Windows e dei pacchetti auto-
installanti rpm e deb per Linux. Anche se in questo articolo
utilizzeremo Windows, il procedimento è identico, o molto
di programmi su
simile, per ogni altro sistema operativo, e la guida fornita
con il prodotto spiega passo passo come procedere. Dopo
aver installato l’SDK, avremo una cartella SuperWabaSDK
dispositivi portabili
contenente gli eseguibili per la creazione dei programmi,
le librerie Waba e gli esempi forniti.
Per installare la Virtual Machine (VM) sul palmare, dob-
biamo innanzitutto scegliere l’eseguibile adatto al nostro

sistema. Una volta scelta la VM adatta, le instal-


lazioni variano per sistemi PalmOS e PocketPC.
Nel primo caso, l’installazione della VM, cioè la
copia dell’eseguibile nelle cartelle adatte, deve
essere fatta manualmente. In particolare, in ogni
versione di PalmOS il file SuperWaba.pdb deve es-
sere copiato nella cartella xplat, contenente i file
di configurazione della piattaforma. Dopo aver
copiato questo file, per ogni versione del sistema
operativo esiste una particolare cartella: il ma-
nuale di SuperWaba a corredo dell’SDK indica in
quale cartella copiare la VM e i metodi nativi. Ad
esempio, con sistemi PalmOS 5 o superiori, i due
file SuperWaba.prc (la VM) e SWNatives.prc (i meto-
di nativi) devono essere copiati nella cartella

palm/PalmOS5_or_16bpp_only

Come ho già detto, rimando alla guida per gli ul-


teriori chiarimenti. Nel secondo caso, ossia per
PocketPC, oltre al file batch CEinstall_RunMe.bat,
che permette l’installazione sulla periferica col-
legata tramite ActiveSync ad un PC, è possibile
utilizzare il file .cab adatto al processore ed al Si-
stema Operativo prescelto, lanciandolo diretta-
mente dalla periferica; cosa da non sottovaluta-
re, in quanto permette anche l’installazione del
sistema tramite inserimento di schede SD o CF
preparate con un file autorun. Inoltre, seguendo
le istruzioni riportate nella guida, è possibile an-
che su piattaforma PocketPC installare il prodotto
FIGURA 1 Ad installazione avvenuta tra i programmi manualmente, copiando i file giusti nelle cartelle
disponibili sul PocketPC appare anche SuperWaba predefinite. Dopo l’installazione, su PocketPC do-

n.4 - settembre/ottobre 2007 41


focus JAVA Journal

vrebbe comparire, nella schermata dei programmi dispo-


nibili, anche SuperWaba, come si vede in Figura 1. Per
verificare di aver eseguito correttamente tutti i passaggi,
proviamo ad installare uno degli esempi forniti con l’SDK.
Come ogni linguaggio di programmazione che si rispetti,
anche SuperWaba ha il suo esempio HelloWorld che trovate
nella cartella SuperWabaSDK sotto

bin/installers/samples/<nome del sistema>/app/ HelloWorld.

Per installare l’applicazione su PocketPC, lanciate il pro-


gramma HelloWorld_Install.bat dopo aver collegato la perife-
rica al computer tramite ActiveSync. Il programma ricono-
scerà il sistema utilizzato dal palmare e utilizzerà il file .cab
appropriato per l’installazione. Dopo l’installazione, sul
palmare troverete un nuovo programma, HelloWorld, che,
se lanciato, visualizzerà la schermata di Figura 2.

Una prima applicazione in SuperWaba

Siamo quindi pronti a creare la nostra prima applicazione.


L’ambiente di sviluppo che andrò ad utilizzare è il Tauschke
MobileCreator (Riquadro 1). Il programma d’esempio con-
siste in una applicazione grafica SuperWaba per poter in-
serire dei dati relativi ad una videoteca in un database por-
tabile. Naturalmente, viene utilizzato questo esempio per
creare una struttura standard da poter utilizzare per l’in-
FIGURA 2 Il programma d’esempio HelloWorld
serimento e la ricerca dei dati in un qualsiasi database con
in esecuzione sul PocketPC.
poche modifiche. Cominciamo dalla definizione della clas-
se Videoteca che ospiteremo nel file Videoteca.java:

import waba.ui.*; Edit edtFilm;


import waba.fx.*;

public class Videoteca extends MainWindow { // metodo costruttore


public Videoteca () {
// casella di testo per l’inserimento di super(“Videoteca”,TAB_ONLY_BORDER);
un titolo }

public void onStart() {

RIQUADRO 1 // aggiunge una label


Tauschke MobileCreator add(new Label(“Film “), LEFT, AFTER+2);

Studiato appositamente per creare applicazioni con // aggiunge la casella di testo edtFilm
SuperWaba, questo ambiente di sviluppo, di facile in- add(edtFilm = new Edit(“ “));
stallazione, crea automaticamente i file per installare
e distribuire le applicazioni con SuperWaba utilizzan- //posizionamento e modifica della
do una struttura visuale alla Eclipse. Questa distribu- grandezza di edtFilm
zione permette di utilizzare in automatico le classi edtFilm.setRect(RIGHT, SAME-1,
Warp ed Exegen che creano, rispettivamente, un file PREFERRED+50, PREFERRED);
di tipo .pdb con il programma SuperWaba sotto for- }
ma di package, e un file eseguibile per l’esecuzione }
dello stesso. Inoltre, Tauschke MobileCreator fornisce
un’anteprima grafica dell’applicazione, utilizzando le Il package waba.ui fornisce l’implementazione della clas-
classi installate nel PC di sviluppo. Il programma (con se MainWindow, la classe di base per creare delle finestre
licenza d’uso personale gratuita) è reperibile all’indi- in SuperWaba. Innanzitutto, definiamo la variabile edtFilm
rizzo Web http://www.tauschke.com. di tipo Edit (una casella di testo). Quindi utilizziamo il co-
struttore della classe che permette di impostare il nome e
il BorderStyle della finestra, impostando il primo a Videoteca

42 n.4 - settembre/ottobre 2007


JAVA Journal focus

Questa invocazione, oltre a posizionare il componente (con


Rispetto al .NET allineamento a destra nella posizione SAME-1), permette la
definizione della grandezza del controllo, grazie agli ulti-
mi due valori, PREFERRED+100 e PREFERRED. Utilizzan-
Compact Framework do questa tecnica di posizionamento e ridimensionamen-
to dei componenti, si possono creare applicazioni in grado
di ridimensionarsi automaticamente su periferiche diver-
e a J2ME SuperWaba se; ed è quindi altamente consigliata. Invocando lo stesso
metodo andremo a inserire e posizionare i campi di testo
edtRegista, edtDurataMin, edtAnno; inoltre, andremo a siste-
garantisce un migliore mare un controllo di tipo checkbox con le seguenti righe:

Check chkDVD;
utilizzo della memoria e …
add(chkDVD = new Check(“DVD”), LEFT, AFTER+2);

buone prestazioni. A questo punto, aggiungiamo tre controlli, btnIndietro, bt-


nAvanti e btnInserisci, di tipo Button:

Button btnIndietro, btnAvanti, btnInserisci;

add(btnIndietro = new Button(“<”),LEFT, AFTER+2);


e il secondo a TAB_ONLY_BORDER, uno stile senza bordi
visibili. All’attivazione dell’applicazione partirà il metodo add(btnInserisci = new Button(“NEW”),AFTER, SAME);
onStart(), che in genere è incaricato di creare la struttura add(btnAvanti = new Button(“>”),AFTER, SAME);
grafica della finestra. Da notare il particolare metodo con
cui SuperWaba inserisce i vari controlli in una finestra: il Da notare fra doppi apici il testo assegnato a ciascun pul-
metodo si chiama sempre add(), come nelle applicazioni sante. Il risultato è la finestra mostrata nella Figura 3.
Swing, ma viene utilizzato con dei modificatori particola-
ri. Durante l’inserimento di un componente, in SuperWa-
ba si possono utilizzare due tipi di posizionamento: nume-
rico oppure logico. Con il posizionamento numerico, si esprime
la posizione fissa di un componente tramite i valori delle
coordinate; ad esempio possiamo inserire un controllo uti-
lizzando il metodo:

add(Control control, int x, int y)

Ciò serve a posizionare in modo assoluto il controllo nel-


la finestra (x e y sono valori calcolati in pixel a partire dal
punto in alto a sinistra di MainWindow). Con il posizio-
namento logico (detto anche posizionamento smart) ogni
componente viene inserito in MainWindow utilizzando un
criterio relativo, grazie a dei metodi che permettono il po-
sizionamento rispetto all’ultimo componente inserito. Nel
nostro caso, ad esempio, abbiamo inserito il primo control-
lo utilizzando il comando:

add(new Label(“Film “), LEFT, AFTER+2);

Nella fattispecie, non essendoci altri controlli, il posizio-


namento ha come riferimento l’angolo in alto a sinistra
di MainWindow. Il componente verrà posizionato con alli-
neamento a sinistra e in basso di tre posizioni (rispetto al
bordo superiore). Il secondo componente (edtFilm), invece,
viene prima aggiunto a MainWindow e poi viene posizio-
nato e ingrandito con il comando:

edtFilm.setRect(RIGHT, SAME-1, PREFERRED+100, FIGURA 3 L’interfaccia dell’applicazione


PREFERRED); Videoteca descritta nell’articolo.

n.4 - settembre/ottobre 2007 43


focus JAVA Journal

mente sul PDA. Le due stringhe Videoteca alla fine del co-
Compilazione e test dell’applicazione
mando sono rispettivamente la main-class del pacchetto
È quindi giunto il momento di compilare e testare l’ap- (Videoteca.class) e il package .pdb da utilizzare per creare il
plicazione. Per la compilazione, dobbiamo aggiungere al file .cab (Videoteca.pdb).
classpath i file SuperWaba.jar e SuperWabaTools.jar che si tro-
vano nella cartella SuperWabaSDK/lib. Il mio consiglio è di
aggiungerli alla variabile di sistema classpath, in quanto Creare e utilizzare un PDB
verranno utilizzati più volte (durante la compilazione e
l’esecuzione). Per maggiore chiarezza, giusto per dichiara- Un PDB, un tipo di file che abbiamo già incontrato, è un
re in modo esplicito dove si trovano questi file, nel primo database portabile (Portable Database) che permette di ve-
comando di compilazione della classe utilizzo il formato locizzare le operazioni di immissione e di ricerca dei dati
esteso: in un dispositivo portatile. Il lavoro che esegue la VM Su-
perWaba durante l’utilizzo dei PDB è analogo, in maniera
javac -classpath C:\SuperWabaSDK\lib\SuperWaba.jar meno potente rispetto alle versioni desktop, a un motore
Videoteca.java DBMS: collega al filesystem alcuni dati o indici mantenu-
ti in una memoria veloce, permettendo il rapido recupe-
Una volta compilato il file e creata la classe Videoteca.class, ro delle informazioni. Per l’utilizzo dei PDB esistono delle
dobbiamo eseguire ancora due passaggi: particolari classi che permettono l’inserimento di dati in
un catalogo e la lettura degli stessi tramite puntatori a re-
§ creare un package che contiene la classe (utilizzando cord. Nella Tabella 1 viene riportata una lista di classi che
la classe Warp); verranno utilizzate per scrivere e leggere i dati dal PDB.
Per completare la nostra Videoteca, andremo a scrivere due
§ creare l’eseguibile (meglio se in un .cab di installazione) ulteriori classi: la classe Film e la classe CatalogoFilm. La
utilizzando la classe Exegen. prima (Film) conterrà semplicemente i dati per definire un
film, i metodi accessori get e set e un costruttore compren-
Per il primo passaggio, il comando è il seguente: dente tutti i dati e sarà quindi simile alla seguente:

java superwaba.tools.Warp c Videoteca public class Film {


Videoteca.class
private String titolo
Questo comando crea il file Videoteca.pdb con le classi da private String regista;
eseguire con la VM SuperWaba: nel nostro caso solamen- private int anno
te la classe Videoteca.class. È un comando che potrebbe dare private int durata;
qualche messaggio di errore (che al momento possiamo private boolean DVD;
ignorare) durante l’esecuzione con JDK superiori all’1.3. Il
secondo comando, invece, è il seguente: public Film(String titolo, String regista,
int anno, int durata, boolean DVD)
java superwaba.tools.Exegen /E /Z Videoteca {
Videoteca this.titolo=titolo;
this.regista=regista;
Dopo averlo lanciato, vengono creati un file .cab di in- this.anno=anno;
stallazione (/Z) per ogni piattaforma disponibile nei tool this.durata=durata;
SuperWaba, dei file eseguibili per PocketPC (/E) e un file this.DVD=DVD;
batch simile a quello utilizzato per l’installazione di Hel- }
loWorld che installa l’applicazione via ActiveSync diretta-

Classe Scopo di utilizzo

Catalog Permette di creare un PDB e di posizionarsi con dei puntatori su particolari record

ResizeStream Viene utilizzata per creare un record di grandezza fissa

DataStream Classe wrapper per dati da inserire in un flusso (nel nostro esempio: un record)

TABELLA 1 Classi per la lettura e la scrittura di dati sul PDB

44 n.4 - settembre/ottobre 2007


JAVA Journal focus

tore della classe crea il PDB all’interno della cartella dove


public void setTitolo { si trova il programma. Inoltre, istanzia una variabile di tipo
this.titolo = titolo; DataStream che contiene i dati da scrivere nel record e una
} di tipo ResizeStream che permette di ridimensionare a 256
byte i record che gli vengono passati. Il metodo getFilm()
public String getTitolo { posiziona il puntatore su uno specifico record e, con i dati
return titolo; contenuti nello stesso, crea un’istanza di Film da restitui-
} re al metodo chiamante. I dati vengono letti con i metodi
read<tipo>() forniti dalla classe DataStream.
// altri metodi accessori Ad esempio, readString() legge una String nel record fino
… a quando non incontra il terminatore di stringa “\0”; rea-
} dByte() legge un Byte e così via. Infine, il metodo insert-
Film() inserisce un nuovo record al termine del PDB utiliz-
La seconda classe (CatalogoFilm), invece, si preoccuperà di zando i metodi write<tipo> e recuperando i dati dall’istan-
mantenere il catalogo dei film, compresa la posizione del za di Film che gli viene passata. Il procedimento per inseri-
record corrente e i metodi per inserire e scorrere la lista dei re un nuovo record alla fine del PDB è il seguente:
film. Vediamola nel dettaglio:
1. si apre il record con la chiamata
import waba.io.*;
import waba.sys.*; 2. si scrivono i dati con i metodi write<tipo>()
import waba.util.*;
3. si chiude il record e lo si scrive nel PDB
public class CatalogoFilm {
private Catalog cat; il che, tradotto in pseudocodice è simile al seguente esem-
private ResizeStream rs; pio:
private DataStream ds;
public int indice =0; rs.startRecord();
public int datiTotali; //public per comodità writeString(nuovoFilm.getDurata());
anche se errato! rs.endRecord();

public CatalogoFilm() throws Exception {


cat = new Catalog(“FILMDB.”+Settings.
appCreatorId+”.DATA”, Catalog.CREATE);
datiTotali = cat.getRecordCount();
rs = new ResizeStream(cat, 256);
ds = new DataStream(rs);
}

public Film getFilm(int indice) {


cat.setRecordPos(indice);
this.indice = indice;
return new Film(ds.readString(),
ds.readString(), ds.readInt(),
ds.readInt(), ds.readBoolean());
}

public void insertFilm(Film nuovoFilm) {


rs.startRecord();
ds.writeString(nuovoFilm.getTitolo());

ds.writeInt(nuovoFilm.getDurata());

rs.endRecord();
datiTotali++;
}
}

La classe contiene tre istanze (di tipo Catalog, ResizeStream


e DataStream) che permettono ai metodi getFilm() e insert-
Film() di recuperare e scrivere dei dati all’interno del PDB.
Inoltre, due dati di tipo int manterranno il numero dei dati
contenuti nel PDB e l’indice del record corrente. Il costrut-
FIGURA 4 Utilizzo dell’applicazione Videoteca.

n.4 - settembre/ottobre 2007 45


focus JAVA Journal

il metodo Catalogo.insertFilm() passando una nuova istanza


di Film creata recuperando i dati dalle caselle di testo (se

La funzione eseguita
viene premuto btnInserisci); oppure modifica l’indice del re-
cord corrente e lancia il metodo visualizza() per inserire i
dati recuperati dal PDB nei campi della finestra (se vengo-
no premuti i tasti btnAvanti o btnIndietro).
dalla VM SuperWaba Le uniche particolarità di questo metodo (rispetto alle
normali applicazioni Java) sono i due utilizzi del metodo
nell’utilizzo dei PDB Convert.toInt() che converte una String in un int. Il metodo
differisce da Integer.parseInt() in quanto la conversione vie-
ne fatta utilizzando la giusta grandezza degli int per il di-
è analoga a quella di spositivo su cui è stata lanciata l’applicazione. Per comple-
tezza, riporto il metodo visualizza() della classe Videoteca
(anch’esso con qualche omissis), che permette di visualiz-
un compatto motore zare i dati recuperati dal PDB nel form:

private void visualizza(Film daVisualizzare) {


DBMS. edtFilm.setText(daVisualizzare.getTitolo());

edtDurataMin.setText(“”+daVisualizzare.
getDurata);

chkDVD.setChecked(daVisualizzare.DVD);
}
Infine, il metodo aumenta il valore datiTotali. Per utilizzare
queste classi devono essere inserite alcune nuove righe nel Nell’applicazione finale, dopo aver completato il form del-
file Videoteca. Innanzitutto, servono i metodi per inizializza- l’applicazione, basterà premere il pulsante NEW per inse-
re un’istanza di CatalogoFilm: rire un nuovo record nel database, mentre i pulsanti “<”
e “>” serviranno a scorrere i titoli, come è possibile vede-
CatalogoFilm mioCatalogo = new CatalogoFilm(); re in Figura 4.

E quindi serve il metodo onEvent() che gestisce tutti gli


eventi dei pulsanti dell’applicazione:

public void onEvent(Event e)


{
if(e.target == btnInserisci)
{
mioCatalogo.insertFilm(new Film(
edtFilm.getText(),
edtRegista.getText(),
Convert.toInt(edtDurataMin.getText()),
Convert.toInt(edtAnno.getText()),
chkDVD.getChecked()
));
}
else if(e.target == btnAvanti)
{
mioCatalogo.indice++ %=
mioCatalogo.datiTotali;
visualizza(mioCatalogo.getFilm
Note Biografiche
(mioCatalogo.indice));
} Andrea Colleoni si occupa professionalmente di sviluppo di sof-
tware dal 1996 e di Java dal 2000. Attualmente svolge l’attività
else if(e.target == btnIndietro) di consulente attraverso la sua società, coordinando gruppi di
{ lavoro su progetti software di dimensioni medie o grandi in am-
… bito finanziario/bancario e industriale prevalentemente con tec-
nologie legate a J2EE, ma anche con Microsoft.NET. Si occupa
} anche di formazione; insegna Informatica alla Facoltà di Eco-
} nomia dell’Università di Bergamo e in altri corsi più specifici
organizzati da vari enti di formazione. Vive a Seriate in provin-
cia di Bergamo con mia moglie Elena e la sua piccolina, Greta,
In base al pulsante utilizzato, il metodo onEvent() utilizza arrivata cinque mesi fa.

46 n.4 - settembre/ottobre 2007


focus JAVA Journal

Grafici nelle
applicazioni Java
In questo articolo utilizzeremo una famosa libreria open source per la realizzazione di grafici:
JFreeChart.

>> di Federico Paparoni (fpaparoni@javajournal.it)

L
a maggior parte delle applicazioni che mite variabili predefinite. In una situazione reale, i
dobbiamo realizzare ha a che fare con i dati per la creazione dei grafici verranno gestiti di-
dati. Di qualsiasi genere siano, sempre namicamente. La classe che rappresenta il grafico
dati sono: tabelle di database, file da or- a torta è DefaultPieDataset, che fa parte del package
ganizzare, contatti da gestire. In queste org.jfree.data.general. Si tratta di un’implementazione
situazioni talvolta è necessario visualiz- di default di PieDataset, un’interfaccia che specifica i
zare uno schema di questi dati, un report, una qualsi- metodi che qualsiasi implementazione (come appun-
voglia statistica. In Java esistono diverse librerie che to lo è DefaultPieDataset) deve supportare per poter ge-
permettono ciò, ma una fra tutte è quella più utilizza- stire grafici a torta all’interno di JFreeChart. Pertan-
ta, sia per la completezza sia per la lunga serie di fun- to, per un primo grafico a torta non dobbiamo far al-
zionalità offerte: JFreeChart (http://www.jfree.org/ tro che istanziare un oggetto DefaultPieDataset e de-
jfreechart/) finire alcuni valori:

DefaultPieDataset pieDataset = new


JFreeChart DefaultPieDataset();

JFreeChart è una libreria open source realizzata ini- pieDataset.setValue(“Java”, new Integer(55));
zialmente da David Gilbert e rilasciata sotto licenza pieDataset.setValue(“PHP”, new Integer(25));
LGPL (Lesser General Public License) che permette pieDataset.setValue(“C#”, new Integer(15));
di utilizzarla in applicazioni commerciali. Questa li- pieDataset.setValue(“Ruby”, new Integer(5));
breria consente, essenzialmente, di realizzare nelle
proprie applicazioni dei grafici che rappresentano i In questo modo, abbiamo definito un grafico a tor-
dati da trattare e che vogliamo rappresentare in for- ta con quattro spicchi, specificando i valori da visua-
ma grafica. Per approfondire questo tema, grazie a lizzare per ogni spicchio. Un semplice programma di
JFreeChart, andremo a provare tutte le funzionalità visualizzazione del grafico è riportato nel Listato
offerte da questa libreria. Purtroppo, pur essendo un 1. Come si osserva nell’esempio, viene prima creato
progetto open source, c’è enorme scarsità di artico- l’oggetto DefaultPieDataset; successivamente, grazie
li sull’argomento (anche perché la guida ufficiale di alla classe ChartFactory, realizziamo il grafico vero e
questo progetto è a pagamento). Perciò, in questo ar- proprio, invocando il metodo statico createPieChart()
ticolo andremo a scoprire gradualmente quali sono le la cui firma è:
funzionalità disponibili.
static JFreeChart createPieChart
Grafico a torta (java.lang.String title,
// titolo del diagramma
Per introdurre il funzionamento della libreria utiliz- PieDataset dataset,
ziamo un classico grafico a torta. I dati su cui base- // dataset da rappresentare (oppure null)
remo l’esempio sono cablati nel codice sorgente, tra- boolean legend, // presenza della legenda?

48 n.4 - settembre/ottobre 2007


JAVA Journal focus

FIGURA 1 Grafico a torta

boolean tooltips, del JFreeChart, abbiamo salvato questo grafico su un file,


// presenza di tooltip da mostrare? per poterlo poi visualizzare a schermo. Ciò è stato possibile
boolean urls) // generazione di URL? attraverso la classe ChartUtilities:

Se mandiamo in esecuzione il programma, otteniamo il ri- try {


sultato mostrato nella Figura 1. Ma vediamo come cam- ChartUtilities.saveChartAsJPEG(newFile
biando una semplice riga del programma possiamo varia- (“chart.jpg”), chart, 500,300);
re la rappresentazione grafica dei dati. Come si evince dal }
Listato 1, il metodo utilizzato per realizzare un JFreeChart, catch (IOException ex) {
createPieChart() di ChartFactory, prevede il passaggio di un ex.printStackTrace();
parametro PieDataset. Scorrendo la documentazione Java- }
doc di JFreeChart vediamo che possiamo utilizzare la stes-
sa rappresentazione dei dati per creare un grafico, sempre BufferedImage image = chart.createBufferedImage
a torta, ma tridimensionale. Per farlo, basta invocare il me- (500,300);
todo createPieChart3D (la cui firma è identica al meto-
do già visto):

JFreeChart chart=ChartFactory.createPieChart3D(
“PieDataSet Demo”, pieDataset, true, false,
false);

In questo modo abbiamo realizzato un grafico a torta


tridimensionale (Figura 2). Il motivo per cui la libre-
ria è organizzata in questa maniera è abbastanza com-
prensibile: possiamo fare, ad esempio, un parallelismo
con il pattern MVC (Model View Controller). In questo
caso, i dati da gestire sono rappresentati dall’interfac-
cia PieDataset (il Model). Nel momento in cui vogliamo
visualizzare queste informazioni passiamo attraverso il
ChartFactory che genera un JFreeChart (il View) che poi
possiamo utilizzare. Nel Listato 1, dopo la creazione
FIGURA 2 Grafico a torta tridimensionale

n.4 - settembre/ottobre 2007 49


focus JAVA Journal

/*
Istogramma
* PieDatasetDemo.java Appreso il meccanismo di base di ge-
*/ nerazione dei grafici tramite JFree-
import java.awt.*;
Chart, passiamo a un altro interessan-
import java.awt.image.*;
import java.io.*; te esempio di utilizzo: andremo a crea-
import javax.swing.*; re un Dataset (che rappresenta i dati)
e a mostrarli in un istogramma. La
import org.jfree.data.general.*; classe che permette di creare insiemi
import org.jfree.chart.*; di dati per questo tipo di rappresenta-
zione è DefaultCategoryDataset, che im-
plementa l’interfaccia CategoryDataset.
public class PieDatasetDemo extends JFrame { Utilizzando questa classe possiamo
definire i dati che andranno rappre-
public PieDatasetDemo() {
sentati dall’istogramma. Nel Listato 2
DefaultPieDataset pieDataset = new
DefaultPieDataset(); è riportato un esempio di generazione
pieDataset.setValue(“Java”, new Integer(55)); di un grafico di questo tipo. Come nel
pieDataset.setValue(“PHP”, new Integer(25)); caso dei diagrammi a torta, dobbiamo
pieDataset.setValue(“C#”, new Integer(15)); popolare il Dataset con dei valori. Il ri-
pieDataset.setValue(“Ruby”, new Integer(5)); sultato dell’esecuzione del program-
JFreeChart chart=ChartFactory.createPieChart ma è mostrato in Figura 3. In questo
(“PieDataSet Demo”,pie Dataset, rue,false,false); caso, abbiamo voluto visualizzare l’an-
damento agli esami degli studenti Pip-
try { po e Pluto. Per ogni studente sono sta-
ChartUtilities.
ti inseriti tre diversi valori (prima pro-
saveChartAsJPEG(new File(“chart.jpg”), chart,500,300);
} catch (IOException ex) { va, seconda prova e orale). Queste infor-
ex.printStackTrace(); mazioni sono state inserite nel Dataset,
} unitamente al voto ottenuto dagli stu-
denti (il valore sull’asse delle ordinate
BufferedImage image = di ciascun istogramma)
chart.createBufferedImage(500,300);
dataset.addValue(6.0, series1,
JLabel lblChart = new JLabel(); category1);
lblChart.setHorizontal- dataset.addValue(9.0, series1,
Alignment(JLabel.CENTER);
category2);
lblChart.setVertical-Alignment(JLabel.CENTER);
dataset.addValue(7.0, series1,
lblChart.setIcon(new ImageIcon(image));
category3);
this.getContentPane().set-Layout(new
BorderLayout()); dataset.addValue(8.0, series2,
this.getContentPane().add-(lblChart, category1);
BorderLayout.CENTER); dataset.addValue(7.0, series2,
this.setSize(600,400); category2);
this.setVisible(true); dataset.addValue(8.0, series2,
category3);
}

public static void main(String[] args) throws Per creare l’istogramma si ricorre al
Exception { metodo createBarChart() di ChartFactory
PieDatasetDemo pieDatasetDemo = new la cui firma è:
PieDatasetDemo();
} static JFreeChart createBarChart
} (java.lang.String title,
java.lang.String categoryAxisLabel,
LISTATO 1 Classe che crea e visualizza un PieDataSet // etichetta asse dominio
java.lang.String valueAxisLabel,
// etichetta asse valori
Questo metodo di salvataggio dei grafici è semplice e age- CategoryDataset dataset,
vole, ma è scomodo da utilizzare se vogliamo semplice- PlotOrientation orientation,
mente visualizzare il grafico e non intendiamo salvarlo. // orientamento orizz/vert
Nei prossimi paragrafi vedremo come utilizzare ChartPanel, boolean legend,
un pannello realizzato in JFreeChart che permette di inse- boolean tooltips,
rire il grafico direttamente nell’interfaccia grafica senza il boolean urls)
salvataggio su disco.

50 n.4 - settembre/ottobre 2007


JAVA Journal focus

FIGURA 3 Istogramma

Per cui, nel nostro caso scriveremo: Il risultato di questo cambiamento è visibile nella Figu-
ra 4.
JFreeChart chart=ChartFactory.createBarChart
(“Istogramma”, “Esame”, “Voto”,
dataset, PlotOrientation.VERTICAL,
Grafici dal database
true,true,false);
Come abbiamo detto precedentemente, JFreeChart offre
Ed infine abbiamo utilizzato la classe ChartPanel per ag- una vasta gamma di servizi per la rappresentazione grafi-
giungere il grafico direttamente nella nostra interfaccia ca dei dati. Un caso molto comune è avere dei dati memo-
rizzati in un database da visualizzare graficamente. All’in-
ChartPanel chartPanel = new ChartPanel(chart); terno di JFreeChart troviamo un package che fa proprio al
caso nostro: org.jfree.data.jdbc. In questo package sono sta-
chartPanel.setPreferredSize(new Dimension ti definiti tre diversi Dataset, simili a quelli già visti ma
(500, 300)); che riescono a caricare le informazioni dal database. Ciò
setContentPane(chartPanel); che avviene in queste classi è molto semplice (così come
setVisible(true); avremmo fatto se JFreeChart non offrisse questa funzio-
nalità): a questi Dataset vengono passati come parametri
Anche in questo caso abbiamo seguito gli stessi passi effet- una connessione JDBC e una query SQL. Il Dataset effettua
tuati per il diagramma a torta: creazione del dataset, po- la query sul DB e memorizza le informazioni restituite. Il
polamento del dataset, creazione del JFreeChart attraver- passo successivo è visualizzare questi dati, come abbiamo
so ChartFactory e visualizzazione. Per visualizzare altri
grafici, che possono essere generati a partire dal codi-
ce del Listato 2 senza effettuare troppi cambiamen-
ti, basta modificare il metodo utilizzato per la gene-
razione del JFreeChart. Ad esempio, andiamo a riscri-
vere il codice sostituendo l’invocazione del metodo di
ChartFactory con la seguente riga:

JFreeChart chart=ChartFactory.createBarChart3D
(“Istogramma 3D”,”Esame”,”Voto”,
dataset,PlotOrientation.
HORIZONTAL, true,true,false);

Così facendo, abbiamo modificato il grafico in un


istogramma 3D e abbiamo modificato l’orientamento
selezionando il valore PlotOrientation.HORIZONTAL.
FIGURA 4 Istogramma tridimensionale orientato in orizzontale

n.4 - settembre/ottobre 2007 51


focus JAVA Journal

LISTATO 2 Classe che crea e visualizza un CategoryDataSet JFreeChart e applicazioni


Web
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.swing.*; Gli esempi visti finora ri-
guardano sempre applica-
import org.jfree.data.category.*; zioni desktop in cui uti-
import org.jfree.chart.*; lizziamo JFreeChart. Però,
import org.jfree.chart.plot.*; l’utilizzo di questa libreria
si rivolge anche alle appli-
public class CategoryDemo extends JFrame {
cazioni Web, ed ora vedre-
public CategoryDemo() { mo come inserire un gra-
setSize(500,300); fico in una semplice appli-
final String series1 = “Pippo”; cazione Java Server. I gra-
final String series2 = “Pluto”; fici che abbiamo generato,
per il momento, sono stati
final String category1 = “Prima prova”; salvati su file (primo esem-
final String category2 = “Seconda prova”; pio con grafico a torta) o
final String category3 = “Orale”; visualizzati attraverso un
componente ad hoc (se-
final DefaultCategoryDataset dataset =
new DefaultCategoryDataset(); condo esempio con l’isto-
gramma). Vediamo quindi
dataset.addValue(6.0, series1, category1); la prima parte della nostra
dataset.addValue(9.0, series1, category2); applicazione Web, una JSP
dataset.addValue(7.0, series1, category3); dove creiamo un diagram-
ma a torta 2D:
dataset.addValue(8.0, series2, category1);
dataset.addValue(7.0, series2, category2);
dataset.addValue(8.0, series2, category3); <%@page
contentType=”text/
JFreeChart chart=ChartFactory.createBarChart
html”%>
(“Istogramma”, ”Esame ”,”Voto”,
dataset,PlotOrientation.VERTICAL, <%@ page import=”com.
true,true,false); java staff.stats.*” %>
final ChartPanel chartPanel = new ChartPanel(chart); <%@ page
chartPanel.setPreferredSize(new Dimension(500, 300)); import=”java.util.*” %>
setContentPane(chartPanel); <%@ page import=”org
setVisible(true); .jfree.data.general.
} DefaultPieDataset” %>
<%@ page import=»
public static void main(String[] args) throws Exception {
org.jfree.chart.*» %>
CategoryDemo categoryDemo = new CategoryDemo();
<html>
}
} <head>
<title>Demo Web</
title>
</head>
<body>
fatto precedentemente. Come risultato abbiamo un grafico <%
dei dati con poche e semplici righe di codice: DefaultPieDataset
pieDataset = new DefaultPieDataset();
Connection conn = DriverManager.getConnection pieDataset.setValue(“Java”,
(db, username, password); new Integer(55));
JFreeChart chart; pieDataset.setValue(“PHP”,
String sql = “select val1, val2 from table”; new Integer(25));
JDBCXYDataset chartData = new JDBCXYDataset pieDataset.setValue(“C#”,
(conn, sql); new Integer(15));
xyData = (XYDataset) chartData; pieDataset.setValue(“Ruby”,
new Integer(5));
chart = ChartFactory.createXYLineCha (“”, “”, “”, JFreeChart chart = ChartFactory.
xyData, PlotOrientation.HORIZONTAL,true, true, createPieChart(“Demo Web”,
false); pieDataset,true,false,false);
application.setAttribute(“chart”,chart);

52 n.4 - settembre/ottobre 2007


JAVA Journal focus

FIGURA 5 Grafico per la visualizzazione di un Gantt

%> Come si è detto, l’oggetto JFreeChart viene recuperato dal


<IMG src=»ChartServlet»> contesto dell’applicazione. Viene quindi impostato il con-
</body> tent type della risposta come image/png, e viene creata
</html> un’immagine e viene scritta nello stream di output.

In questa JSP abbiamo creato un grafico e abbiamo salvato


l’oggetto JFreeChart nell’oggetto implicito application (ov-
Conclusioni
vero il Context della Web Application). In questa pagina,
abbiamo demandato la creazione del grafico ad una Serv- JFreeChart è un’ottima libreria per la generazione di gra-
let, anche perché non avremmo potuto includere l’imma- fici in Java. Navigando tra la documentazione Javadoc
gine utilizzando solo questa JSP, perché il ContentType del- (l’unica ufficialmente disponibile) è possibile scovare pia-
la pagina è semplicemente HTML e, quindi, non avremmo no piano molte caratteristiche interessanti per le nostre
potuto aggiungere un contenuto come un’immagine. La applicazioni. Esistono moltissime tipologie di grafico, mo-
Servlet ChartServlet in questo caso dovrà generare il grafi- dificabili fin nei minimi dettagli: possiamo cambiare colo-
co, prendendo l’oggetto JFreeChart dal contesto e stampan- ri, font, immagini di sfondo. Ad esempio, un’altra tipologia
do in output l’immagine, come nel caso in cui viene salva- di grafico realizzabile attraverso questa libreria è il Gantt,
ta su file. Qui di seguito viene riportato il metodo doGet() definito nel package org.jfree.data.gantt, come potete vedere
di ChartServlet in Figura 5 che visualizza uno degli esempi di JFreeChart.
Chiaramente l’utilizzo di questa libreria può essere un no-
protected void doGet(HttpServletRequest request, tevole valore aggiunto per le nostre applicazioni.
HttpServletResponse response)
throws ServletException, IOException {

JFreeChart chart = (JFreeChart)getServlet


Context().getAttribute(“chart”);
response.setContentType( “image/png” );

BufferedImage buf = chart.createBufferedImage


(640, 400, null);
PngEncoder encoder = new PngEncoder( buf,
false, 0, 9 ); Note Biografiche
response.getOutputStream().write( Federico Paparoni si occupa prevalentemente di sviluppo sulle
encoder.pngEncode() ); piattaforme JavaME e JavaEE. Gestisce il portale JavaStaff.com
per la pubblicazione di notizie e articoli sul mondo Java.
}

n.4 - settembre/ottobre 2007 53


COMMUNITY
FREESPEECH Login Topic

COMMUNITY WATCH
Ü di Stefano Sanna
(stefano.sanna@javajournal.it)

Nel primo numero di Community Watch abbiamo introdotto la JJ: Quando avete pensato di realizzare il progetto JUG Avis?
community Java italiana (intesa come insieme delle communi-
ty locali e tematiche del nostro Paese): numerosa, vivace e ap- FG: È necessaria una piccola premessa: ai primi del 2005, abbia-
passionata, raduna i programmatori della penisola, organizzan- mo percepito che il nostro JUG dovesse fare un salto di qualità.
do eventi e promuovendo progetti di sviluppo. Viste le molte- Andare oltre la consueta attività didattico-formativa per appas-
plici iniziative in corso, avremo modo di dare spazio a tutti in sionati, tipica di ogni JUG, per applicare le nostre conoscenze
questa rubrica. in un progetto comune. Dedicando il nostro tempo non al solito
Questo mese presentiamo il Java User Group Sardegna Onlus, progetto per ipertecnici (librerie, framework, ecc.) ma al “mon-
che l’anno scorso è stato premiato per il progetto JUG-AVIS du- do reale”. Costruire qualcosa di utile, semplice e di grande effet-
rante la JavaOne Conference a San Francisco con il prestigioso to, ovviamente in Java! Da là, l’idea di sviluppare un’applicazio-
Duke Award. Per parlare del gruppo e del progetto abbiamo in- ne che facilitasse la comunicazione tra i Centri AVIS ed i dona-
tervistato due dei fondatori del JUG Sardegna: Fabrizio Gian- tori di sangue (per emergenze, scadenze di donazioni, solleciti)
neschi e Massimiliano Dessì. è stata quasi immediata, poiché molti di noi, me compreso, sono
Fabrizio è presidente del JUG, Java Champion e coor- donatori. In Sardegna l’emergenza sangue è molto sentita. Al-
dinatore della Community dei JUG su java.net (http:// l’inizio, da tecnici entusiasti, ipotizzammo un “sistemone” che
www.jugsardegna.org/vqwiki/jsp/Wiki?FabrizioGianneschi). faceva un sacco di cose. Poi, grazie al fondamentale aiuto del
Massimiliano è co-fondatore e consigliere del JUG, coordina- Centro AVIS di Sestu, che ha svolto il ruolo di Centro Pilota,
tore degli User Group Italiani su Spring, Jetspeed e Groovy, at- abbiamo capito meglio cosa realmente serviva e come organiz-
tualmente è consulente presso Centro Servizi della Regione Au- zarci. Ad esempio, una cosa a cui non avevamo pensato inizial-
tonoma della Sardegna (http://wiki.java.net/bin/view/People/ mente, è che una migliore capacità di comunicazione (via SMS,
MassimilianoDessi). email, eccetera) è utile ai Centri anche per la normale vita asso-
ciativa, in occasione di assemblee, convocazioni e anche... augu-
JJ: Fabrizio, com’è nato il JUG Sardegna? ri di Natale! Il nostro applicativo, che grazie a Java ed ai Web
Service consente ai Centri di scegliere in autonomia i propri for-
FG: Il JUG Sardegna nasce nei primi mesi del 2002, da un’idea nitori SMS, è stato letteralmente calzato sulle loro esigenze. Ma
mia e di alcuni amici, tra cui Max, dato che al tempo la Sar- nulla di più, se non fargli risparmiare tempo e denaro. È gente
degna era priva di gruppi dedicati a Java. Iniziammo subito a estremamente concreta, che contribuisce a salvare le vite uma-
contattare potenziali interessati, ed in breve mettemmo in pie- ne: in tali contesti la “fuffa”” serve a poco. Infine, la ciliegina
di una mailing list, che ancora oggi è il nostro principale mez- sulla torta è stata l’installazione presso il più importante ospe-
zo di comunicazione interna. Fondamentale fu l’aiuto dell’Uni- dale della Sardegna, che gestisce un proprio Centro Trasfusiona-
versità. Il successo fu immediato e tra alti e bassi siamo a strut- le. Non solo AVIS, dunque, ma anche Sanità Pubblica, che ov-
turarci sempre meglio. Dal 2005 siamo infatti un’Associazione viamente ha le sue specificità. È stata una sfida affascinante.
e dal 2006 siamo iscritti al Registro del Volontariato della no-
stra Regione. JJ: Massimiliano, qual’ è l’architettura del software JUG Avis? Quali
tecnologie avete utilizzato?

Note Biografiche MD: L’architettura del Jug Avis Web è three layer (Figura 1),
costruita utilizzando Spring. Spring MVC e JSP-JSTL per il
layer di presentazione, dei POJO gestiti da Spring con transa-
Stefano Sanna si occupa di sviluppo di applicazioni multi-
zioni AOP per il layer business logic e iBATIS per il data layer.
mediali per piattaforma Savaje presso Beeweeb Technolo-
L’importazione dei donatori può avvenire tramite file .csv o file
gies (http://www.beeweeb.com). Ha lavorato per sette anni
Excel, l’esportazione con Jasper Report in pdf, csv, xls e html.
nel gruppo Network Distributed Applications del CRS4, oc-
Axis viene usato per l’invocazione dei web service già imple-
cupandosi di mobile computing e applicazioni network-orien-
mentati dalla versione Swing, per quelli di nuova costruzione
ted per cellulari e PDA. Collabora attivamente con JIA, JUG
XFire. Per l’invio delle mail abbiamo utilizzato javamail, Rome
Sardegna e Java Mobile Developers Forum. Il sito sito web
per i feed Rss, mentre per le statistiche con i grafici JFreeChart.
personale è http://www.gerdavax.it
Il database è Postgres (Figura 2). L’applicazione consente un

55 n.4 - maggio/ottobre 2007


COMMUNITY
FREESPEECH Login Topic

utilizzo centralizzato dei centri di donazione. Ognuno ha i suoi California! Il Duke Award è stato all’inizio solo una scommessa
dati accessibili solo al coordinatore del centro, il quale può av- fatta così per caso (mai avrei pensato infatti che potessimo vin-
visare i donatori tramite sms, mail e feed rss, può gestire i dati cere) ed alla fine si è trasformato in uno dei più bei ricordi del-
dei donatori, importandoli o esportandoli nel formato oppor- la mia vita. Siamo stati infatti il primo JUG al mondo, ed i pri-
tuno, e può visualizzare le statistiche delle comunicazioni per mi in assoluto in Italia anche contando le aziende, a vincerlo.
gestire al meglio ad esempio l’acquisto degli sms, che in questo E vincerlo così, con un’applicazione apprezzata non tanto dal
modo possono essere acquistati congiuntamente con altri cen- punto di vista tecnico ma per quello che è stato sin dall’inizio il
tri ottenendo prezzi più favorevoli. La versione swing standa- nostro obiettivo, cioè l’utilità, l’innovazione applicata al socia-
lone utilizza hypersonic per conservare i template dei messag- le, è stato grandioso. L’ennesima dimostrazione della tanto mi-
gi, e axis per la spedizione via web-service dei messaggi. L’ap- tizzata “creatività italiana”, ma anche, consentitemelo, un gran-
plicazione importa da file csv i cellulari dei donatori e invia un de orgoglio come sardo. Ho avuto l’opportunità di ricevere il
messaggio che viene scritto dal responsabile del centro, vengo- premio da James Gosling, di conoscere un sacco di gente (il Ja-
no conservati vari template con i messaggi. vaOne è una vera e propria Babele) e di stabilire rapporti im-
portanti per il nostro JUG, in una “5 giorni” in cui avrò dormi-
JJ: Quali sono state le maggiori difficoltà incontrate? to meno di tre ore a notte. Raccontare tutti i dettagli portereb-
be via troppo spazio; chi fosse interessato può leggere un reso-
MD: I “clienti” non sanno esattamente cosa vogliono! Scherzi conto dell’avventura sul mio blog: http://www.jroller.com/page/
a parte, è importante che in caso di invio, se l’applicazione va bitog?entry=l_avventura_del_duke_s
giù per qualsiasi motivo, non si perdano le “code” di spedizio-
ne delle mail o degli SMS: quindi ci sono dei sistemi di sche- JJ: Quali saranno le prossime tappe?
duling, salvataggio e successivo recupero. Naturalmente l’ap-
plicazione deve essere testata automaticamente dal DB alle in- MD: Per l’aspetto tecnico, una volta terminata l’intera infra-
terfacce utente. struttura, test automatici compresi, si cercherà di introdurre in-
terfacce utente che utilizzano AJAX, e come novità si proverà
JJ: Ricevere il Duke Award è di grande prestigio, ma anche grande ad aggiungere funzionalità di comunicazione VOIP per le quali
emozione: ci racconti com’è andata? si è offerta una società con competenze nel settore. Per l’aspetto
organizzativo, cercare volontari che possano lavorare con conti-
FG: Beh, in poche parole ... da Sestu (CA) ai grattacieli della nuità per abbreviare i tempi di sviluppo.

n.4 - maggio/ottobre 2007 56


Non
Non perderti
perderti
Computer
Computer Programming
Programming
di
di Settembre!
Settembre!
Ordinalo
Ordinalo direttamente
direttamente da
da
www.infomedia.it
www.infomedia.it