SeamFramework.orgCommunity Documentation
Seam supporta Wicket come uno strato di presentazione alternativo a JSF. Si guardi l'esempio wicket
in Seam che illustra l'esempio Booking riscritto per Wicket.
Il supporto Wicket è nuovo in Seam, perciò alcune caratteristiche che sono disponibili in JSF non sono ancora disponibili quando viene usato Wicket (ad esempio il pageflow). Si potrà notare inoltre che la documentazione è molto centrata su JSF e necessita di una riorganizzazione per riflettere il supporto di prima categoria per Wicket.
Le caratteristiche aggiunte ad un'applicazione Wicket possono essere divise in due categorie: la bijection e l'orchestrazione. Esse vengono discusse in dettaglio di seguito.
E' comune un uso intensivo di classi interne (inner class) quando si costruisce un'applicazione Wicket, in cui l'albero dei componenti viene generato nel costruttore. Seam gestisce pienamente l'uso di annotazioni di controllo nelle inner class e nei costruttori (a differenza che nei componenti Seam normali).
Le annotazioni sono elaborate dopo ogni chiamata alla superclasse. Ciò significa che qualsiasi attributo iniettato non può essere passato come argomento in una chiamata a this()
o super()
.
Stiamo lavorando per migliorare questo aspetto.
Quando un metodo è chiamato in una inner class, la bijection avviene per ogni classe che la contiene. Ciò consente di posizionare le variabili bi-iniettabili nella classe esterna e riferirsi ad esse in qualsiasi inner class.
Un'applicazione Wicket abilitata per Seam ha accesso completo a tutti i contesti Seam standard (EVENT
, CONVERSATION
, SESSION
, APPLICATION
e BUSINESS_PROCESS
).
Per accedere ai componenti Seam da Wicket basta iniettarli usando @In
:
@In(create=true)
private HotelBooking hotelBooking;
Poiché la classe Wicket non è un componente Seam completo, non c'è bisogno di annotarla con @Name
.
E' anche possibile fare l'outject di un oggetto da un componente Wicket nei contesti Seam:
@Out(scope=ScopeType.EVENT, required=false)
private String verify;
TODO Rendere questa parte più orientata allo use case
E' possibile abilitare la sicurezza di un componente Wicket usando l'annotazione @Restrict
. Questa può essere messa nel componente più esterno o in qualsiasi componente interno. Se viene indicato @Restrict
, l'accesso al componente verrà automaticamente limitato agli utenti registrati. Facoltativamente è possibile usare un'espressione EL nell'attributo value
per specificare la restrizione da applicare. Per maggiori dettagli vedi Capitolo 15, Sicurezza.
Ad esempio:
@Restrict
public class Main extends WebPage {
...
Seam applicherà automaticamente la restrizione ad ogni classe interna.
E' possibile demarcare le conversazioni da un componente Wicket attraverso l'uso di @Begin
e @End
. La semantica di queste annotazioni è la stessa di quando sono usate nei componenti Seam. E' possibile mettere @Begin
e @End
in qualsiasi metodo.
L'attributo deprecato ifOutcome
non è gestito.
Ad esempio:
item.add(new Link("viewHotel") {
@Override
@Begin
public void onClick() {
hotelBooking.selectHotel(hotel);
setResponsePage(org.jboss.seam.example.wicket.Hotel.class);
}
};
E' possibile che l'applicazione abbia delle pagine che possono essere visitate solo quando l'utente ha una conversazione lunga (long-running conversation) attiva. Per imporre questo criterio è possibile usare l'annotazione @NoConversationPage
:
@Restrict @NoConversationPage(Main.class) public class Hotel extends WebPage {
Se si vogliono ulteriormente disaccoppiare le classi dell'applicazione è possibile usare gli eventi Seam. Naturalmente è possibile lanciare un evento usando Events.instance().raiseEvent("pippo")
. In alternativa è possibile annotare un metodo con @RaiseEvent("pippo")
; se il metodo restituisce un valore non nullo senza eccezioni, l'evento verrà lanciato.
E' anche possibile controllare task e processi nelle classi Wicket attraverso l'uso di @CreateProcess
, @ResumeTask
, @BeginTask
, @EndTask
, @StartTask
e @Transition
.
TODO - Realizzare il controllo BPM - JBSEAM-3194
Seam deve istruire il bytecode (instrumentare) delle classi Wicket per poter intercettare le annotazioni da usare. La prima decisione da compiere è: si vuole istruire il codice a runtime quando l'applicazione è in esecuzione oppure a compile time? Il former non richiede integrazioni con il proprio ambiente di build, ma ha dei problemi di performance quando ciascuna classe viene instrumentata per la prima volta. L'ultima è più veloce, ma richiede di integrare quest'instrumentazione nel proprio ambiente di build.
Ci sono due modi per ottenere l'instrumentazione a runtime. Uno colloca i componenti wicket da instrumentare in una speciale cartella nel deploy WAR. Se questo non è accettabile o possibile, si può usare l'"agente" di instrumentazione, che si specifica tramite linea di comando quando si lancia il container.
Qualsiasi classe collocata nella cartella WEB-INF/wicket
dentro il deploy WAR verrà automaticamente instrumentata dal runtime seam-wicket. Si possono collocare qua le pagine ed i componenti wicket specificando una cartella di output separata per quelle classi nel proprio IDE, o attraverso l'uso di script ant.
Il file jar jboss-seam-wicket.jar
può essere usato come agente di instrumentazione attraverso la Java Instrumentation API . Questo viene ottenuto attraverso i seguenti passi:
Si faccia in modo che il file jboss-seam-wicket.jar
"viva" in una posizione in cui si abbia un percorso assoluto, poiché la Java Instrumentation API non consente percorsi relativi quando si specifica la locazione di una libreria agent.
Si aggiunga javaagent:/path/to/jboss-seam-wicket.jar
alle opzioni da linea di comando quando si lancia il container webapp:
Inoltre occorrerà aggiungere una variabile d'ambiente che specifichi i pacchetti che l'agente deve instrumentare. Questo si ottiene con una lista di nomi di pacchetti separati da una virgola:
-Dorg.jboss.seam.wicket.instrumented-packages=my.package.one,my.other.package
Si noti che se viene specificato un pacchetto A, vengono esaminate anche le classi nei sottopacchetti di A. Le classi scelte per l'instrumentazioni possono essere ulteriormente limitate specificando:
-Dorg.jboss.seam.wicket.scanAnnotations=true
e poi marcando le classi instrumentabili con l'annotazione @SeamWicketComponent
, si veda Sezione 12.2.3, «L'annotazione @SeamWicketComponent
».
Seam supporta l'instrumentazione a compile-time attraverso Apache Ant o Apache Maven.
Seam fornisce un task ant in jboss-seam-wicket-ant.jar
. Viene usato nel seguente modo:
<!-- XML : generated by JHighlight v1.0 (http://jhighlight.dev.java.net) --> <span class="xml_tag_symbols"><</span><span class="xml_tag_name">taskdef</span><span class="xml_plain"> </span><span class="xml_attribute_name">name</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"instrumentWicket"</span><span class="xml_plain"> </span><br /> <span class="xml_plain"> </span><span class="xml_attribute_name">classname</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"org.jboss.seam.wicket.ioc.WicketInstrumentationTask"</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">classpath</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">pathelement</span><span class="xml_plain"> </span><span class="xml_attribute_name">location</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"lib/jboss-seam-wicket-ant.jar"</span><span class="xml_tag_symbols">/></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">pathelement</span><span class="xml_plain"> </span><span class="xml_attribute_name">location</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"web/WEB-INF/lib/jboss-seam-wicket.jar"</span><span class="xml_tag_symbols">/></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">pathelement</span><span class="xml_plain"> </span><span class="xml_attribute_name">location</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"lib/javassist.jar"</span><span class="xml_tag_symbols">/></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">pathelement</span><span class="xml_plain"> </span><span class="xml_attribute_name">location</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"lib/jboss-seam.jar"</span><span class="xml_tag_symbols">/></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">classpath</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols"></</span><span class="xml_tag_name">taskdef</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"></span><br /> <span class="xml_tag_symbols"><</span><span class="xml_tag_name">instrumentWicket</span><span class="xml_plain"> </span><span class="xml_attribute_name">outputDirectory</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"${build.instrumented}"</span><span class="xml_plain"> </span><span class="xml_attribute_name">useAnnotations</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"true"</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">classpath</span><span class="xml_plain"> </span><span class="xml_attribute_name">refid</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"build.classpath"</span><span class="xml_tag_symbols">/></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">fileset</span><span class="xml_plain"> </span><span class="xml_attribute_name">dir</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"${build.classes}"</span><span class="xml_plain"> </span><span class="xml_attribute_name">includes</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"**/*.class"</span><span class="xml_tag_symbols">/></span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols"></</span><span class="xml_tag_name">instrumentWicket</span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols">></span><span class="xml_plain"></span><br />
Questo ha effetto nelle classi instrumented che vengono messe nella directory specificata da ${build.instrumented}
.Occorre poi fare in modo che Ant copi le classi alterate da ${build.instrumented}
a WEB-INF/classes
. Se si vuole attivare l'esecuzione a caldo dei componenti Wicket è possibile copiare le classi alterate in WEB-INF/hot
. Se si usa l'esecuzione a caldo, accertarsi che anche la classe WicketApplication
sia eseguita nello stesso modo. Dopo che le classi eseguite a caldo vengono ricaricate, l'intera istanza di WicketApplication deve essere reinizializzata allo scopo di recuperare tutti i nuovi riferimenti alle classi delle pagine montate.
L'attributo useAnnotations
è usato per fare includere al task ant solo le classi marcate con l'annotazione @SeamWicketComponent
, si veda Sezione 12.2.3, «L'annotazione @SeamWicketComponent
».
Il repository maven repository.jboss.org
fornisce un plugin chiamato seam-instrument-wicket
con un mojo process-classes
. Un esempio di configurazione del proprio pom.xml potrebbe essere:
<!-- XML : generated by JHighlight v1.0 (http://jhighlight.dev.java.net) --> <span class="xml_tag_symbols"><</span><span class="xml_tag_name">build</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">plugins</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">plugin</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">groupId</span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols">></span><span class="xml_plain">org.jboss.seam</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">groupId</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">artifactId</span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols">></span><span class="xml_plain">seam-instrument-wicket</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">artifactId</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">version</span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols">></span><span class="xml_plain">2.1.2</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">version</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">configuration</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">scanAnnotations</span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols">></span><span class="xml_plain">true</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">scanAnnotations</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">includes</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">include</span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols">></span><span class="xml_plain">your.package.name</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">include</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">includes</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">configuration</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">executions</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">execution</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">id</span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols">></span><span class="xml_plain">instrument</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">id</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">phase</span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols">></span><span class="xml_plain">process-classes</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">phase</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">goals</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">goal</span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols">></span><span class="xml_plain">instrument</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">goal</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">goals</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">execution</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">executions</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">plugin</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">plugins</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols"></</span><span class="xml_tag_name">build</span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols">></span><span class="xml_plain"></span><br />
L'esempio di cui sopra illustra che l'instrumentazione è limitata alle classi specificate dall'elemento includes
. In quest'esempio, viene specificato scanAnnotations
, si veda Sezione 12.2.3, «L'annotazione @SeamWicketComponent
».
Le classi posizionate in WEB-INF/wicket verranno instrumentate incondizionatamente. L'altro meccanismo di instrumentazione consente di specificare che l'instrumentazione venga applicata soltanto alle classi annotate con @SeamWicketComponent
. Quest'annotazione viene ereditata, il che significa che tutte le sottoclassi di una classe annotata verranno instrumentate. Un esempio di utilizzo è:
<!-- <br/> --><span class="java_keyword">import</span><!-- <br/> --><span class="java_plain"> org</span><!-- <br/> --><span class="java_separator">.</span><!-- <br/> --><span class="java_plain">jboss</span><!-- <br/> --><span class="java_separator">.</span><!-- <br/> --><span class="java_plain">seam</span><!-- <br/> --><span class="java_separator">.</span><!-- <br/> --><span class="java_plain">wicket</span><!-- <br/> --><span class="java_separator">.</span><!-- <br/> --><span class="java_plain">ioc</span><!-- <br/> --><span class="java_separator">.</span><!-- <br/> --><span class="java_type">SeamWicketComponent</span><!-- <br/> --><span class="java_separator">;</span> <!-- --><br/><span class="java_plain">@</span><span class="java_type">SeamWicketComponent</span> <!-- --><br/><span class="java_keyword">public</span><span class="java_plain"> </span><span class="java_keyword">class</span><span class="java_plain"> </span><span class="java_type">MyPage</span><span class="java_plain"> </span><span class="java_keyword">extends</span><span class="java_plain"> </span><span class="java_type">WebPage</span><span class="java_separator">{</span> <!-- --><br/><span class="java_plain"> </span><span class="java_separator">...</span> <!-- --><br/><span class="java_separator">}</span>
Un'applicazione web Wicket che usa Seam deve usare SeamWebApplication
come classe base. Questa crea gli agganci nel ciclo Wicket che consentono a Seam di propagare auto-magicamente la conversazione quando necessario. Aggiunge pure i messaggi di stato alla pagina.
Ad esempio:
La SeamAuthorizationStrategy
delega le autorizzazioni a Seam Security, consentendo l'uso di @Restrict
nei componenti Wicket. SeamWebApplication
provvede ad installare la strategia di autorizzazioni. E' possibile specificare una pagina di login implementando il metodo getLoginPage()
.
C'è poi bisogno di impostare la home page dell'applicazione implementando il metodo getHomePage()
.
public class WicketBookingApplication extends SeamWebApplication {
@Override
public Class getHomePage() {
return Home.class;
}
@Override
protected Class getLoginPage() {
return Home.class;
}
}
Seam installa automaticamente il filtro Wicket (assicurando che sia inserito nella posizione corretta), ma è ancora necessario indicare a Wicket quale classe WebApplication
usare:
<components xmlns="http://jboss.com/products/seam/components"
xmlns:wicket="http://jboss.com/products/seam/wicket"
xsi:schemaLocation=
"http://jboss.com/products/seam/wicket
http://jboss.com/products/seam/wicket-2.1.xsd">
<wicket:web-application
application-class="org.jboss.seam.example.wicket.WicketBookingApplication" />
</components
In aggiunta se si pensa di usare le pagine basate su JSF in un'appliczione con pagine wicket, bisogna assicurarsi che il filtro delle eccezioni jsf sia abilitato per gli url jsf:
<components xmlns="http://jboss.com/products/seam/components"
xmlns:web="http://jboss.com/products/seam/web"
xmlns:wicket="http://jboss.com/products/seam/wicket"
xsi:schemaLocation=
"http://jboss.com/products/seam/web
http://jboss.com/products/seam/web-2.1.xsd">
<!-- Si mappa solo il filtro per le eccezioni jsf di seam nel path jsf, che viene identificato con il path *.seam -->
<web:exception-filter url-pattern="*.seam"/>
</components
Per maggiori informazioni sulle strategie di autorizzazione e gli altri metodi che possono essere implementati sulla classe Application
fare riferimento alla documentazione Wicket.