In questo capitolo sono descritte le scelte di design che sono alla base del codice generato da guigen, con le principali cartucce di generazione, ovvero:
E' l'architettura base, quella che viene generata se si utilizza la cartuccia struts2 senza l'abilitazione delle funzionalità ricche. Si tratta di una classica applicazione web realizzata in tecnologia J2EE (compatibile con i runtime WLS 9.2 e JBoss 4.3, JBoss 6.0, JBoss 6.2). I framework utilizzati sopra lo strato J2EE per la realizzazione del core dell'applicazione sono:
L'applicazione può interagire con sistemi esterni tramite accesso a servizi. Inoltre, a seconda della modalità di autenticazione/accesso modellate, l'architettura sarà completata con l'integrazione opportuna con i sistemi di SSO/security.
Per l'implementazione dello strato di accesso ai dati è possibile utilizzare datagen, che si innesta nell'architettura complessiva nello strato spring. In alternativa è possibile utilizzare un backend SOA.
Ad ogni ContentPanel corrispondono i seguenti elementi del design target:
Questa scelta di mapping tra il concetto di ContentPanel e gli elementi dei framework utilizzati si discosta alquanto dalle modalità più frequentemente utilizzate con il framework struts (che tipicamente non prevedono questa "monoliticità" sistematica relativamente alla schermata ma una serie più liberamente composta di coppie action->view destinazione) e si ispira in modo più netto a meccanismi tipici del mondo dei fat-client. La scelta dipende principalmente da una migliore gestibilità della generazione del codice e dalla maggior facilità di riutilizzare questo modello nelle architetture estese (entriched e fat-client).
A fronte di questa scelta il flusso di navigazione tra schermate è realizzato sempre tramite il meccansimo di chaining delle action di struts: in pratica, supponendo:
handle_B1_CLICKED()) sulla action associata alla schermata S1, e questo comporta:
prepare() della action associata alla schermata
S1, ovvero l'esecuzione della logica associata
all'evento implicito di refresh della schermata S1 (viene eseguito il "programma"
di comandi modellato come onRefreshCommand)execute()) il che comporta:
prepare()) della action associata alla schermata
S2)La logica di business è modellata secondo il pattern command, nei vari punti in cui questo è previsto (inizializzazione dell'applicazione, refresh della schermata, event handler, ingresso o inizializzaizone di una schermata, ...). A livello di codice generato il pattern command è implementato come segue:
String doCommand();
doCommand() del primo
comando della catena, che comporterà:
doCommand()) ad
un eventuale comando successore (se previsto dalla tipologia di comando e dalla logica
di controllo)Lo stato di un'applicazione guigen è definito dalla valorizzazioen dell'insieme degli ApplicationData accessibili ad un certo istante in una certa schermata, ovvero:
Lo stato di visibilità o abilitazione dei singoli widget è un'informazione necessaria allo strato JSP per decidere che tipo di rendering utilizzare per essi. Tale informazione è messa a disposizione della JSP da un apposita coppia di metodi disponibili su tutte le action associate ai vari ContentPanel:
isWidgetEnabled(<id del widget>)isWidgetVisible(<id del widget>)Il rendering delle varie schermate è realizzato tramite pagine JSP. Esiste una JSP per ogni ContentPanel. Tale JSP principale può essere a sua volta strutturata mediante il meccanismo dell'inclusione in frammenti destinati a coprire particolari esigenze di rendering, quali ad esempio:
La composizione delle schermate (ovvero il reale contenuto finale della pagina html) dipende dal portale target. Attualmente esistono due grossi filoni:
Relativamente alla modalitè "neutral", esistono poi due possibilitè di referenziazione delle risorse grafiche (immagini, css):
E' un'estensione dell'architettura base destinata ad assolvere a alcuni requisiti funzionali aggiuntivi, tipicamente descritti nel catalogo dei widget come modalità ricca, e sintetizzabili come segue:
Per l'implementazione di tali funzionalità aggiuntive viene usato pesantemente codice Javascript che gira nel browser dell'utente: solo in questo modo infatti à possibile eseguire le logiche client-side necessarie. Al fine di garantire l'utilizzabilità dell'applicazione anche a chi non dovesse utilizzare un browser compatibile con tale linguaggio è previsto un meccanismo di downgrade funzionale automatico che, in pratica, permette di utilizzare l'applicazione nella modalità prevista dall'architettura base. Tale meccanismo di basa sul rilevamento client-side della disponibilità del linguaggio javascript e la differenziazione server side del rendering a seconda che tale rilevamento abbia fornito un esito positivo o negativo. Il risultato ottenuto è che l'utente riuscirà comunque a svolgere le funzionalit� principali rinunciando però necessariamente alle sotto-funzionalità ausiliarie.
Le scelte di design di questo tipo di architettura sono additive rispetto a quelle dell' architettura base.
L'implementazione delle funzionalità "ricche" dal lato client è realizzata con un meccanismo denominato arricchimento della U.I, che è il seguente: si parte dalla struttura di U.I prevista dall'architettura base e, per i widget ove questo sia previsto, viene messo in opera una modifica client-side di tale widget; questa modifica ne determina l'arricchimento ch edà il nome al meccanismo. Alcuni esempi di arricchimento:
Affinchè l'effetto di arricchimento delle singole porzioni di schermata sia quello desiderato questo deve essere applicato nei momenti corretti e il nomero di volte corrette. Al fine di garantire questo corretto comportamento gli arricchimenti relativi ad un singolo ContentPanel sono registrati (con indicazione del frammento "affetto"). Il registro così ottenuto può essere perciò utilizzato per applicare selettivamente gli arricchimenti:
Rispetto alla architettura base la modalità enriched webapp prevede la creazione di una serie di metodi denominati di data provider:
provide_<nome_widget>_DATASET()dataProviderStreamQuesti metodi data provider sono utilizzati pesantemente nella modalità fat client. La scelta di farli generare già nell'architettura enriched webapp è stata effettuata per permettere eventuali implementazioni custom. Sono invece direttamente utilizzati nell'implementazione della funzionalità di suggestion del TextField: al termine dell'esecuzione della logica necessaria per effettuare l'estrazione dei dati da restituire all'utente come suggestion, invece di restituire direttamente il codice del result, il metodo handler delega l'esecuzione al metodo data provider del widget, il quale provvede a restituire allo strato client l'elenco dei suggerimenti in formato JSon.
L'implementazione del metodo handler relativo alla funzionalità di suggestion su TextField (ovvero quella relativa all'evento KEY_PRESSED associato al campo di testo) differisce leggermente rispetto alla modalità normale: al termine dell'esecuzione della catena di comandi, infatti, il controllo viene passato al metodo data provider che provvede a fornire al widget client side l'elenco delle suggestion in formato JSon
E' un'estensione dell'architettura enriched webapp che permette una implementazione alternativa dello strato di U.I, che sposta sul client una gran parte della logica di rendering; proprio per questo si parla di architettura fat webapp. Di fatto lo strato di View+Controller si sposta totalmente sul client e si trasforma in uno strato costituito da componenti di user interface che interagiscono con il lato server (business logic + front-controller) principalmente in modalità AJAX. Tale strato server, di fatto, non fornisce più in risposta al client un rendering preconfezionato (html) ma fornisce informazioni (dati applicativi e non) destinate a popolare i widget che compongono la schermata.
E'importante notare come questa tipologia architetturale possa essere implementata con differenti tecnologie client di componentizzazione di interfaccia: l'unico vincolo è che le tecnologie candidate siano in grado di implementare le (semplici) specifiche di interazione con lo strato server. Allo stato attuale la tecnologia client utilizzata è basata sulle librerie ExtJS (linguaggio javascript), ma sarebbe ugualmente possibile, ad esempio, ottenere una implementazione basata su Adobe Flex o java swing, ...
Rispetto all'architettura base i cambiamenti sono pochi e additivi. Viene mantenuta l' associazione tra ciascun ContentPanel la action di struts corrispondente, mentre lo strato di pura view viene implementato con un unico modulo JS che contiene tutta la struttura dell'applicazione.
Rispetto all'architettura base nella modalità fat-client vi è una differente ripartizione sui vari tier architetturali della responsabilità di esecuzion delle catene di comandi. Infatti, mentre nell'architettura base la responsabilità completa dell'esecuzione dei comandi è affidata allo strato server (struts + spring), nella modalità fat si verifica una differente ripartizione delle responsabilità, guidata da alcuni criteri precisi:
Al fine di realizzare la differente ripartizione di responsabilit� nell'esecuzione dei comandi (descritta al paragrafo precedente) è necessario introdurre in ciascuna action una ulteriore serie di metodi, detti di exec command che hanno l'unico scopo di esporre allo strato di componenti client i metodi di business disponibili nello strato spring. Se, durnate l'esecuzione di una catena di comandi lato client, lo step corrente comprenderà un ExecCommand, l'esecuzione del metodo di business associato verr&agravE; delegata allo strato server, che restituirà successivamente le informazioni necessarie per aggiornare i widget (con i dati modificati per effetto dell'esecuzione della business logic).
In questa architettura sono utilizzati pesantemente i metodi cosiddetti di data provider introdotti già nell'architettura arricchita per tutti i widget che sono associati ad una collezione/fonte dati. Esempi:
Il client ha inoltre a disposizione una nuova tipologia di metodo di data provider, associato
all'intero ContentPanel: il metodo provide_CPDATA() ha infatti il
compito di restituire allo strato client il contenuto degli ApplicationData da utilizzare per popolare i valori dei vari widget coerentemente con lo
stato applicativo. Sono esclusi i dati di tipo collection che sono invece forniti dagli specifici
metodi di data provider. La combinazione di queste due tipologie di metodi di fornitura
dati permette di mantenere lo stato dell'applicazione sul server e trasferire sul client solo
le informazioni necessarie.
Il flusso tra due schermate differenti è realizzato caricando i componenti JS relativi alla schermata target, come effetto dei comandi di navigazione (JumpCommand).