Introduzione
Tapestry è un ambiente di sviluppo nato un paio
di anni fa, e che dal maggio 2003 è entrato a
far parte di Jakarta. Si tratta di uno strumento rivolto
in particolar modo alla produzione di siti Internet
particolarmente grandi e complessi, in cui la fase di
sviluppo richieda la presenza di due team distinti (uno
team di sviluppatori ed uno di grafici). Tuttavia non
si limita solamente al Web, ma punta, grazie ad una
estrema flessibilità, ad adattarsi ad altri linguaggi
a tag già esistenti (ad esempio esistono delle
librerie per lavorare con wml) o futuri.
Le applicazioni Tapestry richiedono la definizione,
attraverso degli appositi documenti xml, delle pagine
che fanno parte dell'applicazione e delle componenti
presenti in ciascuna pagina. L'obiettivo di fondo è
quello di ottenere dei template grafici estremamente
puliti e che siano testabili anche a livello statico
(ovvero senza la necessità di aver già
sviluppato le parti dinamiche del sito, quali ad esempio
le interrogazioni a database).
Tapestry:
cos'è, quando nasce e perchè
Tapestry è costituito essenzialmente da alcune
librerie all'interno del package net.sf.tapestry. All'interno
di questo esistono diversi sottopackage, ciascuno dei
quali svolge un preciso compito.
Tapestry non è un framework per lavorare solamente
con documenti html. Si tratta anzi un approccio completamente
generico e slegato da qualsiasi linguaggio a tag. A
partire da questo approccio generico si sono sviluppati
poi dei sottopackage specializzati in alcuni linguaggio
a tag particolarmente diffusi. In particolare oggi esiste
una libreria per la creazione e la gestione di documenti
html e una per la gestione di documenti wml. In futuro
però Tapestry potrà essere esteso a qualsiasi
linguaggio a tag.
Tapestry non è un linguaggio di scripting; si
tratta anzi di un progetto che vuole profondamente prendere
le distanze da questi linguaggi (ed in particolar modo
dalle JavaServer Pages) e dalla loro filosofia.
L'idea alla base di Tapestry è di dividere il
lavoro dei disegnatori grafici di un sito da quello
degli sviluppatori Java e di permettere ai due gruppi
di procedere parallelamente con l'implementazione. Uno
dei principali scopi di Tapestry è quindi quello
di ridurre al minimo l'impatto del codice implementativo
all'interno dei file html (mentre invece nei linguaggi
di scripting parti statiche html e parti dinamiche sono
continuamente confuse e inserite in uno stesso documento).
<%
String nome = (String)session.getAttribute("nome");
%>
<p>Benvenuto
<%=nome%></p>
"Benvenuto
utente" con JavaServer Pages
<p>Benvenuto
<span jwcid="insertNome">Pietro Ferrara</span></p>
"Benvenuto
utente" con Tapestry
Come
si può vedere dall'esempio, mentre un linguaggio
di scripting modifica sensibilmente la pagina html (che
in questo modo è difficilmente editabile con
un editor html) anche per una semplice operazione di
lettura e scrittura di una variabile, l'impatto di Tapestry
è minimo. Visualizzando la pagina di Tapestry
con un editor html la si visualizzerà correttamente.
Ma cosa accade quando questa pagina viene interpretata
dal server?
Struttura
di un'applicazione Tapestry
La chiave di Tapestry sono gli attributi jwcid (acronimo
per Java Web Component ID). Questi attributi (che vengono
ignorati dagli editor html) servono ad indicare che
si tratta di parti dinamiche della pagine, e richiamano
la componente con il nome riportato; a sua volta la
componente è collegata ad una classe java. Il
comportamento a livello dinamico può essere estremamente
diverso in base al tipo di componente che viene richiamata
(analizzeremo in seguito le diverse componenti esistenti
e come crearne ex novo). Nel nostro caso, quanto scritto
tra i due tag <span> viene rimosso e al suo posto
viene inserito quanto restituito dalla componente insertNome.
Tutte le componenti devono essere definite in un apposito
file .page. Questo file conterrà anche tutti
i riferimenti a classi Java. Per poter interagire con
le classi java Tapestry si appoggia sulla struttura
dei JavaBeans. A ciascun file .page è associato
un template html (nel caso in cui si stia lavorando
con le librerie html) che serve a definire la struttura
grafica della pagina e dove inserire le diverse componenti.
I file page poi per poter essere inseriti in una applicazione
devono essere definiti all'interno di un file .application.
Quando un utente si collegherà al sito, un'apposita
servlet richiamerà il file .application. Questo
verrà analizzato da apposite classi del package
di Tapestry.
Figura 1 - Struttura di un'applicazione Tapestry
(clicca sull'immagine per ingrandire)
I
JavaBeans
Apro qui una parentesi per spiegare l'architettura dei
JavaBeans, elementi essenziali per lo sviluppo di siti
internet con Tapestry e per permettere la comunicazioni
tra le componenti e le classi java.
L'idea che sta alla base dei JavaBeans è di manipolare
oggetti Java senza conoscerne a priori il tipo. Per
poter accedere a questi dati è necessario rispettare
le seguenti regole di naming nel definire i diversi
metodi:
public
type getName (){
}
public
void setName (type valore){
}
In
questo modo Tapestry potrà accedere ai valori
contenuti nella classe tramite il metodo getName, mentre
potrà settarne il valore tramite setName.
E' importante sottolineare che non è necessario
che ad ogni coppia setName e getName corrisponda un
attributo Name relativo; questi metodi infatti potrebbero
effettuare una serie di operazioni su più attributi
o valori presi dall'esterno (ad esempio da un database)
prima di restituire un valore o settare uno o più
attributi.
public
Boolean isName (){
}
Esiste
infine un metodo per lavorare con variabili booleane
e che è tipicamente utilizzato da componenti
che impostano il loro comportamento in base ad una condizione
(ad esempio le componenti di tipo Conditional).
ApplicationServlet
In Tapestry le servlet sono state altamente automatizzate
e la loro implementazione è estremamente ridotta.
La navigazione tra le diverse pagine è gestita
in automatico dalle librerie Tapestry, tramite una serie
di parametri standard.
L'unico ruolo delle servlet è di richiamare un
file application. In pratica quindi servono ad indicare
dove risiede la definizione dell'applicazione all'interno
dell'apposito metodo "protected String getApplicationSpecificationPath()"
import
net.sf.tapestry.ApplicationServlet;
public class ProvaServlet extends ApplicationServlet{
protected String getApplicationSpecificationPath()
{
return "Prova.application";
}
}
Esempio
di ApplicationServlet
Come
si vede il codice all'interno della servlet è
ridotto al minimo. La classe deve estendere ApplicationServlet
(che analizzerà quanto contenuto nel file .application)
contenuta all'interno del package net.sf.tapestry e
non la classica HttpServlet contenuta in javax.servlet.http.
Come
già detto, la definizione dell'applicazione è
contenuta all'interno di un file application che serve
a definire lo spazio dei nomi delle pagine. Ecco un
esempio di file application
<application
name="Prova" engine-class="net.sf.tapestry.engine.SimpleEngine">
<page name="Home" specification-path="Prova.page"/>
<page name="Menu" specification-path="Menu.page"/>
<page name="Principale" specification-path="Principale.page"/>
</application>
La
struttura di un file application è di tipo xml.
E' necessario definire un nome dell'applicazione (che
corrisponderà al nome del file .application in
cui vengono salvate queste informazioni) e associarci
un "motore". Per l'applicazione che andremo
a vedere è più che sufficiente utilizzare
la classe SimpleEngine presente nel package net.sf.tapestry.engine
(è l'unica classe motore che viene fornita insieme
a Tapestry). Tuttavia è possibile definire dei
motori propri estendono la classe AbstractEngine (e
definendo i metodi protected void cleanupAfterRequest(IRequestCycle
cycle) e Collection getActivePageNames() ).
Per ciascuna pagina è poi necessario legare un
nome a ciascun file page (richiamato all'interno del
parametro specification-path). E' importante che esista
una pagina denominata Home, che sarà la pagina
di partenza quando un utente verrà a visitare
il sito. Non è quindi possibile accedere direttamente
delle pagine interne all'applicazione ma è necessario
entrare da tale pagina.
Definizione
delle pagine (file page)
Come per l'applicazione, anche le pagine vengono definite
in file xml. All'interno di questo file vengono definite
diverse componenti che saranno richiamate all'interno
dei template html. Ecco un esempio di definizione di
una pagina
<page-specification
class="net.sf.tapestry.html.BasePage">
<component id="componente1" type="
">
</component>
<component id="componente2" type="
">
</component>
<component id="componenten" type="
">
</component>
</page-specification>
A
ciascuna pagina è necessario associare una classe
che estenda net.sf.tapestry.AbstractPage. Nel nostro
caso (ovvero per lavorare con template html) associamo
la nostra pagina alla classe net.sf.tapestry.html.BasePage.
Se ad esempio volessimo definire un file wml dovremo
associare la nostra pagina alla classe net.sf.tapestry.wml.Deck.
E' quindi in questa fase che Tapestry associa l'applicazione
ad un particolare linguaggio a tag.
Spesso però non è sufficiente utilizzare
la classe BasePage; per inserire parti dinamiche all'interno
della pagina infatti è necessario estendere questa
classe e definire diversi metodi per l'interazione tra
le componenti e le classi java (la spiegazione di ciò
viene rimandata al capitolo sulle componenti e sui binding
dinamici).
Template
(file html)
I template html sono pagine html che possono essere
visualizzate da un normale editor e che contengono,
lì dove vi è la necessità di inserire
contenuti dinamici, tag con attributi jwcid (come visto
in precedenza). Il comportamento a livello dinamico
dipenderà poi dal tipo di componente definito:
ad esempio, nel caso in cui venga richiamata una componente
di tipo Insert, quanto contenuto tra i due tag verrà
rimosso e sostituito con quanto trovato a livello dinamico.
A ciascun file page è associato un file html.
Lo standard di Tapestry impone che il nome del file
page sia lo stesso di quello del template. Anche si
sta lavorando con file non html (ad esempio wml) il
template dovranno essere comunque denominati con estensione
html.
Una
funzionalità estremamente interessante dei template
html è la possibilità di settare il linguaggio
in cui si vuole visualizzare il sito Internet. Questà
possibilità è implementata a partire dalla
classe java.util.Locale (da cui vengono prese le costanti
per la definizione dei diversi linguaggi), lavorando
poi sulla classe IPropertySelectionModel (che permette
di inserire all'interno di una pagina tutti i linguaggi
desiderati e di settare il linguaggio attualmente in
uso).
Una volta settato il linguaggio, Tapestry cercherà
ricorsivamente il template html in base ad una serie
di regole standard di naming. Supponiamo ad esempio
che si voglia visualizzare la pagina francese di un
template HTML di index.html. Tapestry cercherà
prima la pagina index_fr.html, e nel caso in cui non
troverà tale pagina si sposterà ricorsivamente
su index.html. E' possibile anche definire più
sottolinguaggi, ad esempio una persona spagnola che
parla brasiliano (nel cui caso verrà cercato
prima index_es_BR.html, poi index_es.html, infine index.html).
Conclusioni
Tapestry è una tecnologia estremamente interessante.
Si tratta infatti di un ambiente che cerca di aderire
alle nuove tendenze (ed in particolar modo all'xml)
e di essere il più possibile flessibile, sia
rispetto alle tecnologie già esistenti, sia rispetto
a quelle possibili in futuro. I risultati ottenuti a
prima vista sono sicuramente stimolanti, anche se è
necessario utilizzare più da vicino questo prodotto
per rendersi conto dei suoi limiti e delle sue potenzialità.
Certo è che, trattandosi di un prodotto ancora
giovane, sarà necessario seguire da vicino la
sua evoluzione per capire quali potranno essere i suoi
sviluppi futuri.
Bibliografia
[1] Howard Lewis Ship - "Tapestry Tutorial",
http://www.jakarta.org/tapestry
[2] Howard Lewis Ship - "Tapestry API", http://www.jakarta.org/tapestry
[3] Howard Lewis Ship - "Tapestry Developer's Guide
", http://www.jakarta.org/tapestry
[4] Howard Lewis Ship - "Tapestry Component Reference",
http://www.jakarta.org/tapestry
|