Guigen - overview
Introduzione
versione: 3.3.0
GUIGEN è un generatore model-driven di front-end applicativi.
Permette la generazione di applicazioni a partire da un modello dichiarativo dell'applicazione e con l'aggiunta manuale
di codice custom a completamento della logica di business (principalmente per la realizzazione dell'interazione con il backend, con
servizi esterni o con risorse quali DBMS).
Il modello che descrive l'applicazione è:
Il modello cosè definito ricopre vari aspetti di una applicazione:
- caratteristiche strutturali
- struttura delle schermate
- struttura dei menu delle funzionalità
- caratteristiche dinamiche
- flusso tra le schermate
- eventi associati ai vari componenti di controllo (menu, pulsanti, etc.)
- azioni (comandi) scatenate a fronte di un evento su un componente di controllo
- modifica stato dei widget (disabilitazione/visibilit�, ...)
- caratteristiche di binding dati
- definizione di strutture dati (model)
- binding bidirezionale tra widget e dati del model
Il metamodello secondo il quale occorre modellare l'applicazione è indipendente da una particolare modalità/tecnologia
di realizzazione dell'applicazione, utilizzando concetti generali (es. widget, event-handler, panels) e non technology-specific
(es. submit, JTree, ...): di conseguenza il generatore GUIGEN può in linea teorica generare un'applicazione modellata secondo tale
metamodello utilizzando differenti tecnologie di implementazione.
Attualmente il target di generazione è rappresentato da una web-application J2EE compliant con l'attuale framework applicativo basato
su tecnologie Servlet/JSP e framework struts2/spring. Dalla versione 2.4.0 è possibile generare:
- un EAR deployabile in application server JBoss (4.3, EAP 6.4.x) o Weblogic9.2
Per approfondimenti circa il mapping tram modello GUIGEN e piattaforma specifica
(ovvero per comprendere meglio le regole di generazione del codice a fronte del metamodello, è
possibile consultare la sezione design rationale.
Browser supportati
Allo stato attuale è garantito il supporto per i seguenti browser internet:
| browser | versione | livello di supporto |
| internet explorer | 7 e 8 |
- Tutte le funzionalità di base sono supportate
- Tutte le funzionalità ricche sono supportate
|
| mozilla firefox | 3.6.x |
- Tutte le funzionalità di base sono supportate
- Tutte le funzionalità ricche sono supportate
|
Per i seguenti browser, invece è previsto un supporto parziale (con qualche limitazione di
funzionalità e con la possibilità di alcuni malfunzionamenti di carattere "cosmetico")
| browser | versione | livello di supporto |
| internet explorer | 6 |
- Tutte le funzionalità di base sono supportate
- Potrebbero essere presenti alcune imperfezioni grafiche minori
- Tutte le funzionalità ricche sono supportate ma la velocità
di composiziobe della pagina arricchita è minore rispetto ai browser più
moderni: questo crea un effetto di "composizone progressiva" della schermata
(della durata complessiva proporzionale alla complessità della pagina e dell'ordine
comunque di frazioni di secondo)
- Esistono alcune particolari situazioni (non riconducibili all'operatività)in cui potrebbero
verificarsi malfunzonamenti della visualizzazione.
|
Poichè l'evoluzione delle tecnologie di navigazione internet è molto rapida e sovente
non è facile limitare la varietà di browser utilizzati dall'utente finale (specie in
caso di utenza di tipo internet, è previsto un costante piano di verifica e, se
necessario, adeguamento degli strumenti in modo da garantire il più vasto possibile bacino di utenza.
Occorre però tenere conto che tale adeguamento non è immediato e di questa inevitabile
latenza devono tenere conto i progetti.
Funzionalità
Di seguito sono elencate le principali funzionalità messe a disposizione dal generatore GUIGEN.
Definizione della struttura della User Interface dell'applicativo
La U.I dell'applicazione è organizzata in alcune aree prinicpali:
- un header e un footer che contengono informazioni statiche non gestite da applicativo (che in genere sono determinate dalla
collocazione di un applicativo in un particolare contesto (es. sito web) e che non varia da applicazione ad applicazione
- una area applicativa ApplicationArea che dipende dalla particolare applicazione. A sua volta questa area applicativa �
strutturata in:
- una struttura a menu (MenuBar)
- un'insieme di schermate applicative (ContentPanel) che si avvicendano a fronte del flusso funzionale dell'applicativo e sono
visualizzate all'interno dell'area invariante (header, footer). Il menu � gestito come widget in modo da poter essere collocato
in tutte le schermate.
Ciascuna schermata contiene Widget di vario genere strutturati in pannelli (Panel) che possono essere dei seguenti tipi:
- CommandPanel: tipo specializzato di Panel che pu� contenere solo widget di tipo Command (pulsanti)
- DialogPanel: pannello utilizzato per la visualizzazione di popup
- FormPanel: pannello destinato a contenere esclusivamente sottopannelli
- MenuPanel: tipo specializzato di Panel che pu� contenere solo widget di tipo menu o affini (attualmente
solo MenuView o TreeView).
- MsgBoxPanel: pannello utilizzabile per la visualizzazione di messaggi o html custom (pu� contenere soloun tipo di widget: il PlainText
- MultiPanel: Pannello mutevole: pu� assumere differenti forme in base ai sottopannelli contenuti (il contenuto di ciascun sottopannello è a sua volta un pannello)
- PanelDefUse: Utilizzo di pannello definito esternamente: permette la definizione di frammenti di U.I. riusabili in più modelli / punti del modello.
- StdMessagePanel: pannello di visualizzazione di messaggi (di errore ed informativi)
- TabSetPanel: il classico pannello a tab (il contenuto di ciascun tab è a sua volta un pannello)
- UserInfoPanel: pannello utilizzato pe rmostrare in modo standard le informazioni relative all'utente collegato
- UserDefinedPanel: pannello altamente personalizzabile (inclusione di sorgente hand written)
da utilizzare in casi molto particolari
- WidgetsPanel: tipo specializzato di Panel destinato a contenere esclusivamente widget
- WizardPanel: implementazione di wizard (il contenuto di ciascuno step è a sua volta un pannello)
Ciascun singolo pannello prevede uno schema di layout (selezionabile in un insieme di possibilità) secondo cui i sottopannelli
e i widget vengono disposti:
- Disposizione a cascata verticale su un'unica colonna (VerticalFlowPanelLayout);
- applicabile a sottopannelli e widget;
- l'ordine di visualizzazione � dall'alto in basso a seconda dell'ordine in cui i componenti appaiono nel modello (non sono
necessarie delle layout specification aggiuntive);
-
Disposizione in sequenza orizzontale left to right su un'unica riga (HorizontalFlowPanelLayout)
- applicabile a sottopannelli e widget;
- l'ordine di visualizzazione � dasinistra a destra a seconda dell'ordine in cui i componenti appaiono nel modello (non sono
necessarie delle layout specification aggiuntive;
-
Disposizione a 5 quadranti (UpDownLeftRightCenterPanelLayout)
- applicabile al pannello principale, al command panel (in questo caso sono disponibili solo le posizioni Left e Right e
servono per implementare plusantiere di navigazione del tipo indietro-prosegui) e ai FormPanel (disponibile solo per le cartucce
di layout "neutral" e "nuova rupar");
- può contenere al massimo 5 sottopannelli, 1 al massimo per sezione, ed è necessario specificare
esplicitamente per ciascun elemento il quadrante di destinazione (mediante una UDLRCWidgetLayoutSpec);
-
Disposizione a griglia nXm (GridPanelLayout)
- applicabile solo a sottopannelli
- può contenere al max. n X m widget (uno per cella della griglia - ogni widget
comprende tutti gli elementi grafici utili a realizzarlo, quali label, widget vero e proprio etc..)
- per ciascun widget è possibile specificare con precisione la posizione nella griglia e, opzionalmente, il numero di colonne
per cui la porzione non-label del widget si deve estendere (1 colonna = 1 posto per un widget completo, indipendentemente
dal numero di elementi grafici utilizzati nel codice generato.
I widget disponibili condividono alcuni comportamenti comuni:
- possono essere disabilitati o abilitati a comando (abiltazione/disabilitazione/stato di default, comandabile singolarmente o utilizzando un concetto di ScreenState): se disabilitati non possono
accettare input o comandi dall'utente e, se previsto dallo skin del portale, assumono un'apparenza
grafica differente;
- possono essere resi invisibili/visibili a comando (visibile/invisibile/stato di default, comandabile singolarmente o utilizzando un concetto di ScreenState): se invisibili non
vengono renderizzati nella schermata;
- possono essere visibili/invisibili o abilitati/disabilitati a fronte di Security constraints che possono essere
o meno soddisfatti per l'utente correntemente collegato all'applicazione;
- possono essere posizionati con precisione nel pannello contenitore utilizzando una parametrizzazione specifica
del tipo di layout del contenitore (vedi sopra);
- possono essere corredati da un EventHandler in grado di gestire eventi di interazione umana (per l'elenco delle tipologie
di eventi supportate da ciascun widget e per dettagli sulla gestione degli eventi si vedano le sezioni apposite);
Widget disponibili
- CommandWidget: classe di widget che hanno lo scopo principale di gestire comandi utente. I CommandWidget condividono la possibilità
di catturare eventi di user interaction (vedere sotto). Sono disponibili i seguenti widget:
- Pulsanti (ConfirmButton) che permettono l'esecuzione di una serie di azioni/comandi
- Pulsanti che permettono la pulizia della schermata senza esecuzione di nessuna logica applicativa (ResetButton)
- Select list: selezione singola o multipla da una lista di valori (ComboBox)
- Radio button: pulsanti a selezione esclusiva (RadioButtons/RadioButton)
- Comandi di navigazione di TabSet e Wizard (TabSwitcher, widget implicito)
- Menu (la struttura è definita centralmente nell'applicativo; questo widget è solo un segnaposto necessario per
collocare il menu all'interno della schermata)
- DataWidget: widget destinati all'input/output di informazioni.
- condividono alcuni comportamenti comuni aggiuntivi rispetto ai widget generici:
- sono dotati di un tipo del dato associato
- prevedono la possibilità di effettuare una serie di validazioni sull'input immesso
- possono essere collegati al model mediante appositi binding (AppDataBinding)
- possono essere valorizzati in base allo stato delle variabili (ApplicationData) dell'applicazione
- possono passare l'informazione immessa dall'utente ai moduli di logica applicativa (esclusi Image, PlainText)
- alcuni di essi possono essere anche dei CommandWidget (es. Table, ComboBox, RadioButton)
- sono disponibili i seguenti widget:
- Campi di immissione testo monolinea (TextField) o multilinea (TextArea)
- Drop-down list (ComboBox) con possibilità di funzionamento a selezione
singola o multipla
- Pulsante on-off (Check Box)
- Pulsanti a scelta esclusiva in un insieme di opzioni definite a tempo di design (RadioButton)
- Tabella di visualizzazione (Table) con possibilit� di:
- ordinamento
- paginazione
- export dei dati in vari formati (pdf, xls)
- selezione di una o più righe per l'esecuzione di un'azione su di esse
- editing "in place" di una cella con diversificazione della modalità di editing a fronte del tipo di dato della
colonna:
- textfield in caso di tipo Stringa
- checkbox in caso di tipo boolean
- editing in place con possibilità di selezionare il valore in una lista di opzioni, che possono essere le stesse per
tutte le righe oppure diversificate riga per riga
- possibilitè di rendere o meno editabile a seconda di condizioni valutate a runtime una singola cella
ordinamento, paginazione, export dei dati in vari formati, selezione di
una o più righe per l'esecuzione di un'azione su di esse, editing "in place" di una cella con diversificazione
- Albero espandibile (TreeView)
- Immagine (Image)
- Testo puro (PlainText, widget per sola visualizzazione)
- Tool di selezione data (Calendar)
Maggiori dettagli riguardo alle modalità di strutturazioen della user interface sono disponibili
qui.
Strutturazione modulare della GUI
E'possibile utilizzare per la strutturazione della User Interface un approccio componentizzato: è infatti possibile:
- definire un pannello riusabile (con eventuale strutturazione in sottopannelli, binding, event handlers e comandi associati)
- utilizzare tali pannelli nel modello dell'applicazione, contestualizzandoli (ridefinizione degli application data collegati ai widget,
ridefinizione di Actor/Roles/UseCases referenziati nei security constraints).
Funzionalità di Rich user experience (stile web2.0 - funzionalità sperimentale)
Se abilitate, sono disponibili alcune funzionalità di arricchimento della user-experience.
Attualmente le funzioni previste sono le seguenti:
- refresh selettivo di una porzione di schermata (per aggiornare i dati o visualizzare un tab o un
pannello mutevole senza ricaricare l'intera pagina)
- ordinamento delle righe di una Table senza ricaricare l'intera schermata
- comparsa di tooltip sulle label dei widget a fronte del passaggio con il mouse sopra la label stessa
- comparsa di tooltip sull'intestazione delle colonne di una Table a fronte del passaggio con il mouse sopra l'header stesso
- possibilità di ridimensionare, nascondere, spostare le colonne di una Table
- maschera di immissione dati nei campi di testo coerenti con il tipo di dato associato al widget (es. solo
caratteri numerici se il tipo è numerico)
- autocompletamento progressivo della selezione di una ComboBox a fronte dell'immissione dei
caratteri iniziali della selezione stessa
- suggestion su TextField con interazione server-side per effettuare la selezione progressiva delle
voci suggerite a fronte dell'immissione testuale
Securizzazione dell'applicativo
E' possibile modellare la maggior parte delle caratteristiche di sicurezza dell'applicazione:
- Autenticazione: è possibile definire il meccanismo utilizzato per l'autenticazione, scegliendolo tra:
- Autenticazione in single sign on tramite SSOBART
- Autenticazione in single sign on tramite Oracle Portal - OPAUTH
- Autenticazione in single sign on tramite Shibboleth
- Autorizzazione/profilazione: è possibile definire eventuali constraint sulla visibilit� o abilitazione di ciascun widget;
i possibili tipi di constraint utilizzabili sono:
- Actor-based Security Constraint: il widget viene visualizzato/reso attivo solo se l'utente corrente impersonifica un ben determinato Actor di IRIDE2
- Role-based Security Constraint: il widget viene visualizzato/reso attivo solo se l'utente corrente appartiene ad un ben determinato Ruolo di IRIDE2
- UseCase-based Security Constraint: il widget viene visualizzato/reso attivo solo se l'utente corrente � abilitato ad un determinato UseCase di IRIDE2
- Custom Security Constraint: il widget viene visualizzato/reso attivo solo se l'utente corrente soddisfa una logica custom (codificata manualmente)
Lo sviluppatore ha inoltre a disposizione nella business logic le info relative all'utente corrente, nell'ApplicationData denominato "currentUser".
(@since 3.1.0) L'interazione con il servizio PEP (PolicyEnforcementPoint di IRIDE2) può avvenire con il protocollo RMI oppure con il protocollo WS.
La scelta avviene tramite una property da impostare nel file di proprietà di build specifiche di un determinato ambiente, in modo
da permettere l'utilizzo di protocolli differneti su ambienti differenti.
La properietà da impostare è iride2.pep.pd.protocol e può valere EJB (default) o WS.
E' poi necessario impostare i parametri di collegamento per i due protocolli, tramite le due proprietà
iride2.pep.provider.url e iride2.pep.wsfad.url.
Nel caso in cui fosse necessario implementare meccanismi di autenticazione e/o autorizzazione specifici, è
possibile seguire l'apposita guida.
Definizione del model gestito nell'applicativo
Lo strato di model nell'applicativo è costituito da:
- definizione di tipi utilizzati nella logica applicativa. I tipi possono essere:
- tipi complessi (ComplexType)relativi agli oggetti che dovranno essere maneggiati dalla logica applicativa (strutture dati)
- tipi semplici (SimpleType) user defined che si aggiungono ai tipi semplici base customizzandone alcuni
aspetti (es. formato, conversione, logica di uguaglianza/confronto, ...)
- definizioni di ApplicationData, che rappresentano le porzioni di informazione (strettamente tipizzate) che vengono maneggiate
all'interno della logica applicativa e dallo strato di view:
- hanno un nome che li identifica a livello di applicazione e con il quale possono essere referenziati all'interno delle GUI o nella
logica applicativa
- sono tipizzati (tipi semplici o complessi o collezioni di tipi semplici o complessi)
- possono "vivere":
- per il solo tempo di una singola interazione utente (scope = USER_ACTION)
- per tutto il tempo in cui l'utente permane in uno stesso ContentPanel(scope = PAGE) anche a fronte di più interazioni successive
- per tutta la durata della sessione utente (scope = USER_SESSION)
- sono coinvolti in sessioni di editing, con possibilità di effettuare undo
delle modifiche apportate da U.I. tramite appositi comandi.
La logica di business è nettamente separata dalla logica di U.I e deve essere codificata manualmente:
- avendo a disposizione gli ApplicationData necessari, il cui valore è pre-compilato (se necessario) a fronte dell'input utente sulle
GUI a cui tali dati sono collegati o a fronte del valore contenuto in sessione se l'ApplicationData è a scope USER_SESSION o PAGE;
- restituendo al gestore del contesto applicativo gli ApplicationData creati/modificati dalla logica, in modo che possano
essere maneggiati dallo strato di presentation
- implementando metodi con una interfaccia ben definita
- il collegamento tra U.I, controller e model/logica è modellato come spiegato nel paragrafo successivo
Definizione del comportamento dinamico dell'applicativo
Il comportamento dinamico dell'applicativo si concretizza nella possibilit� di associare una serie di comandi agli
eventi di user interaction che avvengono sull'applicativo.
In particolare sono disponibili le seguenti possibilit�/comandi:
- comandi di gestione dello stato della schermata
- ONOFFCommand: abilitazione/disabilitazione di un set di widget e\o menu definito a tempo di design
- VisibilityCommand: rendere visibile/invisibile un set di widget e\o menu definito a tempo di design
- ScreenStateCommand: permette di far passare la schermata corrente ad un particolare stato di abilitazione/visibilità complessiva dei widget in esso contenuti;
- comandi di gestione del flusso di navigazione
- JumpCommand: saltare ad una schermata (ContentPanel) differente da quella corrente
- JumpExtCommand: saltare ad una pagina, tramite link diretto (in genere utilizzato per uscire
dal contesto applicativo corrente e puntare, ad esempio, ad una pagina statica o ad un'applicazione esterna
- ShowDialogCommand: passare alla visualizzazione di una pagina corrispondente ad un DialogPanel;
- comandi di richiamo della business logic
- ExecCommand: eseguire una logica applicativa java (il cui codice deve essere scritto manualmente) e, a seconda dell'esito eseguire altre
sequenze di comandi
- comandi di gestioen dello stato applicativo
- BeginEditSession: inizia una sessione di editing su un insieme di ApplicationData
mantenendo automaticamente un backup dei dati per un eventuale necessit� di undo
- EndEditSession: termina una sessione di editing su un insieme di ApplicationData,
permettendo (se specificato) di effettuare l'undo delle modifiche effettuate durante
la sessione
- altri comandi
- SequenceCommand: eseguire una sequenza di comandi
La struttura di comandi che devono essere eseguiti a fronte di un evento di U.I su un particolare widget sono modellati
e sono implementati automaticamente dal codice generato, ad esclusione dell'ExecCommand. In quest'ultimo caso, infatti,
sebbene il codice generato provveda a richiamare automaticamente un metodo di business fornendogli il contesto applicativo e
modificando il contesto applicativo con i risultati dell'esecuzione di tale metodo, il metodo di business deve essere codificato
manualmente nel linguaggio target (java). Al momento questo rappresenta l'unico punto di intervento manuale post-generazione sul codice.
I possibili punti di aggancio di un comando sono:
- evento click su ConfirmButton: la logica viene eseguita alla pressione del pulsante
- selezione di una cella di una Table
- selezione di una voce di menu
- evento di cambiamento della selezione di una ComboBox: la logica viene eseguita ogni volta che viene selezionato un valore nella combo
- evento selezione di un radiobutton: la logica viene eseguita al click su uno dei radiobutton di un gruppo di radiobutton
- refresh della pagina (contentPanel): questa logica viene eseguita ogni volta che viene ricaricata una pagina, comprese le volte in cui il refresh
è conseguente all'esecuzione di un altro evento.
- inizializzazione dell'applicazione: la logica viene eseguita ogni volta che si passa dalla pagina iniziale