Sei sulla pagina 1di 113

Universit degli Studi di Padova

Facolt di Scienze Matematiche, Fisiche e Naturali Corso di Laurea in Informatica

Tesi di Laurea

Sviluppo di unintranet aziendale realizzata con Liferay nellambito del Web 2.0

Relatore: Prof.ssa Francesca Rossi

Candidato: Mattia Bazzega

Anno Accademico 2011-2012

Alla mia famiglia

Indice
1 Introduzione 1.1 Scopo dello stage . . . . . . . . . . . 1.2 Motivazioni allorigine del progetto . 1.2.1 Il Web 2.0 . . . . . . . . . . 1.2.2 Intranet aziendali e Web 2.0 1.3 Ambiente aziendale . . . . . . . . . . 2 Elementi e funzionamento di un portale 2.1 Definizioni generali . . . . . . . . . . 2.2 Esempio di una sequenza di eventi . 2.3 Creazione di una pagina del portale . 2.4 Linterfaccia Portlet . . . . . . . . . 2.5 Ciclo di vita di una portlet . . . . . . 2.5.1 Caricamento e istanziazione 2.5.2 Inizializzazione . . . . . . . 2.5.3 Portlet Window . . . . . . 2.5.4 Gestione delle richieste . . . 2.5.5 Distruzione della portlet . . 2.6 Modello dei dati della portlet . . . . 2.7 Limiti della specifica JSR-168 . . . . 9 9 10 10 11 13 15 15 18 18 19 19 21 21 22 23 26 26 27 29 29 31 33 34 35 36 36 36 37 38 38 39 40

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3 La piattaforma Liferay Portal 3.1 Introduzione a Liferay Portal . . . . . . . . 3.2 Panoramica delle caratteristiche del portale 3.3 Funzioni di collaborazione . . . . . . . . . . 3.4 Gestione degli utenti e gruppi . . . . . . . . 3.4.1 Utenti . . . . . . . . . . . . . . . . 3.4.2 Gruppi di utenti . . . . . . . . . . 3.4.3 Organizzazioni . . . . . . . . . . . 3.4.4 Comunit . . . . . . . . . . . . . . 3.4.5 Ruoli . . . . . . . . . . . . . . . . 3.5 Scope . . . . . . . . . . . . . . . . . . . . . 3.6 Architettura e framework . . . . . . . . . . 3.6.1 Service Oriented Architecture . . . 3.6.2 Enterprise Service Bus . . . . . . . 5 di 113

INDICE 3.6.3 Spring . . . . . . . . . . Strategie di sviluppo del portale . 3.7.1 Ambiente Plugins SDK 3.7.2 Ambiente Extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 41 42 43 45 45 46 47 49 49 50 51 51 52 53 53 53

3.7

4 Analisi dei requisiti 4.1 Euris Due.Zero . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.1 Problemi e mancanze . . . . . . . . . . . . . . . . . . 4.1.2 Lista dei requisiti . . . . . . . . . . . . . . . . . . . . 5 Ambiente e strumenti di lavoro 5.1 Installazione e configurazione del portale 5.1.1 Ambiente Ext . . . . . . . . . . 5.1.2 Ambiente Plugins SDK . . . . 5.2 Strumenti utilizzati . . . . . . . . . . . . 5.2.1 Requisiti per linstallazione . . 5.2.2 Database . . . . . . . . . . . . 5.2.3 Application server . . . . . . . 5.2.4 IDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6 Stabilizzazione dellapplicazione web 55 6.1 Modifica del messaggio di benvenuto . . . . . . . . . . . . . . 55 6.2 Redirect dopo lautenticazione dellutente . . . . . . . . . . . 59 6.3 Filtraggio attivit di modifica pagine Wiki . . . . . . . . . . . 67 7 Sviluppo di nuove funzionalit 7.1 Sistema per la modifica dei documenti . 7.1.1 Realizzazione dellapplet . . . . 7.2 Visualizzazione di un documento . . . . 7.3 Sviluppo portlet . . . . . . . . . . . . . . 7.3.1 Portlet per le informazioni . . . 7.3.2 Portlet per la pagina daccesso 7.3.3 Portlet per gli interessi utente . 7.3.4 Portlet per i feedback . . . . . 8 Conclusioni Glossario Bibliografia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 71 77 82 88 93 94 97 100 107 109 113

6 di 113

Elenco delle figure


Raffigurazione di una pagina formata da portlet. . . . . . . . . . . . Creazione di una pagina del portale. . . . . . . . . . . . . . . . . . Package javax.portlet che contiene linterfaccia Portlet. . . . . Diagramma di macchina a stati che specifica il ciclo di vita di una portlet. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5 Caricamento di una pagina del portale. . . . . . . . . . . . . . . . . 2.6 Process di unaction. . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1 Organizzazione delle risorse umane e loro gruppi nel portale. . . . . 3.2 Architettura di Liferay Portal. . . . . . . . . . . . . . . . . . . . . . 3.3 Strategie di sviluppo di Liferay. . . . . . . . . . . . . . . . . . . . . 3.4 Funzionamento dellambiente Plugins SDK. . . . . . . . . . . . . . 3.5 Funzionamento dellambiente Extension. . . . . . . . . . . . . . . . 6.1 Messaggio di benvenuto visibile nel pulsante del pannello di controllo in diverse situazioni. . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 Diagramma di interazione del pattern architetturale MVC. . . . . . 6.3 Portlet di autenticazione al portale. . . . . . . . . . . . . . . . . . . 6.4 Portlet per il tracciamento delle attivit. . . . . . . . . . . . . . . . 7.1 Applet per la modifica dei documenti. . . . . . . . . . . . . . . . . . 7.2 Finestra informativa dellapplet. . . . . . . . . . . . . . . . . . . . . 7.3 Richiesta delle credenziali per la modifica di un documento. . . . . 7.4 Viewer incorporato nella pagina. . . . . . . . . . . . . . . . . . . . 7.5 Portlet per le informazioni su una comunit. . . . . . . . . . . . . . 7.6 Portlet per laccesso alle comunit. . . . . . . . . . . . . . . . . . . 7.7 Singola comunit visualizzata dalla portlet. . . . . . . . . . . . . . . 7.8 Categorie associate agli interessi/competenze di un utente. . . . . . 7.9 Portlet per gli interessi/competenze di un utente. . . . . . . . . . . 7.10 Portlet per linvio di feedback. . . . . . . . . . . . . . . . . . . . . . 2.1 2.2 2.3 2.4 . 16 . 18 . 19 . . . . . . . . . . . . . . . . . . . . . . 20 24 25 35 39 42 43 44 58 62 66 67 80 80 81 87 94 95 96 97 98 101

7 di 113

ELENCO DELLE FIGURE

8 di 113

Capitolo 1
Introduzione
In questo primo capitolo si spiegheranno le motivazioni e gli scopi che hanno portato alla realizzazione di questo stage. In particolare si introdurr brevemente il contesto web sul quale si poggia la piattaforma Liferay Portal e come questa possa essere utilizzata al fine aziendale. Nel secondo capitolo verranno riportati i concetti principali sui quali si fonda lapplicazione web, facendo una panoramica sul suo funzionamento generale. Larchitettura verr poi illustrata dettagliatamente nel terzo capitolo, nel quale si descriveranno anche le varie funzionalit offerte dalla piattaforma in questione. Nel quarto capitolo, invece, si evidenzieranno i diversi problemi, pi o meno significativi, e le mancanze riscontrate allinterno dellapplicazione web. Nel capitolo 5 si parler dellambiente e degli strumenti di lavoro necessari ad eseguire le dovute modifiche al portale. I capitolo 6 e 7 saranno invece dedicati alla stabilizzazione dellapplicazione web con conseguente correzione dei problemi in essa rilevati e alla successiva implementazione di nuove funzionalit richieste dallazienda. Lultimo capitolo sar destinato alle conclusioni e alle considerazioni personali sullattivit di stage.

1.1

Scopo dello stage

Lo scopo dello stage stato quello di esplorare il grado di stabilit e completezza funzionale della piattaforma utilizzata per la realizzazione dellintranet aziendale che ingloba funzionalit tipiche del Social Network con funzionalit strettamente aziendali. Lattivit ha sfociato quindi nello sviluppo di alcune delle funzionalit necessarie per soddisfare le esigenze dellazienda e nellintegrazione della suddetta piattaforma con strumenti aziendali di frequente utilizzo. 9 di 113

CAPITOLO 1. INTRODUZIONE

1.2

Motivazioni allorigine del progetto

Per parlare delle motivazioni allorigine dello sviluppo dellintranet aziendale, necessario innanzitutto definire al meglio il contesto duso della piattaforma. Infatti, questultima fondata sul paradigma del cosiddetto Web 2.0, in quanto lintranet sta divenendo sempre pi sociale. Si pu parlare, come si vedr in seguito, di Intranet 2.0 nella quale integrato il famoso strato 2.0. Socializzare linformazione ci che sta alla base di questo nuovo modo di comunicare, consentendo agli utenti di condividere e promuovere qualunque contenuto della Intranet con i colleghi, interagire con essi e fare in modo cos di migliorare la comunicazione top-down: questultima non scomparir, ma ha bisogno di rinnovarsi per diventare pi utente-centrica ed interattiva.

1.2.1

Il Web 2.0

La piattaforma Liferay Portal strettamente legata al concetto di Web 2.0 di cui qui di seguito ne verr data una panoramica, traendo come fonte principale un importante articolo di Tim OReilly su questo tema [1]. In questo articolo, lautore, che in effetti uno degli inventori della formula, cerca di ripercorrere la nascita del termine, proposto nellambito dellincontro tra la OReilly stessa e Medialive International, volto ad organizzare la prima conferenza riguardo il Web 2.0. Lidea di promuovere una conferenza con tale titolo nata dalla presa di coscienza, sostiene OReilly, che, dopo lesplosione della Bolla di Internet nel 2001, sia gradualmente emerso un nuovo modo di concepire il Web. Il fatto che dopo la crisi di molte societ, gettatesi a capofitto nella rete sperando di trarne veloci e facili profitti, alcuni abbiano sostenuto che lera del Web fosse giunta al termine, mentre altri ancora che il fenomeno fosse proprio di tutte le rivoluzioni industriali, , secondo i promotori della conferenza, caratteristico di una tecnologia che sta per entrare in una nuova fase. Ben lontano dallessere in declino, il Web non sarebbe mai stato cos importante dato che, di giorno in giorno, con una regolarit sorprendente, compaiono nuovi siti e applicazioni dal carattere innovativo. Inoltre, le societ che erano sopravvissute al collasso, sembravano avere alcune caratteristiche in comune. Quindi, le due societ concordarono sullanalisi per cui il collasso delle dot-com 1 avesse segnato per la rete un punto di svolta tale che un richiamo allazione definito come Web 2.0 potesse avere senso. OReilly cerca di dare una definizione compatta del concetto in questione. Infatti, specifica che il Web 2.0 la rete come piattaforma, attraverso tutti i dispositivi ad essa connessi. Inoltre, le applicazioni Web 2.0 sono quelle che potenziano i vantaggi intrinseci di tale piattaforma: fornendo programmi come servizi continuamente aggiornati che migliorano man mano che le persone ne
dot-com: societ di servizi che sviluppano la maggior parte del proprio business tramite un sito web
1

10 di 113

1.2. MOTIVAZIONI ALLORIGINE DEL PROGETTO fanno uso, consumando e rimescolando dati da molteplici sorgenti, includendo i singoli utenti, distribuendo i loro stessi dati e servizi in una forma che ne permette il rimescolamento da parte di altri, creando una comunit attraverso unarchitettura della partecipazione, e superando la metafora della pagina del Web 1.0 per offrire allutente ricche esperienze. Nellarticolo OReilly cerca di chiarire gli aspetti di tale mutamento e i principi fondanti del Web 2.0, ponendo a confronto una serie di siti ed applicazioni, che potrebbero essere considerati i portabandiera di una nuova concezione della Rete, contro altri, che esemplificherebbero i paradigmi precedenti alla Bolla del 2001, dimostratisi, questi s, superati. I punti cardine di questa evoluzione del Web risultano quindi essere la partecipazione degli utenti (e di conseguenza il formarsi di unintelligenza collettiva), la trasformazione dei dati (remixability) e la loro creazione da parte degli utenti (user-generated content) ed infine il cambiamento di rotta del design centrato sulle esigenze dellutente. Se, dunque, la prima forma di Internet stata caratterizzata da una partecipazione passiva degli utenti, in quanto concepita come modo per la visualizzazione di soli documenti ipertestuali statici, il Web 2.0 rappresentato da tutta una generazione di funzioni e di servizi contraddistinti da una cooperazione attiva e creativa degli utenti, i quali contribuiscono a produrre conoscenze. Le strutture del Web 2.0 si costruiscono dal basso, per effetto di apporti minimi ma costanti in continuo confronto e interazione. Il protagonismo partecipativo degli utenti e la crescente mediazione tecnologica dellattivit comunicativa giustificano in pieno la nozione di intelligenza collettiva, anzi connettiva, distribuita ovunque, coordinata nella dimensione sincronica, che alcuni hanno proposto per indicare le attivit cognitive che si svolgono in rete e grazie alla rete.

1.2.2

Intranet aziendali e Web 2.0

Le intranet aziendali, grazie al Web 2.0, stanno cambiando per trasformarsi in nuovi spazi sociali nei quali lavoro, comunicazione e condivisione si sovrappongono e dove relazioni e processi si intersecano per dare vita a vere community. Si pu dunque riferirsi ad unIntranet 2.0, intendendo, innanzitutto, levoluzione delle tradizionali intranet verso un modello e degli standard di eccellenza guidati dalle migliori pratiche a livello mondiale. Si pu parlare di nuovi standard che tutte le intranet dovrebbero adottare per avere successo. Per quanto riguarda gli utilizzi dellintranet 2.0, si pu dire che la sua vera sfida quella di traghettare gli scambi dai canali alle piattaforme, valorizzando insieme le potenzialit di comunicazione, partecipazione e condivisione allo scopo di lavorare meglio. necessario tenere in considerazione che ci possono essere varie situazioni aziendali e che, quindi, la struttura deve supportare ciascun membro nelle diverse fasi delloperare (lavorare, collaborare, condividere, 11 di 113

CAPITOLO 1. INTRODUZIONE contribuire) allinterno dei diversi contesti (da solo, team, dipartimento, community, ecosistema). In tutte queste condizioni distinte, infatti, cambiano i contenuti e gli obiettivi, ma anche limpegno che richiesto e il tipo di contributo che le persone possono dare (lavorare diverso da collaborare che diverso da condividere che diverso da contribuire). Anche i parametri della partecipazione variano: in alcuni casi gli oggetti dellIntranet servono ad una specifica risorsa, in altri sono a disposizione di tutti i dipendenti e in alcuni casi sono dedicati a piccoli gruppi che interagiscono. Sempre pi spesso, al momento di riprogettare o semplicemente rinnovare la propria intranet molte imprese oggi si pongono la questione di quanto e come sia opportuno integrare dimensioni pi sociali, partecipate, collaborative allinterno delliniziativa. Questa esplosione in direzione Enterprise 2.0 2 riproposta con forza dai risultati dellIntranet 2.0 Global Survey 2010 [2] pubblicato da Toby Ward e Prescient Digital Media che ha coinvolto 526 aziende di ogni dimensione, settore e localizzazione geografica. Le indicazioni pi rilevanti estrapolate da questo studio si possono elencare di seguito: i social media sono ormai sdoganati allinterno delle intranet con una qualche presenza nell87% dei casi, mentre solo il 10% delle organizzazioni non sta nemmeno considerando tali modalit per il futuro; in compenso la partecipazione dei dipendenti lascia ancora molto a desiderare; i bisogni che vengono raccolti sono guidati innanzitutto dalla collaborazione tra i dipendenti (77%) e la gestione della conoscenza (71%). A seguire il coinvolgimento dei dipendenti (56%) e le comunicazioni dallalto (40%); circa met (47%) dei progetti riguardo lintranet 2.0 hanno meno di due anni e questo conferma il lungo lavoro ancora da fare sulladozione e sul raffinamento degli strumenti; si inizia a diffondere lidea che non introdurre gli strumenti collaborativi rischi di precludere significative opportunit allazienda. In cima alla lista degli strumenti pi usati ci sono blog (53%), forum (52%), istant messaging (51%), wiki (49%) mentre il social networking si attesta al 27%, ma anche la componente in crescita maggiore; per quanto riguarda le tecnologie di riferimento, pi di tre quarti delle aziende (77%) si avvalgono di un sistema di gestione dei contenuti (CMS) per le loro intranet; relativamente al livello di soddisfazione, il 46% delle organizzazioni giudicano buono il servizio offerto dallintranet 2.0 e questo numero indica
Enterprise 2.0: luso di specifiche applicazioni del nuovo web riadattate allinterno dellorganizzazione per gestire, in genere, la conoscenza aziendale
2

12 di 113

1.3. AMBIENTE AZIENDALE unevoluzione sia degli strumenti, che della comprensione da parte degli utenti che non pu che far bene alla sua maturazione allinterno del contesto aziendale. Quindi, in definitiva, da quanto detto si comprende che, cos come per i servizi del Web 2.0 si assistito ad un sostanziale cambiamento dei flussi di origine dellinformazione, la gestione della conoscenza aziendale sta prendendo spunto da fenomeni di condivisione sociale di nuova concezione per trasformarsi. Infatti, da intranet intese come classici sistemi di gestione documentale in cui le informazioni vengono elaborate da redazioni od organi istituzionali e veicolate verso la base di utenti, oggi si parla sempre pi spesso di architetture flessibili di Knowledge Management e di e-learning molecolare in cui il sapere viene prodotto e codificato dagli stessi utilizzatori finali che, a seconda delle specifiche competenze, permettono ai colleghi di accedere a informazioni trasmesse generalmente solo per via informale.

1.3

Ambiente aziendale

Lo stage stato svolto presso lazienda Gruppo Euris S.p.A. nella sua sede di Padova. Questultima opera da pi di ventanni nel settore IT, con lobiettivo di realizzare software customizzati per organizzazioni di media e grande dimensione. Durante la permanenza in azienda sono stato supportato dalla mia tutor, Nicoletta Bressan, la quale ha dimostrato grandi capacit e conoscenze. Infatti, mi ha seguito nello svolgimento del progetto, dandomi dei feedback su quanto fatto ed aiutandomi in tutte le varie fasi percorse. Lazienda, inoltre, mi ha messo a disposizione risorse hardware e software sufficienti per svolgere al meglio il lavoro affrontato.

13 di 113

CAPITOLO 1. INTRODUZIONE

14 di 113

Capitolo 2
Elementi e funzionamento di un portale
In questo capitolo ci si occuper di fornire alcune nozioni fondamentali necessarie ad introdurre la piattaforma Liferay Portal. In particolare, i concetti che si illustreranno verranno corredati da figure e descrizioni utili a far comprendere non solo la loro funzione, ma anche altri aspetti ad essi correlati per avere unampia visione sullargomento.

2.1

Definizioni generali

Sono sostanzialmente tre i concetti base che consentono di presentare questo argomento, ossia: portale; portlet; portlet container. Innanzitutto, necessario specificare cosa sintende con il termine portale. Confrontando pi fonti si ottenuto di poter identificare il portale con un servizio che opera da mediatore di informazione (infomediario) a favore degli utenti della rete, permettendo a questi di raggiungere, tramite un particolare punto di ingresso nella rete, una grande quantit delle risorse esistenti. Un portale sostanzialmente un aggregatore di informazione che offre un servizio di navigazione sul web facilitando il lavoro di ricerca: nati come evoluzione dei motori di ricerca, i portali hanno associato agli strumenti tipici di questi (search engine e categorizzazione delle informazioni) altri servizi, informativi e non, allo scopo di proporsi come accesso preferenziale e guida per la navigazione via Internet. Generalmente i portali sono costruiti e manutenuti con componenti software 15 di 113

CAPITOLO 2. ELEMENTI E FUNZIONAMENTO DI UN PORTALE dinamiche chiamate portlet. Una portlet un modulo web realizzato in tecnologia Java riusabile allinterno di un portale web. Attraverso le portlet possibile generare contenuti dinamici e, di conseguenza, gestirne la personalizzazione. Inoltre, tramite esse possibile integrare contenuti provenienti da diverse sorgenti. Il contenuto generato da una portlet denominato anche frammento. Questultimo del markup (ad esempio HTML, XHTML, WML) che aderisce a certe regole e che pu essere aggregato ad altri frammenti per costituire un documento completo. Il frammento di una stessa portlet pu variare da un utente allaltro a seconda della configurazione apportata ad essa. Diverse portlet, integrate insieme, concorrono a creare una singola pagina del portale.

Figura 2.1: Raffigurazione di una pagina formata da portlet. 16 di 113

2.2. ESEMPIO DI UNA SEQUENZA DI EVENTI Inoltre, una stessa portlet pu essere utilizzata in pi pagine. Visivamente, le portlet sono porzioni di pagina e funzionalmente sono dei canali informativi. Lapplicazione di questa modularit permette agli utenti di costruirsi un portale personalizzato, semplicemente scegliendo dove, come e in quale pagina disporre le portlet con diversi contenuti. Le portlet sono identificabili come un tipo speciale di Servlet, progettate per essere inserite facilmente in un portal server ed essere eseguite. Quindi, come si pu osservare, lutente finale costruisce una pagina per aggregazione dei singoli elementi, avendo come risultato finale una pagina web configurabile ed adattabile alle sue volont. Tecnicamente, la rappresentazione finale affidata per gran parte al portlet container che, come si vedr dettagliatamente in seguito, gestisce il loro ciclo di vita. Infatti, il suo compito di seguire le azioni dellutente (link, form, javascript, ecc.), eseguire la logica di business di tutte le portlet presenti nella pagina ed infine passare al portale i frammenti generati dalle stesse. In seguito il portale aggrega il risultato proveniente da ognuna di esse in un pannello tipo quello in figura 2.1. Per consentire la portabilit tra i vari portlet container commerciali, stata fatta richiesta al Java Community Process (JCP) di formalizzare uno standard apposito per le portlet, lo standard JSR-168 (Java Portlet Specification 1.0 [3]). Questultimo stato rilasciato nel 2003 e al gruppo di lavoro hanno partecipato diverse importanti aziende tra le quali Apache Software Foundation, IBM, Sun Microsystems, Oracle. La specifica ha definito un insieme di interfacce applicative (API) per linteroperabilit fra un portlet container e le portlet. In particolare, ha fissato i seguenti punti: il ruolo e le funzionalit dei portlet container; il contratto tra il container e le portlet; la gestione del ciclo di vita delle portlet; il packaging per la distribuzione delle portlet; linterazione con lo standard WSPR (Web Services for Remote Portlets) che definisce un protocollo standard per il dialogo tra il container e le portlet. Il portlet container, dunque, contiene le portlet e gestisce il loro ciclo di vita. Si occupa di immagazzinare le preferenze e le configurazioni di ogni portlet. Inoltre, riceve le request dal portale e le indirizza alle portlet che gestisce. Un portlet container non per responsabile dellaggregazione dei contenuti generati dalle diverse portlet. Questo , infatti, compito del portale. Portale e container possono essere integrati insieme come un componente singolo di una suite di applicazioni oppure come due parti separate di una portal application. 17 di 113

CAPITOLO 2. ELEMENTI E FUNZIONAMENTO DI UN PORTALE

2.2

Esempio di una sequenza di eventi

Qui di seguito si pu riportare una tipica sequenza di eventi, che inizia dal momento in cui un utente accede alla pagina del portale: un client (ad esempio un browser web), dopo essersi autenticato, esegue una richiesta HTTP al portale; la richiesta viene ricevuta dal portale; il portale determina se la richiesta contiene unazione mirata su una qualsiasi delle portlet associate alla pagina; se c unazione indirizzata ad una portlet, il portale richiede al portlet container di invocare la portlet per processare lazione; attraverso il container, il portale invoca le portlet per ottenere i frammenti generati da esse che possono essere inclusi nella pagina risultante; il portale aggrega gli output delle diverse portlet nella pagina e rimanda questultima al client.

2.3

Creazione di una pagina del portale

Il portlet container riceve i vari contenuti generati dalle diverse portlet. Poi, tipicamente, li passa al portale, il quale crea la pagina aggregando i vari frammenti delle portlet e la invia al dispositivo client (un browser) dove viene visualizzata. Il meccanismo appena descritto si pu riportare nella seguente figura.

Figura 2.2: Creazione di una pagina del portale. 18 di 113

2.5. CICLO DI VITA DI UNA PORTLET Gli utenti possono accedere ad un portale utilizzando un comune browser web. Al momento di ricevere la richiesta della pagina, il portale determina la lista di portlet di cui necessita per soddisfare la richiesta e, attraverso il portlet container, le invoca. In tal modo, il portale crea la pagina con i frammenti generati dalle portlet che viene ritornata al client dov presentata allutente.

2.4

Linterfaccia Portlet

Linterfaccia Portlet la principale astrazione delle Portlet API. Tutte le portlet implementano questa interfaccia o direttamente oppure, pi comunemente, estendendo una classe che la implementa. La specifica, infatti, include la classe GenericPortlet che implementa linterfaccia Portlet e fornisce delle funzionalit di base. Gli sviluppatori dovrebbero estendere, direttamente o indirettamente, tale classe per implementare le loro portlet.
javax.portlet

Portlet + destroy() : void + init(config : javax.portlet.PortletConfig) : void + processAction(request : javax.portlet.ActionRequest, response : javax.portlet.ActionResponse) : void + render(request : javax.portlet.RenderRequest, response : javax.portlet.RenderResponse) : void

GenericPortlet

Figura 2.3: Package javax.portlet che contiene linterfaccia Portlet.

2.5

Ciclo di vita di una portlet

Una portlet gestita attraverso un ciclo di vita ben definito che determina come caricata, istanziata ed inizializzata, in che modo tratta le richieste che provengono dai client e come le soddisfa. Il ciclo di vita di una portlet per molti aspetti analogo al corrispettivo ciclo delle servlet. Le varie fasi sono individuate dai tre seguenti stati: 19 di 113

CAPITOLO 2. ELEMENTI E FUNZIONAMENTO DI UN PORTALE caricamento delle classi e inizializzazione; gestione della request; distruzione della portlet. Tutte le fasi sopracitate sono gestite attraverso quattro metodi esposti dallinterfaccia Portlet: init, che viene chiamato dal container quando la portlet viene inizializzata; destroy, metodo invocato dal container quando la portlet viene distrutta; processAction, chiamato dopo che lutente ha effettuato una richiesta e serve a processare i dati avuti in input; render, il quale va in esecuzione ogni volta che la portlet si visualizza nella pagina web. Il ciclo di vita di una portlet pu essere riassunto nel diagramma di stato sottostante.

SM1.1 Caricamento

SM1.2 Istanziazione

SM1.3 Inizializzazione

Gestione delle richieste

SM1.4 processAction

SM1.5 - render

End Of Service / s End Of Service ? / no

SM1.6 Distruzione

Figura 2.4: Diagramma di macchina a stati che specifica il ciclo di vita di una portlet. 20 di 113

2.5. CICLO DI VITA DI UNA PORTLET Di seguito si descriveranno dettagliatamente tutte le operazioni che avvengono nel ciclo di vita.

2.5.1

Caricamento e istanziazione

Il meccanismo di base del caricamento di una portlet non diverso da quello adottato da ogni altra applicazione Java EE. Il portlet container, che responsabile del caricamento (stato SM1.1 nel diagramma 2.4) e della conseguente istanziazione (stato SM1.2 nel diagramma 2.4) delle portlet, procede secondo le regole (e le priorit) dellapplication server sul caricamento delle classi e delle librerie presenti allinterno dellarchivio di Deploy dellapplicazione. Entrambe queste operazioni possono avvenire quando il container avvia lapplicazione portlet, oppure vengono ritardate fino a che esso determina che la portlet necessita di servire una richiesta arrivatale. Il portlet container deve caricare la classe della portlet usando lo stesso ClassLoader del servlet container utilizzato per la parte di applicazione web dedicata alla portlet, in modo che la classe principale e le classi di supporto possano condividere lo stesso spazio di indirizzamento. Dopo aver caricato le classi, il portlet container le istanzia per il loro uso.

2.5.2

Inizializzazione

Dopo che loggetto portlet istanziato, il portlet container deve inizializzarlo prima di invocarlo per gestire la richiesta del client. Linizializzazione (stato SM1.3 nel diagramma 2.4) avviene al momento dello startup dellapplicazione o del portal server (se specificato il parametro di autostart) o in alternativa al momento della prima invocazione da parte del client. Linizializzazione deve essere eseguita per fare in modo che le portlet possano inizializzare a loro volta delle risorse dispendiose (come, ad esempio, le connessioni al backend) e compiere tutta una serie di altre attivit. Il container inizializza loggetto portlet chiamando il metodo init che presenta come parametro di invocazione il contesto di configurazione, definito dallinterfaccia PortletConfig del package javax.portlet. Questultimo oggetto fornisce laccesso ai parametri di configurazione e consente alla portlet, inoltre, di accedere ad un oggetto di contesto che descrive il suo ambiente desecuzione. Analogamente al caso delle servlet, fino a che il metodo init non termina la sua esecuzione, la portlet non disponibile per lesecuzione. Per questo motivo bene non imporre lunghe procedure di inizializzazione, cos come sbagliato invocare nel metodo init metodi che necessitino della portlet in uno stato vivo e funzionante. Eccezioni durante linizializzazione Durante la fase di inizializzazione una portlet pu andare incontro a problemi di 21 di 113

CAPITOLO 2. ELEMENTI E FUNZIONAMENTO DI UN PORTALE varia natura che ne possono pregiudicare o meno il funzionamento successivo. Si possono infatti verificare problemi temporanei (che con una qualche operazione di recovery possono essere risolti agilmente) o incidenti definitivi (mancanza della connessione al database, un importante file di configurazione non viene trovato o un altro grave problema che pregiudica lesecuzione della portlet). Una portlet, dunque, pu notificare al portal server queste due situazioni lanciando le eccezioni di tipo PortletException o UnavailableException secondo lo schema seguente: throws new PortletException(Messaggio) : il problema provvisorio e il container pu tentare di riattivare la portlet in seguito; throws new UnavalaibleException(Messaggio) : il problema grave e non si deve riattivare la portlet; throws new UnavalaibleException(Messaggio, n) : il problema grave ma risolvibile: in tal caso si comunica al portlet container che pu essere tentata una successiva inizializzazione della portlet fra n secondi; throws new UnavalaibleException(Messaggio, 0) : in questo caso si ipotizza un problema non grave per il quale per non possibile determinare quando potr essere riattivata la portlet. Il container tenter nuovamente linizializzazione dopo una pausa arbitrariamente lunga. Il container, quindi, pu riprovare in qualsiasi momento ad istanziare ed inizializzare le portlet dopo un insuccesso, a meno che una UnavailableException indichi un tempo minimo di indisponibilit. Se ci accade, il portlet container deve aspettare un determinato tempo prima di creare ed inizializzare un nuovo oggetto portlet. Durante linizializzazione, inoltre, uneccezione di tipo RuntimeException trattata come una PortletException.

2.5.3

Portlet Window

La definizione della portlet pu includere un insieme di attributi (con i loro valori di default) che specificano delle preferenze e che sono utilizzati per creare i relativi oggetti. Le portlet, infatti, sono comunemente configurate per fornire delle viste o dei comportamenti personalizzati per utenti differenti. Tale configurazione rappresentata come un insieme persistente di coppie nome - valore che fanno riferimento alle preferenze della portlet. Il portlet container responsabile del recupero e della memorizzazione di questi attributi. Le preferenze sono destinate a salvare i dati di configurazione di base delle portlet e non loro scopo sostituire i comuni database. Le portlet hanno accesso ai relativi attributi delle preferenze attraverso linterfaccia PortletPreferences del package javax.portlet. Laccesso pu 22 di 113

2.5. CICLO DI VITA DI UNA PORTLET avvenire mentre stanno processando le richieste del client e, quindi, la modifica degli attributi (che non sono altro che array di stringhe) da parte di una portlet si pu verificare solamente durante uninvocazione del metodo processAction. A tempo desecuzione, quando vengono servite le richieste, una portlet associata ad un oggetto delle preferenze. In genere, una portlet personalizza il suo comportamento e il contenuto da essa prodotto basato proprio sugli attributi del relativo oggetto delle preferenze. Essa, quindi, pu leggere, modificare e aggiungere attributi, i quali possono anche assumere valori nulli. Di default, un oggetto delle preferenze costruito usando i valori iniziali delle preferenze, definiti nel Deployment descriptor della portlet. Limplementazione di un portale/portlet-container pu fornire, inoltre, degli strumenti per creare nuovi oggetti delle preferenze basati su altri gi esistenti. Quando una portlet posta in una pagina del portale, un oggetto di questo tipo viene associato ad essa. Linsieme di una portlet e del relativo oggetto delle preferenze costituisce la finestra della portlet (portlet window). Una pagina del portale pu contenere pi finestre che fanno riferimento alla stessa portlet e allo stesso oggetto delle preferenze.

2.5.4

Gestione delle richieste

Dopo che la portlet opportunamente inizializzata, il container pu invocarla per gestire le richieste (stati SM1.4 e SM1.5 nel diagramma 2.4) che provengono dal client. La richiesta eseguita dal client sul portale viene tradotta in una render request o action request a seconda della tipologia di invocazione. Per questo scopo, linterfaccia Portlet definisce i due metodi render (che, come detto, esegue la visualizzazione delle portlet) e processAction (che esegue una richiesta di elaborazione). In un caso o nellaltro il portale invoca il primo metodo o il secondo per rispondere alla richiesta, ma nel caso in cui sia attivo un meccanismo di cache, la ri-renderizzazione non viene forzata. Tipicamente le richieste del client sono innescate da URL creati dalle portlet (chiamati appunto portlet URL) che riferiscono le portlet stesse. Ad esempio, quando un utente agisce su un indirizzo relativo ad una portlet (cio cliccando un link o eseguendo il submit di un form) il risultato che ne consegue una nuova richiesta da parte del client al portale mirata a quella portlet. I portlet URL possono essere quindi di due tipi: action URL o render URL. Normalmente, una richiesta client innescata da un render URL si traduce come molte render request una per ogni portlet della pagina, mentre una richiesta provocata da unaction URL si realizza come unaction request e molte render request, una per portlet della pagina. Nel primo caso, il portale/container deve invocare il metodo render per tutte le portlet presenti nella pagina con la possibile eccezione delle portlet per cui i loro contenuti vengono trattenuti in cache. Non deve, invece, invocare il metodo processAction per alcuna delle portlet della pagina per quella richiesta. 23 di 113

CAPITOLO 2. ELEMENTI E FUNZIONAMENTO DI UN PORTALE In tal caso, infatti, si tratta semplicemente di caricare la pagina del portale visualizzando tutte le varie portlet della stessa, senza elaborare alcun dato ricevuto in input come nel caso dellaction request. Di seguito si riporta un diagramma di sequenza che illustra come viene gestita una richiesta innescata da un render URL.
:Client :Portale :PortletContainer :PortletA :PortletB

1 : request()

2 : render()

3 : render() 4 : frammento

5 : frammento

6 : render() 7 : render() 8 : frammento 9 : frammento 10 : pagina del portale

Figura 2.5: Caricamento di una pagina del portale. Se, invece, la richiesta del client innescata da unaction URL, il portale / portlet-container deve prima avviare la richiesta invocando il metodo processAc tion della portlet in questione. In seguito, dopo aver atteso la terminazione della richiesta, deve innescare la render request chiamando il metodo render per tutte le portlet della pagina, eccetto possibilmente, anche in questo caso, per quelle il cui contenuto viene cachato. In questo modo quindi il container eseguir il refresh delloutput di tutte le portlet della pagina. Le render request possono essere eseguite sequenzialmente o in parallelo senza rispettare alcun ordine specifico. bene inoltre considerare che il portale deve garantire un efficiente livello di servizio a tutti i client per tutte le portlet basato su un meccanismo multithread la cui gestione viene eseguita in modo pi agile e snello proprio eliminando ogni vincolo di priorit e sincronia sullesecuzione di tali thread. Il container, infatti, gestisce le richieste concorrenti che arrivano alla portlet (la stessa portlet pu essere visualizzata in vari punti in pi pagine) da esecuzioni concorrenti di gestione richiesta su differenti thread. Action Request Tipicamente, in risposta ad unaction request, una portlet aggiorna il suo stato sulla base delle informazioni inviate tramite i parametri della richiesta. Il metodo processAction, infatti, riceve in ingresso due parametri di tipo 24 di 113

2.5. CICLO DI VITA DI UNA PORTLET


:Client :Portale :PortletContainer :PortletA :PortletB

1 : request() 2 : processAction() 3 : processAction() 4 5

6 : render() 7 : render()

8 : frammento 9 : frammento

10 : render() 11 : render()

13 : frammento 14 : pagina del portale

12 : frammento

Figura 2.6: Process di unaction. ActionRequest e ActionResponse. Loggetto ActionRequest fornisce accesso a diverse informazioni: parametri della richiesta stessa; window state, che un indicatore della quantit di spazio della pagina che sar assegnata al contenuto generato dalla portlet (la specifica ha definito tre stati: NORMAL, MAXIMIZED e MINIMIZED) e pu essere usato da questultima per decidere quanta informazione dovrebbe renderizzare; portlet mode, che indica la funzione che la portlet sta eseguendo (la specifica ha fissato tre stati: VIEW per generare del markup che rispecchia lo stato corrente della portlet, EDIT, modalit che consente di modificare le impostazioni dellutente ed HELP che presenta informazioni di aiuto relative alla portlet); portal context, per ottenere informazioni sul portale; portlet session, che permette di identificare un utente su pi richieste e di memorizzare informazioni transitorie su di esso; dati delle preferenze della portlet. Durante una richiesta di questo tipo, la portlet pu cambiare la sua modalit di funzionamento (portlet mode) o il suo stato (window state). Tali operazioni 25 di 113

CAPITOLO 2. ELEMENTI E FUNZIONAMENTO DI UN PORTALE sono svolte utilizzando loggetto di tipo ActionResponse e diverranno effettive nella successiva fase di render. Render Request Comunemente, durante una render request, le portlet generano dei contenuti basati sul loro stato corrente. Il metodo render riceve in input due parametri di tipo RenderRequest e RenderResponse. Il primo parametro, come nel caso dellActionRequest, permette di accedere a diverse informazioni, ossia ai parametri della render request, al window state, al portlet mode, alla portlet session, alle preferenze della portlet e al portal context. Una portlet, inoltre, pu generare il suo contenuto usando loggetto di tipo RenderResponse (con un opportuno metodo getWriter() che ritorna un oggetto di tipo PrintWriter per inviare testo alla pagina del portale) oppure pu delegare questa operazione ad una servlet o ad una pagina JSP.

2.5.5

Distruzione della portlet

Il portlet container distrugge la porlet (stato SM1.6 nel diagramma 2.4) quando ritiene non pi necessario il suo utilizzo nel container. Questa decisione viene presa se non ci sono pi richieste in corso (e per un qualche motivo si deve fare shutdown dellapplicazione), quando tutti i thread di rendering o di action hanno terminato la loro esecuzione oppure quando il processo di inizializzazione si concluso. Da notare che il container non tenuto a mantenere indefinitamente in vita una portlet, ma per motivi vari pu procedere alla sua distruzione e successiva inizializzazione (in genere operazione effettuata se la carenza di risorse impone, ad esempio, di ottimizzare luso della memoria). In ogni caso la specifica garantisce che, prima della completa distruzione della portlet, venga invocato il metodo destroy(). Questultimo, infatti, permette ad essa di rilasciare qualsiasi risorsa che stava usando e salvare ogni stato persistente. Dopo la terminazione del metodo, il container deve rilasciare loggetto portlet in modo che possa essere raccolto dal garbage collector.

2.6

Modello dei dati della portlet

Lo standard specifica diversi meccanismi di cui la portlet pu usufruire per avere accesso ai dati persistenti e temporanei. Per gli stati persistenti ci sono i due seguenti modi: parametri di inizializzazione, definiti nel deployment descriptor della portlet, cio nel relativo file portlet.xml; preferenze della portlet, che possono essere di sola lettura oppure modificabili dallutente. 26 di 113

2.7. LIMITI DELLA SPECIFICA JSR-168 Il descrittore portlet.xml verr spiegato nel capitolo 7.3 dove si descriver come sono state sviluppate alcune portlet richieste dallazienda. Per avere accesso agli stati temporanei, invece, la portlet pu fare riferimento a: stato di navigazione, che consiste in portlet mode, window state e parametri di render e che definisce com presentata la vista corrente della portlet e come essa associata ad un particolare client; sessione: la portlet pu memorizzare le informazioni nella sessione o con uno scope globale (application scope), per lasciare che gli altri componenti di quellapplicazione web abbiano accesso ai dati, oppure con un portlet scope che privato per la portlet. Nel capitolo 6.2 si parler pi in dettaglio degli attributi di sessione e del loro funzionamento, in quanto sono stati usati per correggere un problema di cui era affetto il portale aziendale.

2.7

Limiti della specifica JSR-168

La specifica Java Portlet Specification 1.0 [3] presenta diverse limitazioni, le quali possono essere elencate di seguito: supporto parziale alla comunicazione inter-portlet, meccanismo standard per far interagire tra loro le portlet: supportato solamente allinterno della stessa portlet application usando gli attributi di sessione; la portlet ricevente vedr i messaggi solamente alla successiva richiesta di render; le portlet non possono aggiornare i loro stati durante una richiesta di render; da ci si comprende come la gestione degli eventi non sia in realt possibile. una portlet pu eseguire il render solo di frammenti HTML; non possibile ottenere una risorsa direttamente da una portlet, bisogna passare dal servlet container e ci richiede coordinamento tra portlet e servlet; lintegrazione con AJAX non supportata internamente, a meno che non sia offerta dal portlet container in modo non standard. Questi limiti hanno portato allintroduzione dello standard JSR-286 (Java Portlet Specification 2.0 [4]), rilasciato nel 2008, dopo che nel febbraio 2006 fu costituito il JSR 286 Expert Group al fine di arrivare alla specifica. Le novit introdotte riguardano principalmente i seguenti punti: 27 di 113

CAPITOLO 2. ELEMENTI E FUNZIONAMENTO DI UN PORTALE ogni portlet pu lanciare e ricevere determinati eventi; possibilit per le portlet di condividere parametri tra loro, attraverso i public render parameter; capacit di una portlet di restituire una risorsa; supporto migliore alla tecnologia AJAX. Il nuovo standard stato progettato per essere retrocompatibile con la prima specifica. Dunque, tutte le operazioni descritte in precedenza (ciclo di vita, caricamento pagina del portale, gestione delle richieste) sono valide, cos come mantiene la compatibilit con tutti i metodi delle vecchie API. Per via delle nuove funzionalit introdotte, oltre a nuovi metodi, sono state aggiunte diverse entry nel nuovo deployment descriptor.

28 di 113

Capitolo 3
La piattaforma Liferay Portal
In questo capitolo ci si occuper di descrivere dettagliatamente la piattaforma Liferay Portal usata per la realizzazione dellintranet aziendale. In particolare, dopo aver illustrato quali sono le caratteristiche principali della piattaforma, ci si soffermer sullanalisi dellarchitettura del Framework che sta alla base. In seguito si presenteranno le strategie di sviluppo di un portale costruito con questa piattaforma.

3.1

Introduzione a Liferay Portal

Liferay Portal un portale web Open source basato sulla tecnologia Java che sfrutta al meglio le moderne tecnologie Web 2.0. Utilizzato da aziende in tutto il mondo, comprende una lunga lista di funzionalit che lo mettono a confronto diretto con molti portali commerciali, con il vantaggio di non avere oneri di licenza. Infatti, oltre ad una gestione ottimale delle portlet, il suo successo dovuto alla quantit (e qualit) dei servizi integrati, unottima flessibilit di utilizzo e una grande capacit di organizzare e supportare la collaborazione interna. Prima di parlare delle varie caratteristiche che presenta, si possono elencare alcune soluzioni che Liferay pu garantire: intranet (intesa anche come extranet) aziendale, per fare in modo di avere unorganizzazione delle informazioni funzionale e flessibile, consentendo una gestione totale dei ruoli e dei permessi di accesso per reparti/gruppi/singoli utenti; gestione contenuti e pubblicazione web, per amministrare un sito web con molte informazioni e con molte persone coinvolte nellorganizzazione e stesura dei contenuti; collaborazione, per stimolare il lavoro in team; 29 di 113

CAPITOLO 3. LA PIATTAFORMA LIFERAY PORTAL applicazione che pu servire da framework (ambiente) per la gestione e lintegrazione di nuovi contenuti ed applicazioni. Questo software un prodotto della Liferay Inc. ed stato concepito nel 2000. Esistono due versioni per questo progetto: Community Edition (CE), completamente gratuita ( distribuita sotto licenza GNU LGPL), destinata a sviluppatori, community e a coloro che vogliono valutare le potenzialit di questa applicazione; Enterprise Edition (EE), versione pi stabile della precedente e che, come dice la parola stessa, destinata ad usi professionali da parte delle imprese, e comprensibilmente a pagamento. In tal caso, viene trattata la versione 5.2.3 CE, utilizzata per il portale aziendale. Lapplicazione fornisce uninterfaccia web unificata per le varie informazioni e gli strumenti che provengono da diverse sorgenti. Allinterno del portale, come si visto, questa interfaccia composta da un certo numero di portlet. Dal momento che queste ultime sono sviluppate indipendentemente dal portale e che quindi sono scarsamente accoppiate con esso, si pu parlare di una piattaforma basata su unarchitettura SOA, della quale si parler pi dettagliatamente in seguito. Liferay presenta una vasta gamma di portlet liberamente disponibili per blog, forum, sondaggi, calendario, raccolta documenti, galleria immagini, feed RSS, wiki, contenuti web e cos via. Liferay presenta anche le soluzioni di CMS e Web Content Management (WCM). Liferay CMS dotato delle funzionalit di base di Enterprise Content Management System (ECMS), molto utili per la collaborazione in team. Le informazioni, infatti, possono essere specifiche per un piccolo gruppo allinterno di unazienda, ad esempio alcune saranno rilevanti a livello di team, mentre altre in tutta lorganizzazione. Il portale in questione supporta molto bene questo tipo di situazioni. Riassumendo, Liferay ha quindi tre principali funzionalit: portale; CMS e WCM: sistema di gestione dei contenuti aderente allo standard JSR-170 e gestione dei contenuti web; software sociali per la collaborazione tra utenti, come blog, forum, wiki, annunci, bacheca delle attivit, ecc.. In generale, dunque, un sito web costruito usando Liferay pu essere costituito dagli elementi sopra elencati dei quali, qui di seguito, si illustreranno le varie peculiarit e i vantaggi offerti. 30 di 113

3.2. PANORAMICA DELLE CARATTERISTICHE DEL PORTALE

3.2

Panoramica delle caratteristiche del portale

Dal momento che Liferay il leader nel campo dei portali aziendali open source, fornisce soluzioni sia per il settore privato che per quello pubblico. A tale scopo, presenta queste caratteristiche e funzionalit: gira su tutti i principali application server, come ad esempio Tomcat, Glassfish, JBoss, Geronimo, Jetty, JOnAS, Resin, Weblogic, WebSphere; supporta numerosi database, tra i quali si possono citare MySQL, Oracle, SQL Server, PostgresSQL, JDataStore, Sybase, SAP, Apache Derby, Firebird, Hypersonic; multipiattaforma, in quanto eseguibile su diverse famiglie di sistemi operativi quali Linux, Unix, Windows e Mac OS X ; utilizza lultima versione di Java J2EE e le moderne tecnologie Web 2.0; compatibile con le specifiche JSR-168 e JSR-286 per le portlet; interfaccia utente basata su AJAX; oltre 60 portlet pronte alluso: forte di unestesa community, Liferay fornisce il numero maggiore di portlet gi integrate di qualsiasi altro portale sul mercato; drag and drop dinamico: gli utenti possono spostare gli elementi nel portale semplicemente trascinando e rilasciando il mouse; tagging e ricerca di risorse: possibilit di etichettare i documenti, i contenuti web, i messaggi dei forum ed altri elementi in modo dinamico e condividendo questi tag con gli altri utenti del portale. Gli utenti possono quindi ricercare tramite le etichette assegnate alle informazioni o gruppi di informazioni comuni; pagine personali: tutti gli utenti abilitati possono avere uno spazio personale dove immettere proprie informazioni e decidere se renderle pubbliche o tenerle private. possibile personalizzare lo spazio messo a disposizione tramite il drag & drop delle portlet; supporto multilingua; sincronizzazione LDAP; supporto allautenticazione unica Single Sign On (SSO): il portale consente agli utenti di accedere ai contenuti e applicazioni da un unico punto di accesso. Liferay pu infatti aggregare diversi sistemi applicativi rendendoli disponibili accedendo una volta sola con il massimo della riservatezza; 31 di 113

CAPITOLO 3. LA PIATTAFORMA LIFERAY PORTAL sistema di autorizzazioni granulare basato sul ruolo di un utente: per garantire che le persone accedano con diritto alle sole informazioni/dati per le quali sono autorizzate, gli amministratori del portale possono assegnare ai singoli utenti o gruppi di utenti diversi ruoli per attribuire loro differenti livelli di accesso e differenti diritti di modifica; gestione centralizzata di tutti i contenuti, risorse, utenti, comunit, ruoli attraverso un pannello di controllo completamente personalizzabile con la possibilit di aggiungere o togliere alcune sue parti; facile configurazione: una veloce ed intuitiva interfaccia rende Liferay estremamente semplice da utilizzare da tutti i membri di unorganizzazione. Il tempo per modificare un layout di pagina, laggiunta di nuove applicazioni e contenuti, cambiando anche laspetto della grafica pu essere fatto in un paio di click, anche dallutente finale stesso; sistema di gestione dei contenuti: il CMS incluso allinterno di Liferay fornisce un insieme esteso di funzionalit fortemente integrate con le funzioni di collaborazione e fornisce un repository centralizzato per conservare e gestire contenuti da visualizzare sul web. Ciascuna community e ciascuna organization hanno a disposizione una propria separata document library e image gallery. Il CMS implementato tramite Liferay Journal, un contenuto intrinseco (built-in) del portale che abilita una serie di funzionalit di gestione contenuti; Web Publishing, sistema che pu essere usato per creare pagine web in modo veloce usando dei contenuti riusabili, dei modelli (template) per layout flessibili; Flexibile Template Mechanism (XSL/VM ): i modelli creati per i Journal articles (cos vengono chiamati i contenuti web) possono essere realizzati in XSL o Velocity (VM) offrendo cos agli sviluppatori la flessibilit di disegnare le pagine web; Document Library, che provvede un deposito centralizzato per i servizi della libreria, basato sulla specifica Java Content Repository (standard JSR-170 ) per trattare diversi tipi di documenti (PDF, DOC, ecc.) che possono essere salvati sotto un unico URL; Image Gallery, che fornisce un deposito centralizzato per le immagini; Portal Publishing & Staging: la funzione di publishing permette di modificare pagine web in tempo reale senza per pubblicare subito il cambiamento ma solo quando si decide di farlo. Lo staging, invece, consente di creare varie copie di modifica della stessa pagina e testarle senza toccare le pagine correnti sul portale. 32 di 113

3.3. FUNZIONI DI COLLABORAZIONE

3.3

Funzioni di collaborazione

Liferay, come detto precedentemente, offre inoltre un sistema potente ed integrato di funzioni di collaborazione. Queste ultime sono riassunte brevemente qui di seguito: wiki: Liferay implementa un sistema di wiki robusto ed efficace, comparabile a prodotti standalone. Ogni gruppo pu condividere una propria wiki con propri e differenziati insiemi di autorizzazioni. Ogni utente con i diritti necessari pu contribuire alla crescita del repository di conoscenza condiviso. I contenuti vengono inseriti semplicemente con un editor WYSIWYG, le pagine possono essere raggruppate in gerarchie e taggate con sistemi a vocabolario multiplo; bacheca elettronica: un sistema di bacheca elettronica (message boards) permette di condividere idee ed annunci allinterno di un gruppo (organizzazione o community). Liferay mette a disposizione dei report sullattivit svolta nella bacheca, riportando i post recenti, gli utenti attivi. Ogni thread visibile via feed RSS ed ogni post pu inviare una mail di avviso che permette di rispondere al post da client di posta. Come per tutte la altre portlet, anche quella della bacheca sottoposta al sistema finemente granulare di gestione degli accessi e autorizzazioni del portale che garantisce il controllo utilizzando i ruoli; blog: Liferay implementa un sistema di blog ricco di funzionalit, reso pi efficace dalla natura sociale del portale nel suo complesso. Tra le funzionalit pi importanti leditor WYSIWYG, social bookmarking, notifiche email per i contributi e commenti, sistemi di rating dei contributi, sottoscrizione via RSS, scheduling delle pubblicazioni; instant messaging: sono comprese delle funzioni di instant messaging che fruiscono naturalmente del sistema di relazioni del portale. Tramite la lista degli amici vengono automaticamente visualizzati i nomi degli amici collegati. Laccesso al servizio inserito in una barra in fondo alla videata e segue lutente lungo la navigazione allinterno del portale rimanendo sempre disponibile; calendari: possibile impostare ed utilizzare calendari di gruppo (basati sulle community). Gli eventi possono essere condivisi intragruppi, gli alert sugli eventi possono essere impostati per un avviso via email, instant messaging o SMS; avvisi: possibile inviare messaggi di tipo broadcast a gruppi di utenti. Ogni utente pu settare le modalit di ricezione degli avvisi tramite web alert via portale, SMS, email o altre modalit di delivery impostate dallamministratore; 33 di 113

CAPITOLO 3. LA PIATTAFORMA LIFERAY PORTAL sondaggi: sono disponibili delle portlet per limpostazione, la presentazione e la raccolta dati di sondaggi. Possono essere configurati e pubblicati pi sondaggi in contemporanea con visibilit differenziate rispetto ai gruppi; tracking delle attivit: la portlet Attivit Recenti tiene traccia delle attivit pi recenti effettuate sul portale (contributi o commenti su blog, bacheche, wiki e altri strumenti). Lapproccio e la presentazione sono simili a quelli di Facebook; RSS : Liferay consente di condividere, opzionalmente, tutte le tipologie di contenuto tramite feeding RSS.

3.4

Gestione degli utenti e gruppi

Liferay utilizza diversi concetti per organizzare un portale. Il modo pi semplice di pensare a ci considerare gli utenti e i diversi modi con cui essi possono essere raggruppati insieme. Le varie situazioni vengono cos presentate: un portale acceduto da utenti; gli utenti possono essere raccolti in gruppi di utenti; gli utenti possono appartenere ad organizzazioni; le organizzazioni possono essere raggruppate in gerarchie; utenti, gruppi e organizzazioni possono appartenere a comunit che hanno un interesse comune. Le relazioni che intercorrono tra le varie risorse citate sono riportate nella figura 3.1. Nella figura ogni freccia va interpretata con il significato di pu essere parte di. Questo vuol dire, ad esempio, che le organizzazioni possono essere parte di comunit, queste ultime possono essere parte di ruoli, gli utenti possono essere parte di qualsiasi cosa, e cos via. Anche se ci sembra molto complesso, fornisce un potente meccanismo per configurare le risorse del portale in un modo consistente e robusto. importante notare che il diagramma riporta solo gli utenti e i loro possibili raggruppamenti. I permessi non hanno influenza sui gruppi, ma possono essere assegnati solamente ai ruoli. Al portale possono avere accesso diverse categorie di utenti. La prima distinzione da fare tra utente autenticato e visitatore anonimo. Anche questi ultimi possono utilizzare le portlet, purch esse siano configurate opportunamente, dipende dallobiettivo del portale. Se si tratta di un portale aperto al 34 di 113

3.4. GESTIONE DEGLI UTENTI E GRUPPI

Pagine

Organizzazioni

Ruoli organizzazione

Ruoli

Utenti

Gruppi di utenti

Pagine

Comunit

Ruoli comunit

Figura 3.1: Organizzazione delle risorse umane e loro gruppi nel portale. pubblico, e che magari allutente autenticato riserva pi funzionalit personalizzate, saranno apportate opportune configurazioni alle portlet; se, invece, il portale totalmente privato, ad esempio unintranet, saranno fatte le diverse configurazioni del caso. In generale si pu parlare di ruoli allinterno di Liferay: avere un ruolo significa sostanzialmente possedere un insieme di permessi di esecuzione di alcune azioni. Nel sistema sono presenti dei ruoli predefiniti: amministratore, ospite, ecc.. Tuttavia possibile definire e personalizzare i ruoli, creando cos profili molto particolari, che possono ad esempio avere accesso solo su determinate portlet e/o che possono svolgere su di esse solamente alcune azioni.

3.4.1

Utenti

Gli utenti possono essere raggruppati in diverse maniere. Possono essere infatti membri di gerarchie di unorganizzazione oppure far parte di gruppi arbitrari (ad esempio il gruppo Bloggers che permetterebbe loro, ad esempio, di creare pagine di blog nei loro spazi personali). Possono anche essere raggruppati da comunit che condividono un interesse comune. Possono infine avere uno o pi ruoli che descrivono le loro funzioni nel sistema e tali ruoli possono essere nellambito dellorganizzazione, della comunit o dellintero portale. Ogni utente autenticato, inoltre, pu possedere un numero a piacere di pagine private, ovvero accessibili solo da lui, e di pagine pubbliche, cio accessibili a tutti gli utenti della comunit o organizzazione. 35 di 113

CAPITOLO 3. LA PIATTAFORMA LIFERAY PORTAL

3.4.2

Gruppi di utenti

I gruppi sono semplici raggruppamenti di utenti. Non vi un particolare modo di intendere il significato di gruppo. Infatti, i gruppi possono essere creati in base alla nazione di provenienza o in base alla professione ad esempio; la scelta del tutto arbitraria. Un gruppo pu essere parte di comunit o ruoli e ad esso non possono essere assegnati dei permessi. Anche se i gruppi non hanno delle pagine come nel caso degli altri raggruppamenti (comunit o organizzazioni), dispongono di template che possono essere usati per creare e modificare le pagine personali di un utente associato a quel gruppo.

3.4.3

Organizzazioni

Le organizzazioni sono insiemi gerarchici di utenti. Sono utili per poter suddividere gli utenti nello stesso modo in cui sono suddivisi allinterno delle imprese cui appartengono. In sostanza ci che si pu fare creare delle gerarchie aziendali. Ad esempio, se con Liferay si vuole gestire una grande azienda, pu essere utile definire un determinato utente attraverso la sua posizione nellorganigramma aziendale. Se, ad esempio, quellutente un responsabile commerciale che lavora sia per la sede di Padova che per quella di Bologna, potrebbe essere membro delle organizzazioni Vendite, Sede di Padova e Sede di Bologna. Le organizzazioni possono essere parte di comunit e, come queste ultime, dispongono di pagine personalizzabili al loro interno.

3.4.4

Comunit

Le comunit sono gruppi di utenti che condividono un particolare obiettivo/interesse comune. Esse, infatti, sono molto simili alle organizzazioni ad eccezione di non essere gerarchiche e sono pensate per essere dei luoghi a se stanti ai quali chiunque, da ogni organizzazione (o anche da nessuna), pu unirsi. Le comunit si possono poi utilizzare in ogni situazione in cui si ha la necessit di tralasciare la struttura organizzativa e raggruppare gli utenti in modo trasversale. Le comunit sono i luoghi di lavoro ideali dei team per collaborare su progetti comuni. Forniscono infatti unarea isolata dove un gruppo di persone possono inserire tutte le loro informazioni relative ad un particolare argomento. Molte aziende le usano proprio per tale scopo, in quanto questo si rivela essere un sistema di gran lunga migliore di condividere i dati rispetto alluso di mail e semplici cartelle condivise in rete. Come visto in precedenza, infatti, la document library consente agli utenti di accedere ai documenti presenti in essa, ed usufruire anche di un apposito sistema di versionamento. La portlet del calendario permette di tenere traccia di tutti gli appuntamenti e le riunioni del team di lavoro, mentre il forum un ottimo strumento per mantenere in un solo posto tutte le discussioni dei membri. La home page di default di Liferay una comunit chiamata Guest e su 36 di 113

3.5. SCOPE questa andrebbe inserito il sito web pubblico accessibile da tutti. Le comunit possono essere create e gestite in due modi. Il primo attraverso il pannello di controllo, proprio come ogni altra risorsa del portale. Laltro tramite la portlet Le mie comunit che pu essere aggiunta in ogni pagina. Tale portlet permette agli utenti di scorrere la lista delle comunit e per ognuna di esse scegliere se unirsi o meno. Ci permette allamministratore del portale di fornire questa funzionalit agli utenti senza dare accesso loro al pannello di controllo. In Liferay si individuano tre tipi di comunit: pubbliche; private; nascoste. Una comunit pubblica permette agli utenti del portale di unirsi od uscire da essa ogni qualvolta lo vogliono. Questo lo possono fare utilizzando il pannello di controllo o la portlet dedicata a tale scopo (che deve essere aggiunta ad una pagina a cui gli utenti hanno accesso). Una comunit privata, invece, necessita che gli utenti siano aggiunti ad essa dallamministratore della comunit. Gli utenti, anche in questo caso, possono usare il pannello di controllo o la portlet dedicata per richiedere ladesione. Infine, una comunit nascosta come una privata, con laggiunta del fatto che essa non visibile nella portlet delle comunit o come entry del pannello di controllo.

3.4.5

Ruoli

I ruoli sono raggruppamenti di utenti che condividono una funzione particolare allinterno del portale, secondo un determinato ambito. Quindi, avendo definito i possibili ruoli che gli utenti possono ricoprire, la loro suddivisione secondo questo parametro viene di conseguenza. I ruoli possono concedere dei permessi alle varie funzionalit presenti e in tal senso si pu pensare ad un ruolo come ad una descrizione di una funzione. Ad esempio, un ruolo con il nome Amministratore forum molto probabilmente avr i permessi per far funzionare opportunamente la portlet del forum. Gli utenti che si collocano in quel ruolo erediteranno tutte le varie autorizzazioni stabilite. I ruoli possono essere legati allintero portale, ad unorganizzazione o ad una comunit. Anche in questo caso il pannello di controllo fondamentale, in quanto consente di assegnare gli utenti a dei ruoli ed attribuire particolari permessi a questi ultimi. 37 di 113

CAPITOLO 3. LA PIATTAFORMA LIFERAY PORTAL

3.5

Scope

Nella versione 5.2 di Liferay stato introdotto il concetto di scope. In italiano questo termine pu essere tradotto come ambito o meglio ancora come raggio dazione. Pi in dettaglio, si pu dire che uno scope identifica un insieme di dati che isolato da un altro insieme di dati memorizzato nel database del portale. Ad esempio, se si aggiunge una portlet del forum in due comunit diverse, ognuna ha il proprio insieme di dati. Come citato in precedenza, un ruolo pu essere in ambito del portale, di unorganizzazione o di una comunit. Ci significa che ha effetto solo nellambito in cui risiede. Ritornando allesempio fatto nella sezione 3.4.5, si pu dire che un ruolo Amministratore forum con completo accesso alla relativa portlet presenta dei permessi differenti a seconda dello scope del ruolo. Infatti se un ruolo normale, i membri hanno il permesso di gestire i forum dellintero portale. Se, invece, un community role i membri hanno il permesso di gestire i forum solo allinterno delle comunit in cui sono membri del ruolo. Se, infine, un organization role i membri hanno lautorizzazione di amministrare il forum solamente nelle organizzazioni in cui sono membri del ruolo. Similmente a ci, anche alcune portlet presenti in Liferay possono ora avere degli scope che vanno oltre le specifiche comunit o organizzazioni su cui sono inserite. Infatti, possibile fare in modo che lo scope sia per pagina. Questo permette di aggiungere ad una comunit/organizzazione un numero qualsiasi di tali portlet e, fino a quando queste ultime verranno inserite in pagine diverse, avranno insiemi di dati differenti. Ci permette di avere pi di unistanza di una certa portlet in una comunit o organizzazione. Tutte le principali portlet out of the box (forum, blog, calendario, ecc.) di Liferay supportano il concetto di scope e questo offre molta pi flessibilit nel modo in cui si desidera impostare il portale. Tuttavia, per default, lo scope impostato che sia per comunit o organizzazione. Se lo scope di una determinata portlet per pagina, quindi, si possono inserire diverse istanze della stessa in una certa comunit/organizzazione, purch siano piazzate in pagine differenti.

3.6

Architettura e framework

Laspetto pi importante di ogni portale senza dubbio larchitettura sottostante. Quella di Liferay, oltre ad essere adatta per le normali applicazioni, supporta la massima disponibilit per sistemi di tipo mission-critical. Infatti, in grado di bilanciare una solida struttura che garantisce limplementazione dei principali portal standards con il valore e gli standard messi a disposizione dai maggiori open frameworks. La figura 3.2 mostra i diversi strati dellarchitettura e le funzionalit delle portlet. 38 di 113

3.6. ARCHITETTURA E FRAMEWORK

Portlets (JSR 168 / JSR 286) Portal-Kernel Portal-Impl

Web Services Portal-Service

XML, JSON, REST RMI, , SOAP etc. ,

Service Interface (Spring) CMS JSR 170 Events Message Bus Hibernate JDBC External Web Applications Servlet Container

Enterprise Service Bus (Mule / ServiceMix) Mail Server LDAP Server

Share Point

BPM

Bl XForms Reporting

JCR Repository

Database

Figura 3.2: Architettura di Liferay Portal.

3.6.1

Service Oriented Architecture

La piattaforma completamente basata sui principi di progettazione che fanno riferimento alla Service Oriented Architecture (SOA). Vi infatti la necessit di avere un modo standard per esporre un software su una rete attraverso uninterfaccia comprensibile da tutte quelle aziende che, volendo far interagire le proprie applicazioni con quelle di altre compagnie, riconoscono tale standard. Una SOA (Architettura Orientata ai Servizi) un modello architetturale per la creazione di sistemi residenti su una rete che focalizza lattenzione sul concetto di servizio. Un sistema costruito seguendo questa filosofia costituito da applicazioni, chiamate appunto servizi, ben definite ed indipendenti luna dallaltra, che risiedono su pi computer allinterno di una rete (ad esempio la rete interna di unazienda o una rete di connessione fra pi aziende che collaborano: intracompany e intercompany network). Ogni servizio mette a disposizione una certa funzionalit e pu utilizzare quelle che gli altri servizi hanno reso disponibili, realizzando, in tal modo, applicazioni di maggiore complessit. Larchitettura SOA, che si pu considerare quindi come una forma particolare di sistema distribuito, presenta alcune caratteristiche e propriet orientate al riutilizzo e allintegrazione in un ambiente eterogeneo che devono essere rispettate dai servizi. In particolare un servizio dovr: essere ricercabile in base alla sua interfaccia e recuperabile dinamicamente a tempo di esecuzione; essere ben definito, completo ed indipendente dal contesto o dallo stato di altri servizi; essere definito da uninterfaccia ed indipendente dallimplementazione; essere debolmente accoppiato con altri servizi; 39 di 113

CAPITOLO 3. LA PIATTAFORMA LIFERAY PORTAL essere reso disponibile sulla rete tramite la pubblicazione della sua interfaccia ed accessibile in modo trasparente rispetto alla sua allocazione; fornire uninterfaccia possibilmente a grana grossa, con poche funzionalit in modo tale da non dover avere un programma di controllo complesso; essere realizzato in modo tale da permetterne la composizione con altri.

In poche parole, si pu dire che le caratteristiche chiave di Liferay comprendono, tra gli altri aspetti, lutilizzo massiccio dei principi SOA, affidabili sotto il profilo della sicurezza ed integrati con SSO e LDAP. La piattaforma, inoltre, fornisce particolari strumenti e framework per estendere il concetto di SOA ad altre applicazioni enterprise. Larchitettura permette inoltre agli utenti di accedere al portale non solo con i dispositivi tradizionali e wireless, ma gli sviluppatori possono effettuare laccesso grazie a specifiche API per mezzo di protocolli quali REST, SOAP, XML-RPC ed altri.

3.6.2

Enterprise Service Bus

LEnterprise Service Bus (ESB) un gestore centrale delle connessioni che permette ad applicazioni e servizi di essere aggiunti rapidamente ad uninfrastruttura enterprise. Quando unapplicazione deve essere sostituita, essa pu essere facilmente disconnessa dal bus. In particolare, Liferay usa Mule o ServiceMix come ESB. Attraverso questo gestore il portale pu essere integrato con molteplici software, tra i quali SharePoint, applicazioni per il Business Process Management (BPM ) (che servono per ottimizzare e monitorare i processi aziendali), repository JCR (Content Repository API for Java) ed altri. Supporta lo standard JSR 170 per il CMS. Utilizza, inoltre, Hibernate e JDBC per la connessione con qualsiasi database. LESB supporta anche un sistema di eventi basato su messaggi asincroni. Liferay supporta inoltre dei web services per rendere pi facile la comunicazione tra diverse applicazioni in ambiente enterprise. Applicazioni Java, .NET e proprietarie possono funzionare facilmente assieme poich i servizi web usano gli standard XML. Liferay utilizza diversi sistemi di crittografia, tra i quali algoritmi avanzati come DES, MD5 e RSA. Proprio per questo, considerato uno dei portali pi sicuri del mercato. In breve, si pu dire che un portale basato su Liferay generalmente utilizza lESB per dotarsi di un layer di astrazione sopra limplementazione di un Enterprise Messaging System (EMS), che consente di inviare semanticamente dei precisi messaggi tra sistemi di computer. Ci permette di utilizzare il contenuto della comunicazione senza scrivere codice. 40 di 113

3.7. STRATEGIE DI SVILUPPO DEL PORTALE

3.6.3

Spring

Liferay usa il framework Spring per gli strati dei dati di business e dei servizi. Inoltre, lo utilizza anche per la gestione delle transazioni. Tale framework, infatti, ha come obiettivo principale quello di gestire la complessit nello sviluppo di applicazioni enterprise in ambiente Java. Unimportante sua caratteristica quella di non essere intrusivo, in quanto gli oggetti sviluppati non dipendono dalle classi del framework. Due sono gli aspetti principali di Spring i quali vengono spiegati qui di seguito. Il primo il pattern Inversion of Control (IoC) che serve a minimizzare le dipendenze fra gli oggetti rendendo unapplicazione pi robusta, facilitando anche il riutilizzo dei componenti e rendendo pi semplice lo sviluppo. Il concetto alla base dellIoC che le dipendenze degli oggetti devono essere risolte da una qualche infrastruttura esterna che ha la responsabilit di istanziare gli oggetti e di fornire loro le relative dipendenze. Quindi, il ciclo di vita degli oggetti gestito da unentit esterna (container) come anche la loro configurazione che usa file XML. Una delle tecniche con cui si pu attuare lIoC la Dependency Injection (DI), cio il container si fa carico di iniettare le dipendenze nellistanza di un oggetto automaticamente e a runtime. Per fare questo utilizza costruttori e metodi setter. Attraverso la DI, quindi, si riesce a separare il comportamento di una componente dalla risoluzione delle sue dipendenze, minimizzando, allo stesso tempo, il livello di accoppiamento. La seconda nozione quella dellAspect Oriented Programming (AOP), un paradigma di programmazione che mira a disaccoppiare tutte quelle caratteristiche di un sistema che sono logicamente indipendenti da esso stesso ma lo invadono in maniera capillare (ad esempio la security e gli aspetti transazionali). In Liferay, linterfaccia che espone i vari servizi della piattaforma basata appunto sul framework Spring. Basato su tale interfaccia Portal-Impl, una libreria di Liferay il cui utilizzo rivolto principalmente per usi interni alla piattaforma, come ad esempio per lambiente di estensione Ext del quale verr parlato in seguito. Altre librerie, come Portal-Kernel e Portal-Service, sono invece previste per usi esterni (e anche interni). Forniscono infatti delle API che possono venir sfruttate da plugin esterni, come avviene nellambiente Plugins SDK (descritto anche questo in seguito) per lo sviluppo di temi e portlet.

3.7

Strategie di sviluppo del portale

Un portale costruito con Liferay pu essere esteso secondo i seguenti tre livelli di sviluppo, illustrati anche in figura 3.3: ambiente Plugins SDK ; 41 di 113

CAPITOLO 3. LA PIATTAFORMA LIFERAY PORTAL ambiente Extension; codice sorgente di Liferay Portal.

Plugins SDK Environment Extension Environment Liferay Portal Source Code

Level l Level ll Level lll

Figura 3.3: Strategie di sviluppo di Liferay. Generalmente, ogni livello di estensibilit offre un diverso compromesso tra flessibilit e requisiti differenti per far migrare il sistema verso successive versioni. Si pu parlare subito del terzo livello di sviluppo con il quale si va a modificare direttamente il codice sorgente di Liferay. Questo approccio dovrebbe essere utilizzato solamente per sviluppi sponsorizzati, ovvero sviluppare specifiche funzionalit per determinati progetti e contribuire con esse ad estendere, integrare e correggere il codice sorgente. Gli ambienti Plugins SDK ed Extension vengono presentati nelle prossime due sezioni.

3.7.1

Ambiente Plugins SDK

Plugins SDK un semplice ambiente per lo sviluppo di plugin e, quindi, serve per realizzare portlet, temi, layout, hooks 1 come software indipendente dal portale. Tutte queste componenti sono hot-deployable. In particolare, le portlet create in Plugins SDK possono importare classi solamente dalle librerie Portal-Kernel e Portal-Service (e dagli altri file JAR presenti nella cartella /WEB-INF/lib della portlet), ma non da Portal-Impl. Ci forza le portlet ad affidarsi completamente alle API del portale e a non dipendere dalle classi implementative definite in Portal-Impl. Per gestire le propriet del portale, lingua e JSP relative a Portal-Impl si devono usare gli hook. Lambiente SDK consente quindi di creare plugin hot-deployable per il portale Liferay attraverso linvocazione di task di Ant (descritto brevemente in un paragrafo dedicato nella sezione 5.2.1) forniti insieme allSDK, che permettono di automatizzare attivit (come ad esempio la generazione automatica della struttura del progetto o il deploy a caldo sul server) senza dover riavviare lapplication server. Dunque, dapprima vengono sviluppati i plugin e poi vengono usati tali task per costituire dei file WAR che vengono direttamente
hooks: un plugin out of the box di Liferay che permette, come dice il nome, di agganciarsi al codice di Liferay per modificare le funzionalit del core, come ad esempio il sistema di gestione di eventi, i model listeners, propriet del portale e relativi file JSP
1

42 di 113

3.7. STRATEGIE DI SVILUPPO DEL PORTALE copiati in unapposita cartella di Auto Deploy. In seguito, il portale, assieme allapplication server, individua ogni archivio WAR presente nella directory di hot-deploy ed estrae automaticamente i file al loro interno nella cartella di deployment del server. Il funzionamento dellambiente Plugins SDK riportato nella seguente figura.
Ant Deploy Hot Deploy

Plugins SDK

Auto Deploy Directory

Liferay Portal + Application Server

Figura 3.4: Funzionamento dellambiente Plugins SDK. Le portlet vanno a finire nella cartella /portlets, i temi in /themes, i template di layout nella cartella /layouttpl, le applicazioni web in /webs e gli hooks nella directory /hooks.

3.7.2

Ambiente Extension

Lambiente Extension (Ext) permette di personalizzare completamente Liferay Portal. Infatti, estende lambiente di sviluppo del portale, avendo la possibilit di agire sui file di configurazione del portale e sul codice Java e JSP relativo a Portal-Impl. quindi un wrapper per i sorgenti del core di Liferay (per questo motivo la struttura delle cartelle in Ext rispecchia la gerarchia delle directory dei sorgenti, cio ext-impl/, ext-service/ e ext-web/). Si possono configurare layout, temi, deployment, Hibernate, cache, impostazioni varie su utenti, gruppi, lingua, sessione, autenticazione, eventi e cos via, attraverso file di properties con desinenza ext. In particolare, le opzioni generali qui citate vengono settate tramite il file portal-ext.properties. Il file system-ext.properties, invece, modo conveniente per fornire ed estendere le Java System Properties usate dal portale. In Ext si possono creare anche delle classi personalizzate per estendere il portale, configurandole tramite il file portal.properties. In tutti questi casi, comunque, il codice sorgente di Liferay non viene modificato in alcun modo, in quanto tutte le personalizzazioni sono organizzate in un progetto separato con lobiettivo di agevolare lupgrade a nuove versioni di Liferay in cui inserire le personalizzazioni realizzate per le precedenti versioni. Come illustrato nella seguente figura, il funzionamento dellambiente di estensione pu essere riassunto in pochi punti: il custom code sovrascrive (override) il codice sorgente del portale nellambiente Ext; prima del processo di deploy il custom code viene fuso (merge) con il codice sorgente del portale sempre nellambiente Ext; il risultato 43 di 113

CAPITOLO 3. LA PIATTAFORMA LIFERAY PORTAL una versione custom del portale Liferay (Customized Liferay Portal) costruita in ambiente Ext; il portale Liferay cos personalizzato viene quindi deployato da Ext sullapplication server.

override Liferay Portal Source Code

merge Customized Liferay Portal

deploy

Custom Code

Application Server

Figura 3.5: Funzionamento dellambiente Extension. Per il codice sorgente custom, si pu usare anche il meccanismo Spring-based di Dependency Injection, configurato nel file ext-spring.xml. Il descrittore web.xml da invece la possibilit di estendere le definizioni delle servlet. Inoltre, il file struts-config.xml permette di aggiungere definizioni per le action delle portlet realizzate seguendo il framework Struts (che verr presentato nei capitoli dedicati rispettivamente alla correzione e allo sviluppo del portale). Come detto, in Ext si possono creare delle portlet che hanno accesso a Portal-Impl, realizzando semplici file JSP e il tutto, quindi, molto flessibile. Un aspetto per da tenere in considerazione il fatto che le portlet realizzate in Ext non sono hot-deployable e dunque lapproccio di sviluppo mediante lExtension environment pu essere usato solo per i sorgenti del portale e delle portlet interne al portale, ma non per le portlet out of the box, ovvero quelle distribuite al di fuori della web app del portale (ossia la ROOT ).

44 di 113

Capitolo 4
Analisi dei requisiti
In questo capitolo si caler la piattaforma Liferay nel contesto aziendale, presentando innanzitutto il portale Euris Due.Zero. Seguir poi unanalisi dei problemi e delle mancanze di cui soffriva questultimo. Da questa disamina sono infatti emersi i vari requisiti previsti per lattivit di stage. Alcuni di questi, comunque, riguardanti in particolar modo le funzionalit da sviluppare erano gi stati prefissati al momento del colloquio iniziale con lazienda.

4.1

Euris Due.Zero

Nel 2010 lazienda ha lanciato Euris Due.Zero, una piattaforma di social networking che consente la comunicazione e la condivisione di conoscenza fra tutti i dipendenti di Gruppo Euris, spesso lontani fra loro. Tale portale agisce quindi da intranet (o meglio dire da extranet, in quanto accessibile anche a soggetti non operanti allinterno di una stessa rete locale, tramite interfaccia web) per lazienda, fornendo cos un luogo comune dove poter reperire ed inserire informazioni utili al fine aziendale. Inoltre, iniziata ormai da anni e prosegue tuttora una fase di espansione e riorganizzazione del gruppo e dunque lazienda ha sentito ancor pi lesigenza di dotarsi di una piattaforma di questo tipo, che potesse far collaborare al meglio le diverse figure professionali operanti al suo interno. Come illustrato in precedenza, Liferay mette a disposizione diversi strumenti per la collaborazione e varie modalit per lorganizzazione interna degli utenti. In particolare, lazienda ha optato per organizzare il personale secondo delle comunit. Un dipendente pu quindi far parte di una o pi comunit a seconda che svolga una determinata funzione o che operi in una certa sede. Gli amministratori hanno inizialmente dotato ogni comunit di sette pagine, una per la home della comunit, contenente le portlet generali di varie utilit, una per la portlet del calendario per la consultazione degli eventi aziendali, una per la portlet della document library, una quarta per il forum, unaltra per il 45 di 113

CAPITOLO 4. ANALISI DEI REQUISITI blog, una per la portlet della Wiki e unultima per visualizzare informazioni sui membri della comunit. Quando una certa comunit viene creata, viene apportata questa configurazione di default e ci stato reso possibile grazie allinserimento in portal.properties di impostazioni apposite. In seguito gli amministratori (anche quelli della comunit) possono aggiungere o togliere pagine e relativi contenuti a piacimento. Il portale presenta caratteristiche particolarmente spiccate per quanto riguarda la collaborazione aziendale, in quanto, gi al momento del suo concepimento, sono stati integrati diversi tool della suite Liferay Social Office. Questultima soluzione ha lo scopo di facilitare la comunicazione interna, costruire una coesione di gruppo ed incrementare la produttivit. La comunit di Liferay ha messo a disposizione sul web una versione bundle di Liferay Social Office, ovvero una versione precompilata adatta agli utenti non sviluppatori. Tuttavia, per ovvi motivi, tale scelta non stata presa in considerazione. Lapplicazione stata invece integrata in Liferay Portal, installando in ambiente Plugins SDK il relativo tema (so-theme) e la specifica portlet (so-portlet), entrambi presenti nel repository in rete, mediante opportuni comandi di build gestiti con Ant. Si pu dire quindi che Social Office una particolare istanza del portale che fornisce strumenti pi adatti al lavoro in team, offrendo, ad esempio, una document library con maggiori funzionalit e migliorie in diverse altre portlet volte ad incentivare attivit collaborative.

4.1.1

Problemi e mancanze

Essendo Liferay un progetto open source, soffre di alcuni bug, alcuni dei quali possono risultare molto fastidiosi per gli utilizzatori del portale. In particolare, nelle prime settimane di stage, dopo aver studiato dapprima il funzionamento generale del portale e poi la sua architettura interna, sono passato allindividuazione dei problemi di cui era affetta la piattaforma. Ho dunque cercato di scoprire quali erano le cause di tali problemi tracciando il comportamento dellapplicazione durante lesecuzione della stessa in particolari situazioni. Sono stati determinati i seguenti problemi principali: layout disordinato e confusionario in alcuni punti; mancato redirect ad una pagina richiesta dallutente dopo la sua autenticazione; alcune funzionalit implementate soltanto parzialmente; assenza di alcune portlet specifiche per la fruizione di contenuti e la cooperazione aziendale. 46 di 113

4.1. EURIS DUE.ZERO

4.1.2

Lista dei requisiti

Nellelenco qui sopra sono stati riportate le lacune che affliggevano maggiormente il portale aziendale. Da queste sono emersi i diversi requisiti richiesti dallazienda, estrapolati proprio grazie allanalisi fatta. Tuttavia, come detto, alcuni di questi erano gi stati fissati inizialmente. I requisiti, suddivisi per risoluzione o sviluppo di funzionalit, si possono elencare di seguito: risoluzione dei problemi e stabilizzazione dellapplicazione web: modifica del messaggio di benvenuto presente nella barra superiore di quasi tutti i temi installati; correzione reindirizzamento ad una pagina richiesta dallutente dopo la sua autenticazione al portale; filtraggio operazioni di modifica / modifica minore di una pagina della Wiki nella portlet delle attivit; modifica del formato di default delleditor per la creazione di una pagina Wiki. sviluppo di nuove funzionalit: implementazione di un sistema per la modifica dei documenti caricati nel portale; visualizzazione embedded di un documento presente allinterno della piattaforma; realizzazione di diverse portlet per dotare lambiente di ulteriori funzioni organizzative e collaborative, quali: (a) visualizzare informazioni pertinenti una certa comunit e/o lutente autenticato; (b) fornire ai membri dellazienda un accesso semplice ed immediato alle comunit di cui fanno parte e alle relative risorse, dopo il loro login al portale; (c) consentire a ciascun utente di segnalare le proprie aree di interesse e competenza e tenersi aggiornato su di esse attraverso il forum aziendale; (d) permettere a determinati utenti di inviare un feedback mensile al loro responsabile di progetto.

Durante il colloquio con il tutor aziendale erano stati concordati con precisione solamente alcuni requisiti relativi allimplementazione di nuove funzionalit. In particolare, lo sviluppo del sistema di modifica dei documenti e lintegrazione nel 47 di 113

CAPITOLO 4. ANALISI DEI REQUISITI portale dellapplicazione interna allazienda realizzata in Microsoft Silverlight per la compilazione dei rapportini. Questultimo requisito, per, non stato possibile soddisfarlo poich il team di lavoro responsabile dello sviluppo dellapplicazione non lha completata entro i termini previsti (entro cio la durata della mia permanenza in azienda per lattivit di stage).

48 di 113

Capitolo 5
Ambiente e strumenti di lavoro
Al mio arrivo in azienda, il portale era gi online e, quindi, lambiente in locale era configurato ed operativo. Dunque, si agito su di esso per tutte le varie modifiche ed aggiunte da me effettuate. Qui di seguito comunque descriver brevemente le fasi principali per linstallazione e la configurazione dellapplicazione web, per comprendere al meglio il contesto da cui partito lo sviluppo. Inoltre verranno presentati i diversi strumenti software, alcuni necessari allesecuzione dellapplicativo e altri usati per lo sviluppo. Il sistema operativo a cui si fa riferimento Windows XP Professional, messo a disposizione dallazienda.

5.1

Installazione e configurazione del portale

Linstallazione di Liferay Portal per la realizzazione del portale aziendale Euris Due.Zero stata eseguita innanzitutto scaricando il codice sorgente (Liferay Portal Source) dallindirizzo http://downloads.sourceforge.net/lportal/ liferay-portal-src-5.2.3.zip. Era anche possibile scaricare una versione bundle, ovvero un pacchetto nel quale il portale precompilato e preconfigurato su unapplicazione server (sono disponibili diversi pacchetti per vari application server), ma si optato per il solo source code per il suo development. Linstallazione quindi avvenuta separatamente dal server che, in questo caso, Apache Tomcat. Si creata unapposita cartella per il progetto (nel seguito si consideri C:/Projects/liferay/) e in essa si sono poste due ulteriori directory, una per il codice sorgente del portale (cartella portal) e unaltra (tomcat) per lapplication server (dopo aver scompattato i due archivi). Come visto nella sezione 3.7, per poter sviluppare codice custom e personalizzare completamente il portale necessario impostare i due ambienti Ext e Plugins SDK. 49 di 113

CAPITOLO 5. AMBIENTE E STRUMENTI DI LAVORO

5.1.1

Ambiente Ext

Per costruire lambiente Extension, in C:/Progetto/liferay/portal si creato il file release.{username}.properties (che aggiunge direttive a quelle generali del file release.properties presente in quella stessa cartella), dove al posto di {username} si messo appunto uno username scelto. Nel file si inserita la seguente riga:
lp . ext . dir = C :/ Projects / liferay / ext

Tale propriet definisce il percorso dove va a risiedere lambiente Ext. Per creare effettivamente questultimo, dal prompt si dato il comando Ant ant start build-ext allinterno della cartella portal. Dopo che lambiente stato costruito, si pu eseguirne il deploy. Prima di far ci stato per necessario fornire al portale opportune direttive affinch riconosca lapplication server scelto. Dentro la cartella portal stato creato dunque il file app.server.{username}.properties (che fa loverride di app.server.properties), dove come prima, al posto di {username} si posto il nome utente. Nel file si sono inserite le seguenti propriet che definiscono il tipo di server e il percorso dov installato:
app . server . type = tomcat app . server . tomcat . dir = C :/ Projects / liferay / tomcat

stato fatto in modo inoltre che il portale si interfacciasse con un database MySQL, denominato lportal. Questo stato reso possibile grazie alle seguenti direttive inserite nel file portal-ext.properties presente nella directory ext/ext-impl:
jdbc . default . driverClassName = com . mysql . jdbc . Driver jdbc . default . url = jdbc:mysql: // localhost / lportal ? useUnicode = true & chara cterEn coding = UTF -8 jdbc . default . username ={ username } jdbc . default . password ={ password }

Al posto di {username} e {password} si sono inseriti rispettivamente il nome utente e la password impostati per accedere al database. Una volta applicate tali configurazioni, stato eseguito il deploy sul server, lanciando il comando Ant ant clean deploy da C:/Projects/liferay/ext. Cos facendo, stata eseguita una pulizia dei file temporanei presenti allinterno di Tomcat (in particolare leliminazione della directory ROOT allinterno della cartella webapps del server), riversando il codice di funzionamento del portale allinterno di webapps. A questo punto stato possibile avviare il server (con leseguibile startup.bat presente in tomcat/bin) ed accedere alla pagina iniziale del portale, digitando nel browser lindirizzo http://localhost:8080/. 50 di 113

5.2. STRUMENTI UTILIZZATI

5.1.2

Ambiente Plugins SDK

Linstallazione dellambiente Plugins SDK prevede come prima cosa il download del relativo pacchetto presente allindirizzo http://sourceforge.net/ projects/lportal/files/LiferayPortal/5.2.3/. In questo caso, stato scaricato il pacchetto denominato liferay-plugins-sdk-5.2.3.zip, della stessa versione quindi del portale per evitare problemi di compatibilit. Larchivio dunque stato scompattato in una cartella Plugins SDK allinterno del percorso C:/Projects/liferay/. Dentro la nuova directory stato creato un file build.{username}.properties dove, come al solito, al posto di {username} si pone il nome utente utilizzato in precedenza. Tale file va a sovrascrivere i valori delle propriet inseriti in build.properties presente nella stessa cartella. Nel nuovo file di properties si sono inserite queste definizioni:
app . server . dir = C :/ Projects / liferay / tomcat auto . deploy . dir = C :/ Projects / liferay / deploy

Le propriet sopracitate permettono di specificare la cartella del server e quella di Auto Deploy (si veda la sezione 3.7.1) in cui riversare i futuri deploy provenienti da questo ambiente. Con il comando Ant ant clean deploy dato allinterno della directory Plugins SDK si avviata dunque la procedura di deploy. Se tale operazione non produce errori vuol dire che lambiente operativo e si pu iniziare a lavorare su di esso.

5.2

Strumenti utilizzati

Durante lattivit di stage sono stati usati diversi strumenti software, alcuni dei quali hanno permesso la corretta esecuzione del portale, mentre altri hanno facilitato il suo sviluppo. Infatti, per impostare i due ambienti di development (Ext e Plugins SDK) per lo sviluppo, la personalizzazione, il deployment ed il debugging della piattaforma, si devono considerare, oltre al necessario codice sorgente del portale, quattro aspetti che sono: prerequisiti per linstallazione di Liferay; database; application server; Integrated Development Environment (IDE). Tutti questi punti verranno ora approfonditi presentando i diversi strumenti utilizzati e, per alcuni di essi, verranno elencati anche i vantaggi che hanno portato alla loro scelta.

51 di 113

CAPITOLO 5. AMBIENTE E STRUMENTI DI LAVORO

5.2.1

Requisiti per linstallazione

Per quanto riguarda il primo aspetto citato, necessario ricordare che Liferay Java-based, ed usa Ant come tool di build. Gli strumenti richiesti inizialmente sono quindi JDK e Ant. JDK Il JDK (Java Development Kit) un kit che consiste dal compilatore Java (javac) e da strumenti correlati ad esso (per citarne alcuni: javadoc per la generazione automatica della documentazione e jdb il debugger) che consentono la realizzazione di applicazioni Java. disponibile allURL http://www.oracle.com/technetwork/java/javase/ downloads/index.html per i diversi sistemi operativi. Dopo linstallazione necessario impostare correttamente la variabile JAVA_HOME nel sistema operativo. Ant Ant un tool che permette la configurazione, il build ed il deployment di progetti Java complessi. Sviluppato dallApache Software Foundation, Ant un applicativo che consente lautomazione del processo di build, utilizzato per la compilazione, e linstallazione (deployment) di applicazioni Java complesse, come le applicazioni enterprise. Applicazioni di questo tipo, infatti, comportano lesecuzione di diversi compiti, quali ad esempio la compilazione di sorgenti, la creazione e cancellazione di directory di supporto, la creazione di file JAR, WAR e linstallazione dei vari componenti sviluppati su application server remoti. Ant permette di organizzare, parametrizzare ed automatizzare questo tipo di operazioni. Il principale vantaggio nelluso di Ant sta nel fatto che scritto interamente in Java (prerequisito allinstallazione la presenza del JDK) ed quindi ulteriormente estendibile e portabile su diverse piattaforme. Ant esegue i suoi compiti seguendo le istruzioni definite in un file chiamato build.xml, in cui sono presenti speciali tag che servono per definire i task (ogni compito specificato allinterno di Ant un task) da elaborare. Il buildfile infatti un file di configurazione che gestisce ogni operazione eseguita dal tool ed scritto in linguaggio XML. La scelta di questo linguaggio stata dettata da due vantaggi principali: semplicit della sintassi; facilit nel descrivere la procedura di build come albero gerarchico. Per default, Ant si aspetta di trovare tale file nella directory corrente in cui lanciato. Il tool pu essere scaricato allindirizzo http://ant.apache.org e dopo il suo setup occorre settare opportunamente la variabile ANT_HOME. 52 di 113

5.2. STRUMENTI UTILIZZATI

5.2.2

Database

La scelta del database ricaduta su MySQL. Questultimo disponibile allindirizzo http://www.mysql.com. In particolare lazienda si focalizzata su MySQL Administrator utile per la gestione del database e MySQL Query Browser per la semplice interrogazione dello stesso mediante query. Dopo linstallazione stato quindi creato un nuovo database (chiamato lportal) usato dal portale. Di seguito si possono elencare brevemente diversi pregi di MySQL che hanno portato alla sua adozione: veloce; facile da usare. infatti possibile creare e interagire con un database MySQL utilizzando semplici dichiarazioni nel linguaggio SQL, che il linguaggio standard per la comunicazione con un sistema per la gestione di basi di dati relazionali (RDBMS ); poco costoso, in quanto libero sotto la licenza GPL open source e il canone per una licenza commerciale ragionevole; sicuro, poich presenta un sistema flessibile per limpostazione dei permessi (ad esempio di creare un nuovo database o eliminare dati) a specifici utenti o loro gruppi; supporta database di grandi dimensioni; pu girare su molti sistemi operativi.

5.2.3

Application server

Lazienda ha optato per lutilizzo di Apache Tomcat, un web application server open source capace di gestire e supportare le pagine JSP e le servlet nel rispetto delle loro relative specifiche. Fornisce dunque una piattaforma per lesecuzione di applicazioni web sviluppate nel linguaggio Java. Dalla versione 5.5.16 sono state ampliate le funzionalit apportando alcune importanti innovazioni, tra le quali il supporto di alcuni framework di sviluppo come ad esempio Struts, supporto ai web services e alle tecnologie di Objectrelational mapping di Hibernate. La versione usata in azienda, che si pu trovare allindirizzo http://tomcat. apache.org, la 5.5.30.

5.2.4

IDE

Come ambiente di sviluppo integrato stato utilizzato Eclipse (disponibile allindirizzo http://www.eclipse.org). Il vantaggio principale di questultimo che offre unampia scelta di software di terze parti (plugin) che ne 53 di 113

CAPITOLO 5. AMBIENTE E STRUMENTI DI LAVORO incrementano la produttivit, le potenzialit e lesperienza duso. La scelta ricaduta su di esso in quanto presenta numerosi vantaggi: Eclipse nato per programmare in Java, cio il linguaggio maggiormente utilizzato allinterno della piattaforma; possibilit di creare nuovi progetti, package e classi in modo semplice e veloce; gestione dei progetti molto flessibile tramite la vista Project Explorer; la vista Outline consente di consultare tutte le varie informazioni sul contenuto del file aperto (classi, metodi, variabili); possibilit di usufruire di formattazione e completamento automatico del codice. Nonostante tutti questi pregi, Eclipse ha anche dei difetti. Laspetto negativo pi marcato sicuramente la pesantezza e la poca reattivit dellapplicazione e ci dovuto principalmente al fatto di essere programmata in Java. Per facilitare lo sviluppo sono stati usati i seguenti plugin: Sysdeo Eclipse Tomcat Launcher (http://www.eclipsetotale.com/ tomcatPlugin.html) - utile principalmente a gestire pi facilmente lavvio, lo stop e il restart di Tomcat (il plugin compatibile con le versioni 4.x, 5.x, 6.x e 7.x dellapplication server), a configurare alcuni suoi parametri relativi alla JVM e ad impostarlo per effettuare il debugger; Web Tools Platform (http://www.eclipse.org/webtools/) - suite che estende Eclipse per lo sviluppo di applicazioni web, fornendo strumenti che aiutano la stesura di codice per i linguaggi web.

54 di 113

Capitolo 6
Stabilizzazione dellapplicazione web
In questo capitolo si descriveranno in dettaglio le modifiche apportate al portale aziendale Euris Due.Zero per correggere i diversi problemi individuati durante lanalisi e relativi appunto alla stabilizzazione dellapplicazione. Si pu dunque far riferimento ai requisiti del primo punto dellelenco presente nella sezione 4.1.2. Ogni modifica verr qui esposta in una sezione e, qualora ce ne sia necessit, nella descrizione verranno fornire le opportune nozioni teoriche non menzionate in precedenza e che hanno portato a risolvere il problema. Inoltre, sotto il titolo di ogni sezione, tra parentesi quadre verr indicato lambiente nel quale si agito principalmente per effettuare quella modifica.

6.1

Modifica del messaggio di benvenuto


[ambiente Plugins SDK ]

Per famigliarizzare con la piattaforma, inizialmente ho corretto un piccolo problema relativo al messaggio di benvenuto che viene mostrato allutente prima e dopo la sua autenticazione al portale. Tale messaggio visibile dal bottone espandibile del pannello di controllo, presente nel lato destro della dockbar di tutti i temi installati, eccetto per quello di Social Office avente un differente layout. I vari temi erano stati installati come componenti indipendenti usando lambiente Plugins SDK (posizionati allinterno della cartella themes). Una best practice riportata in [5] e [7] per la costruzione di un tema customizzato quella di porre tutte le modifiche allinterno della cartella {nome-tema}/docroot/_diffs (dove {nome-tema} si riferisce appunto alla cartella che contiene tutto ci che relativo ad un tema). In _diffs si possono dunque inserire immagini e file CSS, JavaScript e di templates personalizzati, ognuno dentro alle rispettive cartelle (images, css, javascript e templates). In questo caso mi sono focalizzato sui template. Ogni tema, infatti, possiede diversi file di template che definiscono principalmente le proprie aree di layout: 55 di 113

CAPITOLO 6. STABILIZZAZIONE DELLAPPLICAZIONE WEB init_custom.vm, nel quale si possono inizializzare variabili Velocity custom ed assegnare nuovi valori a quelle gi esistenti. Le variabili definite in tale file possono essere usate negli altri template; portal_normal.vm, template che definisce lintera pagina del portale, invocando direttamente o indirettamente tutti gli altri modelli del tema. Questo template chiamato, interpretato e renderizzato ogni qualvolta viene richiesta una pagina del portale; portal_pop_up.vm, versione analoga (in quanto definisce una pagina completa) ma semplificata del precedente, poich per le finestre popup; portlet.vm, che definisce loutput HTML per una portlet, specificando il relativo template; navigation.vm, per la barra orizzontale usata per la navigazione tra le pagine; dock.vm, che definisce la dockbar superiore della pagina. Come indica anche la particolare estensione, tali file sono scritti in Velocity Template Language (VTL) (si veda [7]), descritto brevemente nel paragrafo seguente. Velocity Template Language Questo linguaggio ha lo scopo di fornire il modo pi facile, semplice e pulito per includere contenuti dinamici ad una pagina web. quindi un template engine che processa un template (un modello, ad esempio di una pagina web) e dei dati (contenuto informativo) per produrre un documento, ad esempio una pagina web da visualizzare. Velocity un template engine che permette di referenziare, e quindi di utilizzare, allinterno del template degli oggetti Java. Il suo scopo quello di assicurare la separazione tra il presentation layer (livello di presentazione) con quello di business (che contiene la logica applicativa), livelli che sono tipici del pattern architetturale Model View Controller (MVC ). Il funzionamento del VTL si pu riassumere in queste due semplici regole: le variabili iniziano con il carattere $; le direttive (statement) iniziano con il carattere # e sono utilizzate per eseguire una certa azione. Ritornando al problema, data la particolare situazione da affrontare, in tal caso si considerato il template della dockbar, ossia dock.vm e si agito su init_custom.vm. Per impostazione predefinita, infatti, il messaggio di benvenuto fornito da una variabile user_greeting, settata nel file init.vm tramite questa istruzione: 56 di 113

6.1. MODIFICA DEL MESSAGGIO DI BENVENUTO


# set ( $user_greeting = $htmlUtil . escape ( $user . getGreeting () ) )

Tale variabile viene impostata con la stringa data da unaltra variabile welcome definita nel file Language.properties1 (settata al valore Welcome). Infatti, per assegnare a $user_greeting la frase di benvenuto viene invocato il metodo getGreeting che ritorna appunto la stringa Welcome. Da ci si pu capire come il messaggio sia uguale alla stringa Welcome! (viene aggiunto poi anche il punto esclamativo) in tutti i casi, sia prima che dopo lautenticazione di un utente al portale e questo non certo il massimo della chiarezza. In pi il termine non personalizzato a seconda della lingua impostata dallutente e questultimo pu avere difficolt nel comprenderlo, seppur sia un termine comune inglese. In init_custom.vm si quindi assegnato un nuovo valore alla variabile $user_greeting in questo modo:
1 2 3 4 # set ( $user_greeting = $languageUtil . format ( $locale , " welcome " , "")) # if ( $is_signed_in ) # set ( $items = $stringUtil . split ( $user_greeting , ! ) ) # set ( $user_greeting = $items . get (0) + " , " + $user_first_name + " " + $user_ middle _name + " " + $user_last_name + " ! " ) # end

Con la direttiva #set si assegna un valore ad una variabile. Come si pu vedere, per prima cosa la frase viene tradotta nella lingua impostata, a livello di utente loggato o predefinita del portale quando non ancora autenticato. Per far ci ho chiamato il metodo format sulloggetto languageUtil del package com.liferay.portal.kernel.language.Language. Il metodo stato invocato nel contesto locale della pagina passando come input la stringa. Dopodich tramite la variabile is_signed_in posta come condizione di #if ho verificato se stata eseguita o meno lautenticazione e, nel caso sia avvenuta, viene impostata una frase di benvenuto che mostra anche il/i nome/i e cognome dellutente. Per la visualizzazione del bottone con il messaggio viene renderizzato il relativo template dock.vm, nel quale la frase identificata da queste poche righe di codice:
1 2 3 < h2 class = " user - greeting " > < span > $user_greeting </ span > </ h2 >

Il risultato, che si pu vedere in figura 6.1, risulta dunque un po pi user friendly. In particolare, la figura 6.1a rappresenta la situazione in cui lutente
Language.properties: un file situato in portal-impl che definisce le stringhe di testo generali usate nel portale
1

57 di 113

CAPITOLO 6. STABILIZZAZIONE DELLAPPLICAZIONE WEB non autenticato (e la lingua predefinita del portale impostata ad italiano) mentre le altre due, 6.1b e 6.1c, illustrano il messaggio con utente loggato e lingua da lui settata rispettivamente ad italiano e tedesco.

(a)

(b)

(c)

Figura 6.1: Messaggio di benvenuto visibile nel pulsante del pannello di controllo in diverse situazioni. Come detto, questa modifica stata fatta per quasi tutti i temi installati, immediatamente applicata per Indigo che rispecchia il colore blu di Gruppo Euris e Crystal X, anchesso di quel colore predominante, ma pi elegante rispetto al primo. Per il tema classico (Classic), invece, ho dovuto creare un nuovo tema, sempre in ambiente Plugins SDK, che fosse identico al classico e apportare in esso le opportune modifiche. Questo stato necessario poich altrimenti tutti i cambiamenti sul tema classico dovevano essere effettuati direttamente sul codice sorgente del portale (Classic infatti incluso in Liferay ed il predefinito). Come visto in precedenza, ci si rivela essere sbagliato in previsione di futuri upgrade del sorgente. Per ovviare a questo ho dunque costruito un nuovo tema denominato ClassicBased grazie allapposito script create.bat fornito in ambiente SDK. Dalla cartella themes ho lanciato dunque il seguente comando:
create . bat classicBased " ClassicBased "

In tal modo, nella cartella classicBased stato creato un tema inizialmente vuoto. Ho quindi copiato in essa la cartella _diffs (e relative sottocartelle) del tema Classic. In seguito ho apportato una piccola variazione al buildfile del nuovo tema, che diventato il seguente:
1 2 3 4 5 <? xml version = " 1.0 " ? > < project name = " theme " basedir = " . " default = " deploy " > < import file = " ../ build - common - theme . xml " / > < property name = " theme . parent " value = " classic " / > </ project >

La modifica ha riguardato lattributo value del tag property che stato impostato al valore classic. Cos facendo il nuovo tema classico personalizzato eredita tutte le caratteristiche del tema Classic. Si eseguito quindi il deploy del tema, facendo il build con Ant. 58 di 113

6.2. REDIRECT DOPO LAUTENTICAZIONE DELLUTENTE

6.2

Redirect dopo lautenticazione dellutente


[ambiente Extension]

Un grave problema che affliggeva il portale aziendale era sicuramente quello dovuto al mancato reindirizzamento dellutente, in seguito alla sua autenticazione, ad una specifica pagina del portale da lui richiesta. Questo bug stato riscontrato nei momenti in cui lazienda forniva un link diretto ad una pagina interna al portale per far s che i dipendenti la trovassero pi agevolmente, senza doverla cercare tra le varie comunit. Un utente dunque cliccava sul link, effettuava il login corretto ma dopo non veniva rimandato alla pagina richiesta, bens a quella principale impostata di default. Per la risoluzione di tale problema, in primo luogo ho cercato di comprendere come viene gestita e processata una richiesta di una pagina del portale, da quando un utente la richiede al momento in cui essa viene presentata sul browser. Meccanismo di rendering di una pagina Nei seguenti punti vengono riassunti brevemente i passi che descrivono il flusso della richiesta di una pagina del portale, dalla richiesta al browser alla sua visualizzazione: 1. la richiesta entra attraverso la classe MainServlet. Nella richiesta (e anche nella sessione) vengono memorizzati vari attributi. In particolare lattributo WebKeys.CURRENT_URL della request detiene il path corrente richiesto a cui viene tolto protocollo, nome dellhost e porta; 2. viene chiamato lhandler service pre action definito dalla relativa classe ServicePreAction del package com.liferay.portal.events, nel quale vengono determinati il layout ed il tema da visualizzare. Il layout corrente memorizzato come attributo della request sotto la chiave WebKeys.LAYOUT (gli altri layout disponibili vengono salvati invece grazie a WebKeys.LAYOUTS). Il tema da mostrare memorizzato sempre come attributo della richiesta nella variabile WebKeys.THEME e lo schema dei colori da usare in WebKeys.COLOR_SCHEME. Generalmente, il tema e il color scheme sono ottenuti dal layout una volta che questultimo stato determinato; 3. viene fatto uso di Struts per gestire la richiesta. Liferay utilizza il proprio Struts request processor definito dalla classe PortalRequestProcessor del package com.liferay.portal.struts. Il metodo getLastPath() della classe calcola lultimo path visitato e fornisce un path predefinito per il primo accesso al portale. Il path di default al momento dellingresso cos schematizzato: <protocol>://<hostName>:<port> /portal/layout. Tale URL pu anche contenere i parametri di query ?p_l_id=default se lutente noto, cio ha appena effettuato laccesso; 59 di 113

CAPITOLO 6. STABILIZZAZIONE DELLAPPLICAZIONE WEB 4. la richiesta iniziale per /portal/layout gestita attraverso la classe LayoutAction del package com.liferay.portal.action; 5. la pagina top level da mostrare /html/common/themes/portal.jsp che specifica appunto lintera pagina del portale; 6. portal.jsp seleziona portal_normal.jsp o portal_pop_up.jsp a seconda dello stato corrente della visualizzazione del tema e la include usando lapposito tag <liferay-theme:include>, implementato dalla classe com.liferay.taglib.theme.IncludeTag che richiede a sua volta com.liferay.taglib.util.ThemeUtil.include(); 7. infine, per ogni portlet viene chiamato il metodo renderPortlet() della classe com.liferay.portal.util.PortalUtil; 8. renderPortlet() invoca a sua volta la pagina render_portlet.jsp (definita allinterno di portal/portal-web/docroot/html/portal/) per fare il render dei contenuti di una singola portlet; 9. render_portlet.jsp chiama a sua volta portlet.jsp presente allinterno di /portal/portal-web/docroot/html/common/themes/; 10. portlet.jsp finisce per chiamare il file portlet_content.jsp (sempre dentro la precedente cartella citata) che visualizza effettivamente il frammento della portlet. Dopo aver compreso meglio il funzionamento del flusso della request, ho iniziato la risoluzione del problema focalizzandomi su due classi Java: la classe LayoutAction (come dal punto 4 del precedente elenco numerato) che gestisce la richiesta iniziale; la classe LoginAction che rappresenta laction della portlet di login (realizzata mediante il framework Struts, spiegato brevemente in seguito) la quale fa eseguire effettivamente lautenticazione di un utente al portale. Il considerare la seconda classe citata deriva dal fatto che, come noto, in seguito ad una richiesta di una pagina interna del portale da parte di un utente non autenticato, questo viene indirizzato alla home page (che, come detto, accessibile da chiunque facendo parte della comunit Guest) in cui presente il form di login. Per la risoluzione del problema ho quindi lavorato in ambiente Ext, ricostruendo i percorsi delle due classi (entrambe collocate in portal-impl). Ho potuto cos inserire del codice customizzato che sovrascriveva il sorgente del portale. Ho innanzitutto testato passo passo il malfunzionamento, eseguendo delle opportune stampe in certi punti del flusso desecuzione dellazione di login al 60 di 113

6.2. REDIRECT DOPO LAUTENTICAZIONE DELLUTENTE portale. Ho infatti posto delle stampe in determinati metodi delle due classi che venivano invocati alcuni per gestire la richiesta pervenuta ed altri per effettuare lautenticazione. In questo modo ho scoperto che il mancato redirect era dovuto al fatto che lindirizzo determinato era incompleto, in quanto appunto mancava la parte di URL relativa al reindirizzamento. Inoltre, anche se incompleto, lURL non arrivava alla portlet di login che, di conseguenza, non poteva eseguire il giusto redirect dopo lautenticazione corretta dellutente. Per correggere il tutto ho dovuto quindi ricostruire lindirizzo della richiesta iniziale, con incluso anche il parametro di redirect, e poi metterlo a disposizione alla portlet di login che dopo lautenticazione indirizzava lutente alla pagina voluta. Un importante concetto che stato utilizzato quello di Inter-Portlet Communication spiegato nel seguente paragrafo. Inter-Portlet Communication (IPC) La prima specifica delle portlet, JSR-168, non includeva alcun supporto per la comunicazione tra diverse portlet e tra portlet e portale. Queste funzionalit sono state aggiunte grazie allo standard JSR-286. Pi precisamente, ha introdotto due metodi per implementare il meccanismo di IPC che sono: Shared render parameters: le portlet hanno la possibilit di impostare dei parametri che possono venir letti da altre portlet; Eventi: richiesti per scenari complessi, il loro vantaggio che consentono una comunicazione completamente disaccoppiata, in quanto una portlet che emette un evento non deve preoccuparsi se c qualcuno in ascolto per esso. In tal caso, si prender in considerazione solamente il primo caso poich sufficiente in molte situazioni abbastanza semplici e, quindi, anche per gli scopi di cui sopra. In particolare, come si vedr in seguito, per la realizzazione dellIPC stata utilizzata la condivisione di variabili di sessione. Un modo infatti quello di memorizzare una o pi variabili nella sessione e renderle condivisibili per le varie portlet e per il portale. Sono partito dunque ad analizzare la classe LayoutAction (che estende la classe Action del package org.apache.struts.action) soffermandomi sul metodo execute ereditato dalla superclasse e opportunamente ridefinito. Come si pu notare, la classe Action fa parte delle API di Struts, framework spiegato brevemente nel successivo paragrafo. 61 di 113

CAPITOLO 6. STABILIZZAZIONE DELLAPPLICAZIONE WEB Struts Il framework Apache Struts una soluzione open source per la creazione di applicazioni web basate su Java. Le web application differiscono dai siti convenzionali per il fatto che possono produrre dei contenuti dinamici. Molti siti web infatti producono solo pagine statiche. Unapplicazione web pu invece interagire con database e motori di business logic per creare i propri contenuti. Le web application basate su JavaServer Pages (JSP)2 si mescolano a volte con diversi codici, relativi al database, alla progettazione della pagina e al flusso di controllo. In pratica, se questi concetti non sono tra loro separati, le applicazioni pi grandi diventano difficili da manutenere. In unapplicazione software un modo per tenerli separati quello di usare il pattern architetturale Model View Controller (MVC ) illustrato in figura 6.2.
Model

Richiesta stato

Cambio di stato

Notifica stato

View Selezione View

Controller

Input utente

Figura 6.2: Diagramma di interazione del pattern architetturale MVC. Il Model rappresenta il codice di business o del database (definisce i dati e le operazioni che possono essere eseguite su di essi), la View la vista, ovvero il codice che realizza la logica di presentazione ed infine il Controller che implementa la logica di controllo in quanto ha la responsabilit di trasformare le interazioni dellutente della vista in azioni eseguite dal Model. In particolare in Struts tutti gli aspetti legati al Controller vengono forniti dal package action facente parte del core del framework. Struts progettato per aiutare gli sviluppatori a creare web application che fanno uso di MVC. Il framework costituito da tre componenti chiave:
JavaServer Pages: una tecnologia che fornisce un modo semplice e veloce per la creazione di contenuti web dinamici. Permette un rapido sviluppo di applicazioni web-based che sono server e platform independent
2

62 di 113

6.2. REDIRECT DOPO LAUTENTICAZIONE DELLUTENTE un request handler fornito dallo sviluppatore che viene mappato su un URI standard; un response handler che trasferisce il controllo ad unaltra risorsa che completa la risposta; una serie di librerie di tag per la gestione del rendering e mapping delle pagine web, che aiutano gli sviluppatori a realizzare applicazioni interattive form-based. In particolare, unazione (definita dalla classe Action) un adattatore tra il contenuto della richiesta HTTP di ingresso e la corrispondente logica di business che deve essere eseguita per processare la request. Il controller (ActionServlet) selezioner unaction appropriata per ogni portlet, ne creer unistanza (se necessario) ed invocher il metodo execute per eseguire lazione. Questultimo, infatti, elabora la richiesta HTTP specificata come parametro dingresso e crea la relativa risposta (o la inoltra ad un altro componente web che la creer), con la possibilit di gestire le eccezioni lanciate dalla business logic. Il metodo ritorna quindi un oggetto ActionForward che descrive dove e in che modo il controllo deve essere inoltrato, oppure null se la risposta gi stata completata. In questo caso, il metodo execute di LayoutAction esegue appunto lazione che ottiene il tema visualizzato e il layout della pagina mediante un opportuno metodo applicato alla richiesta in ingresso e che costruisce il relativo indirizzo. LURL costruito, come detto, non teneva conto per del parametro di redirect che quindi non veniva inviato correttamente alla portlet di login. Qui sotto si pu riportare (e poi commentare) un pezzo di codice del metodo che stato usato per ottenere il giusto indirizzo e metterlo a disposizione della portlet:
1 2 public class LayoutAction extends Action { public ActionForward execute ( ActionMapping mapping , ActionForm form , Htt pS er vl et Re qu es t request , H t tp S e rv l e tR e s po n s e response ) throws Exception { 3 ThemeDisplay themeDisplay = ( ThemeDisplay ) request . getAttribute ( WebKeys . THEME_DISPLAY ) ; 4 Layout requestedLayout = ( Layout ) request . getAttribute ( WebKeys . REQUESTED_LAYOUT ) ; 5 6 String redirectParam = " redirect " ; redirectParam = PortalUtil . g e t Po r t l et N a me s p ac e ( PropsValues . A U T H _ L O G I N _ P O R T L E T _ N A M E ) + redirectParam ;

63 di 113

CAPITOLO 6. STABILIZZAZIONE DELLAPPLICAZIONE WEB


7 String url = PortalUtil . getLayoutURL ( requestedLayout , themeDisplay ) ; 8 9 10 11 12 } String redirect = HttpUtil . addParameter ( themeDisplay . getURLSignIn () , redirectParam , url ) ; 13 14 if ( redirect != null && redirect != " " ) { request . getSession () . setAttribute ( " L I F E R A Y _ S H A R E D _ l o g i n R e d i r e c t " , redirect ) ; 15 16 17 } } } ... ... String qs = request . getQueryString () ; if ( qs != null && ! " " . equalsIgnoreCase ( qs ) ) { url = url . concat ( " ? " ) . concat ( qs ) ;

Come si pu osservare, per prima cosa vengono determinati il tema da visualizzare e il layout della pagina voluto attraverso la richiesta HTTP in ingresso (righe 3 e 4). Si costruisce quindi il nome del parametro di redirect che andr associato alla portlet di login (per identificarlo completamente necessario ottenere il namespace della portlet). Viene poi estrapolato lindirizzo derivante dal layout e tema richiesti (riga 7). A tale URL viene concatenata (se non nulla e non vuota) la query string tratta dalla richiesta, formando cos lindirizzo di redirect. In riga 12 allURL predefinito di sign-in al portale (la pagina in cui presente il login utente) viene aggiunto lindirizzo di redirect, costruendo lindirizzo completo, compreso del parametro di reindirizzamento. Alla riga 14 si pu notare come venga usato il meccanismo di IPC. Si realizzata infatti una comunicazione tra portale e portlet di login per lo sharing dellindirizzo di redirect, il quale non veniva spedito correttamente mediante la response. Tale comunicazione stata implementata usando la sessione. Dal momento che le portlet deployate in WAR differenti hanno sessioni diverse rispetto al portale, il meccanismo consiste di copiare gli attributi di sessione provvisti di namespace dalla sessione del portale a ciascuna delle sessioni delle portlet. Cos facendo gli attributi non corrono il rischio di venir sovrascritti accidentalmente. Daltra parte, per, possono solo essere scritti da portale a portlet e queste ultime non possono in alcun modo aggiornare il loro valore ma solo leggerlo. Per abilitare la portlet di login a considerare questi tipi di attributo, nel file liferay-portlet.xml quella portlet deve presentare:
< private - session - attributes > true </ private - session - attributes >

64 di 113

6.2. REDIRECT DOPO LAUTENTICAZIONE DELLUTENTE Nel file portal-ext.properties necessario invece fare loverride della propriet session.shared.attributes che definisce una lista di attributi (delimitati da virgole) che possono essere condivisi da tutte le portlet:
session . shared . attributes = LIFERAY_SHARED_

In tal caso, oltre allattributo di default definito da portal.properties, ne ho aggiunto un altro denominato LIFERAY_SHARED_loginRedirect che serve appunto a contenere lindirizzo di redirect. In riga 14 si pu osservare come lattributo appena citato venga impostato nella sessione del portale per fare in modo che possa essere letto dalle altre portlet. Il suo valore viene settato con il parametro di redirect costruito. In portal-ext.properties ho rimosso inoltre il reindirizzamento che veniva eseguito precedentemente alla modifica qui descritta e che, dopo laccesso, portava lutente ad una pagina predefinita, impostata grazie alla propriet login.events.post (che fa riferimento ad eventi del portale che si verificano dopo il login utente). Come detto, ho considerato anche laction della portlet di login definita dalla classe LoginAction. Questultima deve infatti recuperare lattributo di redirect ed utilizzarlo opportunamente. Per far ci ho considerato il metodo login che esegue tutte le varie operazioni necessarie allautenticazione al portale e poi al conseguente reindirizzamento. Di seguito si riporta una parte del codice del metodo:
1 2 public class LoginAction extends PortletAction { protected void login ( ThemeDisplay themeDisplay , ActionRequest actionRequest , ActionResponse actionResponse , P ort le tP re fe re nces preferences ) throws Exception { 3 4 PortletSession psession = actionRequest . g etPor tletSe ssion () ; String malformedUrl = ( String ) psession . getAttribute ( " L I F E R A Y _ S H A R E D _ l o g i n R e d i r e c t " , PortletSession . APPL ICATI ON_SCO PE ) ; 5 6 7 8 9 10 String redirectUrl = " " ; if ( malformedUrl != null ) { String splittedUrl = malformedUrl . split ( " redirect = " ) [1]; redirectUrl = URLDecoder . decode ( splittedUrl , " UTF -8 " ) ; } ... LoginUtil . login ( request , response , login , password , rememberMe , authType ) ; ...

65 di 113

CAPITOLO 6. STABILIZZAZIONE DELLAPPLICAZIONE WEB


11 12 13 14 15 16 17 18 } } else { actionResponse . sendRedirect ( " / web / ingresso " ) ; } ... } ... if ( Validator . isNotNull ( redirectUrl ) && redirectUrl != " " ) { actionResponse . sendRedirect ( redirectUrl ) ;

Come detto in precedenza, la classe LoginAction quella che definisce laction della portlet di login (portlet visibile in figura 6.3). Deriva infatti da PortletAction, classe che, a sua volta, deriva dalla classe Action del package org.apache.struts.action.

Figura 6.3: Portlet di autenticazione al portale. Nella riga 3 si pu notare come dalloggetto di tipo ActionRequest, che rappresenta la richiesta mandata alla portlet per gestire unazione, si possa recuperare la sessione della portlet in questione. Tramite questultima possibile recuperare tutti gli attributi che sono stati impostati dal portale e, in particolare, lattributo LIFERAY_SHARED_loginRedirect (riga 4). Il suo valore viene salvato nella variabile malformedUrl di tipo stringa. Tale variabile stata chiamata in questo modo in quanto la stringa lindirizzo completo per arrivare a questa portlet che comprende anche il parametro di redirect voluto. Questultimo si quindi estratto dallindirizzo completo (riga 7) e decodificato opportunamente seguendo lo schema di codifica UTF-8 (riga 8). La classe quindi invoca il metodo login che esegue lautenticazione al portale attraverso vari parametri tra cui stringa di login, password, tipo di autenticazione tutti ottenuti chiamando apposite funzioni. Infine, se lutente ha richiesto il redirect ed stato quindi impostato il relativo parametro, tramite loggetto di tipo ActionResponse si istruisce il portlet 66 di 113

6.3. FILTRAGGIO ATTIVIT DI MODIFICA PAGINE WIKI container a reindirizzare il client ad uno specifico URL (riga 12). In mancanza invece di una specifica richiesta di reindirizzamento, si fa in modo di portare lutente alla pagina della comunit dingresso del portale definita dal path relativo /web/ingresso (riga 15). Come si vedr in seguito, in questa pagina lutente potr accedere in modo semplice e veloce alle varie comunit (e relativi contenuti) di cui membro.

6.3

Filtraggio attivit di modifica pagine Wiki


[ambiente Extension]

Uno dei punti di forza di Liferay la grossa dotazione di portlet gi pronte alluso. Una di queste ad esempio la portlet Attivit che visualizza tutte le varie operazioni compiute dagli utenti su contenuti del portale. In particolare la portlet presenta tre tab, una che mostra le azioni eseguite sulle comunit di cui lutente fa parte, unaltra relativa alle operazioni fatte dai membri amici dellutente e una terza vista che riporta solamente le attivit svolte dallo stesso utente autenticato.

Figura 6.4: Portlet per il tracciamento delle attivit. Si pu parlare dunque di un meccanismo di social activity tracking che registra e visualizza certe attivit (o anche tutte) effettuate dagli utenti che provengono da una determinata portlet. In questo modo si facilita la condivisione delle informazioni allinterno dellazienda, permettendo al personale della stessa di raggiungere agevolmente le risorse aggiunte e/o modificate anche da altri. Le attivit possono riguardare un post pubblicato nel blog di una comunit da parte di un suo membro, lapertura di una discussione o la risposta di un messaggio del forum, laggiunta e laggiornamento di un evento di calendario, il caricamento di un documento nella document library ed una serie di altre 67 di 113

CAPITOLO 6. STABILIZZAZIONE DELLAPPLICAZIONE WEB azioni eseguite allinterno del portale. In questo caso ho considerato le azioni che interessano la Wiki, ovvero laggiunta e la modifica di una sua pagina. Laggiornamento di una pagina Wiki si suddivide in modifica, per indicare un cambiamento normale che pu variare anche una parte consistente di essa, o modifica minore. Questultima differisce dalla prima tipologia, in quanto pensata per indicare che la pagina ha subito appunto una piccola modifica che non riguarda la totalit o la maggior parte degli elementi (testo, link ed altri contenuti) che la costituiscono. Lazienda ha ritenuto ragionevole indicare nellactivity portlet solamente le operazioni di creazione di una nuova pagina Wiki, trascurando totalmente quelle che riguardano un suo aggiornamento (modifica o modifica minore che sia). Si optato per questa soluzione in quanto molto pi importante indicare laggiunta di una nuova pagina che una modifica (soprattutto se non particolarmente significativa) ad essa. Gli amministratori del portale hanno infatti osservato che le modifiche effettuate fino a quel momento ad alcune pagine Wiki riguardavano nella stragrande maggioranza dei casi cambiamenti di formattazione e layout del testo, sicuramente molto meno rilevanti rispetto ad una variazione dei contenuti. Quando si trattava di rettificare i contenuti, la maggioranza degli utenti preferiva invece creare una nuova pagina (eliminando quella non pi aggiornata, se lutente era colui che laveva concepita), pensando di evidenziare maggiormente la modifica apportata. Ho quindi dovuto cambiare lievemente il comportamento predefinito della portlet della Wiki (anche in tal caso ho usufruito dellambiente Ext per fare loverride del codice sorgente), in particolare ho considerato la parte relativa al social activity tracking della stessa. Esiste infatti un interprete delle varie attivit di una portlet (ogni portlet out of the box di Liferay possiede una classe interprete, la quale si pu specificare anche per quelle create autonomamente). In questo caso la classe che agisce da interprete delle attivit della Wiki WikiActivityInterpreter del package com.liferay.portlet.wiki.social. Il metodo che effettua leffettiva interpretazione delle possibili operazioni doInterpret, di cui si pu riportare qui sotto uno spezzone:
1 public class W i k i A c t i v i t y I n t e r p r e t e r extends BaseSocialActivityInterpreter { 2 protected S o c i a l A c t i v i t y F e e d E n t r y doInterpret ( SocialActivity activity , ThemeDisplay themeDisplay ) throws Exception { 3 String link = themeDisplay . getURLPortal () + themeDisplay . getPathMain () + " / wiki / find_page ? p ag e R es o u rc e P ri m K ey = " + activity . getClassPK () ; 4 int activityType = activity . getType () ;

68 di 113

6.3. FILTRAGGIO ATTIVIT DI MODIFICA PAGINE WIKI


5 6 7 8 9 10 11 12 13 14 15 16 } else if ( activityType == WikiActivityKeys . UPDATE_PAGE ) { titlePattern = " activity - wiki - update - page " ; return null ; } ... if ( Validator . isNotNull ( groupName ) ) { titlePattern += " - in " ; } ... String title = themeDisplay . translate ( titlePattern , titleArguments ) ; 17 18 19 20 } String body = StringPool . BLANK ; return new S o c i a l A c t i v i t y F e e d E n t r y ( link , title , body ) ; } ... String titlePattern = null ; if ( activityType == WikiActivityKeys . ADD_PAGE ) { titlePattern = " activity - wiki - add - page " ;

Linterprete, mediante il metodo sopracitato, effettua tutta una serie di operazioni per permettere di aggiungere unattivit della Wiki allactivity portlet. In primo luogo, viene determinato il link che identifica univocamente la certa pagina della Wiki (tra tutte le Wiki delle diverse comunit) dalla quale viene inviata la richiesta di interpretazione delle attivit che avvengono allinterno della stessa (riga 3). Dalloggetto di tipo SocialActivity, parametro dingresso al metodo che rappresenta lazione che lutente ha effettuato, viene poi estrapolato il tipo dellattivit (riga 4) che pu essere relativa alla creazione di una pagina (individuata dalla chiave ADD_PAGE, campo intero statico della classe WikiActivityKeys) o allaggiornamento di una gi esistente (il cui tipo coincide invece con lattributo UPDATE_PAGE). A seconda della tipologia di operazione, viene richiamato lopportuno pattern della descrizione sintetica dellattivit. La frasi pattern vengono definite nel file Language.properties che fa parte del codice del portale, e si possono cos elencare (in tal caso si riportano solamente quelle riguardanti la Wiki): activity-wiki-add-page-in={1} wrote a new wiki page, {2}, in {0}. ; activity-wiki-add-page={1} wrote a new wiki page, {2}. ; 69 di 113

CAPITOLO 6. STABILIZZAZIONE DELLAPPLICAZIONE WEB activity-wiki-update-page-in={1} updated a wiki page, {2}, in {0}. ; activity-wiki-update-page={1} updated a wiki page, {2}. . Come si pu notare, i due pattern per una stessa attivit differiscono tra di loro per laggiunta della stringa -in in fondo alla frase che identifica la descrizione avente anche il nome della comunit, se la portlet della Wiki allinterno di una comunit. Le frasi pattern vengono poi opportunamente riempite con il nome utente che ha fatto lattivit (nel segnaposto {1}), il titolo della pagina Wiki interessata (in {2}) e, se presente, con il nome della comunit in cui installata quella portlet Wiki (nel segnaposto {0}). I vari argomenti qui citati sono dati dal campo titleArguments appositamente costruito. Le frasi vengono anche tradotte nella lingua impostata nel portale (riga 16). Infine il metodo ritorna un oggetto di tipo SocialActivityFeedEntry (riga 18) che rappresenta lentry dellattivit costituita da link alla pagina, la sua descrizione sintetica e da un corpo che, tipicamente, lasciato vuoto. La modifica da me apportata ha riguardato semplicemente laggiunta dellistruzione return null; nella riga 11. Cos facendo, in corrispondenza di unattivit di modifica/modifica minore di una pagina Wiki, il metodo restituisce unactivity entry nulla che quindi non viene aggiunta e visualizzata nellactivity portlet.

Modifica del formato di scrittura predefinito delleditor Una piccola modifica effettuata, e strettamente correlata alluso della portlet della Wiki, ha riguardato il cambiamento del formato di scrittura predefinito delleditor usato per la creazione o laggiornamento di una pagina. Questultimo era infatti impostato di default al formato Creole, una sintassi nata grazie alla crescente insoddisfazione della Wiki community per il mancato utilizzo di un linguaggio standard. Tale sintassi prevede delle direttive particolari per settare gli stili del testo, per inserire dei collegamenti ipertestuali ed immagini allinterno della pagina. Proprio per questo, gli utenti si sono trovati in difficolt nel comprendere ed utilizzare tale formato. Ho dunque impostato come predefinito il formato HTML agendo sul file portal-ext.properties aggiungendo la seguente propriet (che fa loverride di quella di default presente in portal.properties):
wiki . formats . default = html

Il linguaggio di markup HTML risulta infatti essere di pi facile comprensione rispetto al Creole, permettendo allo stesso tempo una maggior personalizzazione del testo. 70 di 113

Capitolo 7
Sviluppo di nuove funzionalit
Tale capitolo si occuper di descrivere lo sviluppo di nuove features e la loro conseguente integrazione nel portale aziendale. Dopo aver infatti applicato una sorta di stabilizzazione dellapplicazione, correggendo gli errori pi evidenti che la caratterizzavano, sono passato alla realizzazione di diverse funzionalit, tutte con lobiettivo di incrementare la produttivit aziendale, rendendo possibili o comunque pi semplici e veloci varie operazioni per la fruizione, la ricerca e la condivisione di informazioni utili. I requisiti richiamati sono quelli riportati nel secondo punto dellelenco presente nella sezione 4.1.2. Anche in questo capitolo, come nel precedente, si indicheranno alcuni concetti teorici richiesti.

7.1

Sistema per la modifica dei documenti


[ambiente Plugins SDK ]

Una pesante limitazione di cui soffriva la document library era dovuta al fatto che non presentava una funzionalit di modifica dei documenti caricati in essa, o meglio, per aggiornare il contenuto di un documento era necessario eseguire lupload di un altro file dello stesso tipo. La portlet (integrata nellistanza Social Office spiegata nellultima parte della sezione 4.1) consentiva infatti di cambiare direttamente solamente il titolo e la descrizione di un documento e di impostare i vari tag associati ad esso. Lazienda, viste le evidenti restrizioni che offriva questo sistema, mi ha richiesto di rendere il tutto pi flessibile, facendo in modo che un utente, che possiede gli opportuni permessi, possa aggiornare un documento in modo semplice e veloce, senza dover eseguire ogni volta un nuovo upload. Il meccanismo non era quindi per niente agevole e in certe situazioni poteva introdurre ulteriori piccole complicazioni (ad esempio, si pensi solo al fatto di dover possedere una copia locale aggiornata del documento e, nel caso lutente non lavesse memorizzata in precedenza, doveva necessariamente scaricarla dalla document library). 71 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT Tutto ci rendeva particolarmente ostico laggiornamento di un documento, specialmente per quegli utenti che per diverse ragioni non usavano spesso questa funzionalit e che dunque non avevano molta dimestichezza con la gestione dei documenti caricati. Lazienda, essendo patner Microsoft, per i suoi dipendenti mette a disposizione macchine dotate di sistema operativo Microsoft dove tra le altre cose installata la suite Office che offre varie applicazioni (come Word, Excel e PowerPoint) per la modifica di diverse tipologie di documenti. Lazienda voleva pertanto automatizzare il meccanismo di apertura, modifica e conseguente salvataggio (con incremento di versione) di un documento allinterno delle document library presenti nelle varie comunit del portale, facendo uso anche delle applicazioni Office preinstallate. Per rendere possibile questo, ho considerato innanzitutto i molti strumenti messi a disposizione da Liferay e come questi potevano aiutare la piattaforma ad interfacciarsi con altri programmi esterni per la modifica dei documenti. Ho puntato su uno in particolare, ovvero il protocollo WebDAV, descritto in breve nel paragrafo sottostante. Il protocollo WebDAV Il protocollo Web-based Distributed Authoring and Versioning (WebDAV) un insieme di istruzioni basate su HTTP che facilitano la collaborazione tra gli utenti nellediting e nella gestione di file (documenti e non) memorizzati su server web remoti. In particolare consiste in un set di metodi, header e content-type che rendono possibili queste operazioni: la gestione delle propriet di risorse (creazione, rimozione e linterrogazione per lottenimento di informazioni quali lautore, la data di modifica, ecc.); la creazione, leliminazione e il listing di gruppi di risorse; la manipolazione dei namespace (cio la capacit di copiare e spostare pagine web allinterno del namespace del server web); il locking di risorse (collision avoidance). Tutte queste caratteristiche fanno s che il Web si possa considerare anche come un mezzo di lettura e scrittura, in quanto fornisce agli utenti un framework per creare, aggiornare e spostare documenti su un server. Il protocollo stato definito allinterno del documento di riferimento RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)[8] (che ha aggiornato la prima specifica RFC 2518 ). Prevede inoltre la possibilit di versionamento dei file, come specificato in RFC 3253: Versioning Extensions to WebDAV.

72 di 113

7.1. SISTEMA PER LA MODIFICA DEI DOCUMENTI Facendo quindi riferimento al protocollo appena citato e soprattutto tenendo bene in considerazione il fatto che le applicazioni del pacchetto Office possono aprire file da server WebDAV e salvarli poi nuovamente sul server senza doverli scaricare in locale, sono passato allideazione della soluzione al problema. Dal momento che ogni file presente nelle varie document library del portale associato ad un URL WebDAV, ho pensato di realizzare unapplet che consentiva ad un utente di aprire automaticamente un documento usufruendo del relativo programma Office. Essendo, come detto, una portlet integrata in Social Office, installato in ambiente Plugins SDK, mi sono concentrato su di esso per apportare le dovute modifiche. In particolare ho considerato il file edit_file_entry.jsp che serve in pratica per la visualizzazione della pagina di edit/view di un file presente nella document library. Cos facendo, ho preservato inoltre il paradigma MVC, in quanto in edit_file_entry.jsp si elabora la request e ho potuto occuparmi della gestione e memorizzazione di alcuni dati, mentre il livello di presentazione era garantito dalla pagina view.portal.jsp relativa alla portlet. Questultima infatti include le varie pagine e risorse costituenti la portlet assicurando la sua corretta visualizzazione a seconda delle azioni possibili effettuate su di essa. Come si vedr poi in dettaglio, nella pagina edit_file_entry.jsp sono effettuate le seguente operazioni: 1) si controlla se lutente loggato ha i permessi per la modifica del file; 2) si verifica se il file un documento modificabile a seconda della sua estensione; 3) se i due precedenti punti sono entrambi soddisfatti, si procede a visualizzare lapplet per la modifica del documento; 4) allapplet vengono passati due parametri (indirizzo WebDAV ed estensione del file) che servono per il suo funzionamento; 5) se lutente non possiede i permessi necessari, si mostra un opportuno messaggio informativo. Qui sotto si possono riportare degli spezzoni di codice che fanno s che venga fatto tutto ci. Man mano si descriveranno i passaggi, espandendo i punti sopracitati.
1 2 3 <% long companyId = C ompa nyT hr ea dL oc al . getCompanyId () ; long loggedUserId = PortalUtil . getUserId ( request ) ;

73 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT


4 Role admin_Role = R o l e L o c a l S e r v i c e U t i l . getRole ( companyId , RoleConstants . ADMINISTRATOR ) ; 5 Role cmty_admin_Role = R o l e L o c a l S e r v i c e U t i l . getRole ( companyId , RoleConstants . C O M M U N I T Y _ A D M I N I S T R A T O R ) ; 6 List < Role > loggedUserRoles = RoleServiceUtil . getUserRoles ( loggedUserId ) ; 7 List < Role > l o g g e d U s e r R e l a t e d R o l e s = RoleServiceUtil . get UserGr oupRol es ( loggedUserId , portletGroupId ) ; 8 9 boolean userCanModify = false ; if ( loggedUserRoles . contains ( admin_Role ) || l o g g e d U s e r R e l a t e d R o l e s . contains ( cmty_admin_Role ) ) { 10 11 12 } %> userCanModify = true ;

Innanzitutto, necessario dire che gli script JSP sono vere e proprie porzioni di codice inserite allinterno di pagine HTML che possono rappresentare dichiarazioni, espressioni ed altre direttive. Ad esempio, il codice Java va racchiuso allinterno dei tag <% %>, mentre per le dichiarazioni (sia di variabili che di metodi) la sintassi <%! dichiarazione %>. Per le espressioni la sintassi invece <%= espressione %>. In questa prima parte si sono valutati i permessi dellutente autenticato che ha richiesto la pagina in questione (il suo identificativo stato ottenuto tramite il metodo statico getUserId della classe PortalUtil, in riga 3). Si sono poi estrapolati i ruoli utente che interessano allo scopo (righe 4 e 5), in quanto ho fatto in modo che gli utenti abilitati alla modifica dei documenti debbano avere un ruolo di amministratore del portale (ADMINISTRATOR) o di amministratore della comunit (COMMUNITY_ADMINISTRATOR) nella quale presente il documento. Dal momento che un utente pu possedere pi ruoli, si sono quindi ricavati i vari ruoli dellutente tramite il metodo statico getUserRoles della classe RoleServiceUtil (riga 6) e quelli a lui correlati per la comunit in cui installata quella document library. Questo grazie invece al metodo statico getUserGroupRoles della stessa classe (riga 7). Si definita una variabile booleana, denominata userCanModify ed impostata inizialmente a false, la quale, se lutente portal administrator oppure amministratore di quella comunit, viene settata al valore true per indicare appunto che pu aggiornare i file.

74 di 113

7.1. SISTEMA PER LA MODIFICA DEI DOCUMENTI


13 14 <% DLFileEntry fileEntry = ( DLFileEntry ) request . getAttribute ( WebKeys . D O C U M E N T _ L I B R A R Y _ F I L E _ E N T R Y ) ; 15 16 17 18 19 long fileEntryUserId = null ; if ( fileEntry != null ) { fileEntryUserId = fileEntry . getUserId () ; } ... if ( userCanModify || ( fileEntryUserId != null && fileEntryUserId == loggedUserId ) ) { 20 21 StringBuffer sb = new StringBuffer () ; /* tramite sb si forma la parte di indirizzo con nome file e relativa cartella di appartenenza */ 22 String webdavUrl = themeDisplay . getPortalURL () + " / tunnel - web / secure / webdav / " + company . getWebId () + group . getFriendlyURL () + " / document_library " + sb . toString () ; 23 24 25 26 27 28 String arraySplittedUrl [] = webdavUrl . split ( " \\. " ) ; String docExt = arraySplittedUrl [ arraySplittedUrl . length -1]; %> < liferay - ui : input - resource url = <%= webdavUrl % > / > <% if ( docExt . equals ( " doc " ) || docExt . equals ( " docx " ) || docExt . equals ( " ppt " ) || docExt . equals ( " pptx " ) || docExt . equals ( " xls " ) || docExt . equals ( " xlsx " ) || docExt . equals ( " csv " ) || docExt . equals ( " txt " ) || docExt . equals ( " rtf " ) || docExt . equals ( " odt " ) || docExt . equals ( " ods " ) || docExt . equals ( " odp ")) { 29 30 31 %> < liferay - ui : message key = " open - external - app " / > ... /* inglobamento applet */ ...

41 42 43 44

<% }... } else {

75 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT


45 46 47 } %> /* l utente non possiede i permessi per la modifica */

Dal parametro della richiesta si ottenuto, tra le altre cose, loggetto di tipo DLFileEntry che rappresenta lentry del file relativo alla pagina (riga 14). Dopodich si ricavato lidentificativo dellutente che lo ha inserito (riga 17). Se lutente autenticato ha un ruolo adeguato (almeno uno dei due citati in precedenza) o se ha caricato il documento in questione (test effettuato come si vede in riga 19), dunque autorizzato a poterlo modificare. In tal caso, si costruisce (riga 22) e visualizza (riga 26) lindirizzo WebDAV della risorsa. Questultimo ha una forma tale per cui nellultima parte identifica la cartella di appartenenza del file e poi il nome dello stesso seguito dalla relativa estensione. In particolare, da questo URL viene estratta la stringa che rappresenta lestensione del file (riga 24) che servir per dire se esso un documento modificabile o meno. Venendo incontro anche alle esigenze dellazienda, si arrivati alla conclusione che i documenti modificabili supportati dallapplet avevano le seguenti estensioni: doc, docx, txt, dot, odt (con Microsoft Word); xls, xlsx, csv, ods (con Microsoft Excel); ppt, pptx, odp (con Microsoft PowerPoint). Se quindi il file presentava una di queste estensioni, veniva visualizzata lapplet, alla quale venivano passati due parametri. Il codice dellapplet si integrato nella pagina come illustrato qui sotto.
32 < jsp:plugin type = " applet " code = " Op en Do cu me ntA pp le t . class " archive = " / html / applet / s i g n e d O p e n D o c u m e n t A p p l e t . jar " width = " 125 " height = " 30 " > 33 34 35 36 37 38 39 40 < jsp:params > < jsp:param name = " webdavUrl " value = " <%= webdavUrl % > " / > < jsp:param name = " docExt " value = " <%= docExt % > " / > </ jsp:params > < jsp:fallback > <p > Impossibile caricare l applet . </p > </ jsp:fallback > </ jsp:plugin >

76 di 113

7.1. SISTEMA PER LA MODIFICA DEI DOCUMENTI Come si evince dal precedente listato, il codice dellapplet viene inglobato grazie al tag <jsp:plugin>. Questultimo fa s che lapplet sia fruibile dal browser del client, utilizzando il plugin Java integrato nel browser. In tal caso, con gli attributi del tag si definito il tipo di plugin (applet appunto), il nome della classe Java che lapplet eseguir per funzionare, larchivio jar con precaricata la classe (in genere questo incrementa la performance dellapplet) e la larghezza e laltezza dellapplet. Mediante i tag <jsp:params> si sono invece specificati i parametri con i relativi valori da passare allapplet. In questa situazione, si sono passati due parametri, ossia lestensione e lindirizzo WebDAV del file, utili a determinare con quale applicazione Office aprirlo. Infine, con <jsp:fallback> si inserito un messaggio di testo da mostrare nel caso in cui il plugin non parta.

7.1.1

Realizzazione dellapplet

Per lo sviluppo dellapplet ho considerato innanzitutto la classe Applet del package java.applet presente nelle API Java. Tale classe deve essere la superclasse di unapplet, in quanto fornisce degli appositi metodi per gestire il suo ciclo di vita, facendo da interfaccia tra essa e lambiente di esecuzione. I metodi pi significativi, chiamati automaticamente dal browser, sono qui elencati: void init(), tipicamente utilizzato per inizializzare lapplet, invocato appena essa viene completamente caricata nel sistema; void start(), chiamato quando il sistema manda in esecuzione lapplet, lo informa di tale avvenimento; void stop(), chiamato dal browser per informare che lapplet ha fermato la sua esecuzione (ad esempio quando la finestra che la contiene non pi in primo piano oppure appena prima che lapplet venga distrutta); void destroy(), invocato quando lapplet viene distrutta. Unapplet presenta qualche differenza rispetto alle normali applicazioni. Non presenta infatti alcun main ed una classe, chiamata come il file che la contiene, che come detto estende la classe Applet. In tal caso, lapplet stata denominata OpenDocumentApplet, appunto perch ha il compito di aprire automaticamente un determinato documento della document library. Di seguito si riporta una parte di codice della suddetta classe.
1 public class O pen Do cu me nt Ap pl et extends Applet implements ActionListener { 2 3 Button launchButton ; String url , docExt , appCommand ;

77 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT


4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 } } } } catch ( Exception e ) { e . printStackTrace () ; } public void actionPerformed ( ActionEvent evt ) { } } else if ( docExt . equals ( " ppt " ) || ... ) { appCommand = " powerpnt " ; } else if ( docExt . equals ( " xls " ) || ... ) { appCommand = " excel " ; public void init () { setLayout ( new FlowLayout () ) ; launchButton = new Button ( " Modifica documento " ) ; add ( launchButton ) ; launchButton . a ddActi onList ener ( this ) ; url = this . getParameter ( " webdavUrl " ) ; url = url . replaceAll ( " " ," %20 " ) ; docExt = this . getParameter ( " docExt " ) ; if ( docExt . equals ( " doc " ) || ... ) { appCommand = " winword " ;

String cmd = " cmd . exe / c start " + appCommand + " " + url ; try { Process p = Runtime . getRuntime () . exec ( cmd ) ;

Come si pu osservare, nella classe OpenDocumentApplet ho fatto loverride del metodo init della superclasse, ridefinendolo in maniera tale da inizializzare lapplet impostando, oltre che una semplice GUI costituita solamente da un bottone, anche il comando da eseguire nella macchina client per aprire il documento con la giusta applicazione Office. Infatti, dopo aver recuperato i due parametri dellURL di WebDAV del file e della sua estensione (rispettivamente in riga 9 e 11), si valutata questultima e a seconda dei casi si settata opportunamente 78 di 113

7.1. SISTEMA PER LA MODIFICA DEI DOCUMENTI la stringa appCommand che rappresenta il comando per eseguire lapplicazione Office (winword per Word, excel per Excel e powerpnt per PowerPoint). Come detto, si implementata anche linterfaccia grafica dellapplet utilizzando una programmazione guidata dagli eventi (event-driven). In questapplicazione esiste infatti un controllo implicito che si occupa di rilevare il click sul bottone e di delegare la gestione di tale evento alle giuste componenti software. Come libreria grafica si scelta AWT (Abstract Window Toolkit) del package java.awt, che delega la creazione e la gestione delle componenti dellinterfaccia alle librerie grafiche della piattaforma sottostante. Laspetto dipende quindi dal sistema operativo sottostante. La sorgente dellevento il bottone che permette di aprire il file, definito dalloggetto launchButton di tipo Button. La gestione dellevento viene delegata ad un oggetto che implementa linterfaccia Listener. dunque questo loggetto che contiene il codice che indica come lapplicazione deve reagire allevento. Linterfaccia Listener a capo di una gerarchia di interfacce, ognuna specifica per un particolare tipo di evento. In particolare linterfaccia ActionListener (implementata dalla classe) rappresenta il tipo di gestore di un evento di tipo ActionEvent, che definisce come in tale situazione la pressione di un bottone. In questo caso lapplet ingloba sia la sorgente dellevento che la sua gestione. Per realizzare effettivamente il gestore di un evento bisogna quindi implementare uninterfaccia del tipo corretto, dando una definizione a tutti i suoi metodi. In tal caso, il codice da eseguire in corrispondenza della pressione del bottone Modifica documento lho inserito allinterno del metodo actionPerformed dellinterfaccia ActionListener. Innanzitutto ho costruito il comando completo da dare in pasto poi al prompt di Windows. Il modo pi semplice di far ci quello di usare il comando start, integrato nellinterprete cmd.exe, e che serve appunto per lanciare una determinata applicazione installata nel sistema. stato necessario quindi invocare start attraverso linterprete e questo stato fatto mediante il flag /c. Lapplicazione Office stata lanciata aprendo direttamente lURL di WebDAV del documento. Per eseguire il comando nella macchina client stato utilizzato il metodo Runtime.exec. Ogni applicazione Java possiede infatti una singola istanza della classe Runtime che permette allapplicazione di interfacciarsi con lambiente sottostante su cui essa esegue. Allistanza corrente, ottenuta attraverso il metodo getRuntime, ho dunque applicato il metodo exec che esegue il comando per lapertura del documento in un processo separato. Nel caso in cui nella macchina client non sia installata lapplicazione Office richiesta viene mostrato a schermo un opportuno errore. Siccome lapplet va ad accedere al sistema in locale, eseguendo un programma nel client, per ragioni di sicurezza ho dovuto necessariamente firmare digitalmente il file JAR creato. Ho generato quindi un certificato generico auto-firmato a costo zero, seguen79 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT do quanto scritto nella guida disponibile allindirizzo http://java.sun.com/ developer/onlineTraining/Programming/JDCBook/signed.html. Lapplet integrata nella pagina di edit/view di un documento nella document library si pu vedere in figura 7.1. Come detto in precedenza, lapplet costituita dal solo bottone di modifica documento ed stata inserita sotto larea dedicata allindirizzo di WebDAV del file.Per integrarla maggiormente nella struttura della pagina, ho aggiunto

Figura 7.1: Applet per la modifica dei documenti. due elementi di abbellimento accanto ad essa. Alla sinistra del bottone ho inserito unopportuna etichetta che seguiva la struttura della pagina. La label stata inclusa grazie ad un particolare tag per la user interface di Liferay, ossia <liferay-ui:message>. In particolare, con il tag <liferay-ui:message key=open-external-app /> si visualizzata una stringa che fa riferimento ad una chiave definita nel file Language-ext.properties in questo modo:
open - external - app = Modifica documento

Alla destra del bottone, invece, ho posto unimmagine di help cliccabile che, cliccata, mostra una finestra di aiuto che riporta alcune informazioni sul pulsante di Modifica documento, visibile in figura 7.2. Questo help importante anche perch ho menzionato come risolvere un fastidioso bug che avveniva utilizzando Office 2007 in ambiente Windows Vista/7.

Figura 7.2: Finestra informativa dellapplet. Laggiornamento proposto corregge diverse problematiche (apportando anche dei miglioramenti legati alla sicurezza) che si verificano quando si usa il componente Web Folders dalla macchina client per connettersi ad un server che 80 di 113

7.1. SISTEMA PER LA MODIFICA DEI DOCUMENTI supporta il protocollo WebDAV. Per rendere pi gradevole la finestra di dialogo ho usato un opportuno plugin di jQuery, chiamato jQuery Alert Dialogs. Nel momento in cui un utente clicca sul bottone di modifica documento, viene aperta la corretta applicazione Office installata nella macchina client. Per effettuare le modifiche volute al documento che sta aprendo, lutente deve prima autenticarsi con le stesse credenziali (username e password) che immette per il login al portale. La finestra che richiede le due credenziali si pu osservare nella figura sottostante.

Figura 7.3: Richiesta delle credenziali per la modifica di un documento.

Soluzione alternativa Per finire, si pu riportare qui di seguito una soluzione alternativa ma al contempo un po pi restrittiva rispetto allutilizzo dellapplet realizzata per la modifica dei documenti. Come descritto in precedenza, lapplet automatizza una serie di operazioni che, altrimenti, dovrebbero essere fatte a mano dallutente. Questultimo infatti dovrebbe copiare lURL di WebDAV del documento dalla relativa pagina del portale ed aprirlo con la giusta applicazione Office. Un altro modo di velocizzare il tutto e, quindi, di implementare lin-place editing dei documenti, consiste nel creare un link che, cliccato, crea un oggetto ActiveXObject tramite JavaScript. Tale oggetto fornisce uninterfaccia ad un oggetto di automazione ed definito in questo modo:
newObj = new ActiveXObject ( servername . typename [ , location ])

I campi obbligatori sono servername, cio il nome dellapplicazione che fornisce loggetto e typename che il tipo o la classe delloggetto da creare. Un campo opzionale invece location, ovvero il nome del server di rete in cui verr 81 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT creato loggetto. Generalmente, un server di automazione fornisce almeno un tipo di oggetto. Un programma di elaborazione di testi, ad esempio, pu fornire un oggetto applicazione, un oggetto documento e un oggetto barra degli strumenti. In questo caso, nel codice riportato di seguito si pu osservare come si possa avviare la corretta applicazione Office a seconda dellindirizzo di WebDAV passato, chiamando semplicemente il costruttore delloggetto ActiveXObject a cui viene applicato il metodo EditDocument:
<a href = " # " onclick = " new ActiveXObject ( SharePoint . OpenDocuments .1 ) . EditDocument ( <%= webdavUrl % > ) ; " > Modifica documento </ a >

Tale soluzione risulta quindi essere di pi facile implementazione, ma non molto flessibile in quanto funziona solamente con Internet Explorer. Questa una grave limitazione, poich gran parte del personale aziendale non utilizza IE come browser. Per via di questa restrizione ho scelto dunque di sviluppare lapplet.

7.2

Visualizzazione di un documento
[ambiente Plugins SDK ]

Un altro requisito riguardava la visualizzazione di un documento integrata direttamente nella relativa pagina. Il modo pi semplice di soddisfarlo si rivelato da subito essere quello che prevedeva luso del visualizzatore Google Docs Viewer. Questultimo ha molti vantaggi, tra i quali i pi significativi sono: si integra facilmente nel browser e quindi permette di visualizzare rapidamente i documenti online senza uscire dallo stesso; supporta pi di 15 diversi tipi di file, tra cui i pi comuni PDF, i documenti di Microsoft Word (.doc e .docx), Excel (.xls e .xlsx), PowerPoint (.ppt e .pptx), le immagini vettoriali SVG, gli archivi (.zip e .rar) e molti altri; fornisce varie scorciatoie da tastiera per velocizzare la navigazione di un documento; gratuito e non richiede un account di posta Gmail per il suo utilizzo. Dal momento che lazienda utilizza la document library non solo per conservare documenti testuali, ma anche per altri tipi di file, quali immagini ed archivi (la libreria consente infatti di creare delle cartelle utili a separare i diversi contenuti), la scelta risultata ragionevole. Il visualizzatore stato inglobato nella pagina di edit/view del file e, quindi, come in precedenza, ho effettuato le dovute modifiche in edit_file_entry.jsp. 82 di 113

7.2. VISUALIZZAZIONE DI UN DOCUMENTO In origine, in fondo alla pagina erano presenti due tab, una (avente etichetta Commenti) per visualizzare i commenti al file inseriti dagli utenti e unaltra (identificata dalla label Cronologia delle Versioni) per consultare il suo versionamento, con possibilit di fare anche il download di una certa versione del file. Ho aggiunto una terza tab che serviva appunto a contenere il viewer. Per poter visualizzare correttamente i file presenti nella document library ho dovuto applicare alcuni cambiamenti riguardanti la loro memorizzazione nel file system dopo averne fatto lupload sul portale. Memorizzazione dei file presenti nella document library Per la gestione dei file caricati nel portale, Liferay li memorizza effettivamente in /data/document_library. Allinterno presente una cartella denominata con lidentificativo companyId (id che individua lunica istanza del portale). Allinterno di questultima cartella sono presenti poi tutte le varie cartelle create nelle document library di tutte le comunit del portale. Ogni cartella chiamata con il proprio identificativo (folderId). Dentro ognuna di queste cartelle sono presenti tante directory quanti sono i file caricati allinterno di quella determinata cartella del portale. Ogni cartella che identifica un file denominata DLFE-n.ext dove n una chiave auto-generata dal portale ed ext lestensione del file che viene caricato. Infine, dentro alla directory che identifica il documento ci sono tanti file quante sono le sue versioni. Tali file sono denominati 1.x dove x il numero della versione. Questi tipi di file non risultato visualizzabili direttamente su Google Docs Viewer per due motivi: 1. presentano estensioni ovviamente non supportate; 2. non sono accedibili come indirizzo web, in quanto il percorso dei file non mappato. Quindi, per la visualizzazione del documento (lultima sua versione, in quanto il portale per tutte le altre versioni consente solamente il download) tramite Google Docs Viewer ho dovuto soddisfare i due precedenti punti.

1. Per risolvere la problematica descritta nel primo punto, necessario salvare il file quando ne viene fatto lupload e aggiornarlo ogni qualvolta si esegue una modifica del suo contenuto (tramite lapplet). A questo proposito si deciso di salvare i documenti visualizzabili in unaltra cartella rispetto a /data/document_library/ in quanto questa presentava 83 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT tante sottocartelle quanti erano i documenti. In questo caso, tenendo solamente lultima versione del documento, quelle sottocartelle non sono pi necessarie. Si voluto, quindi, alleggerire la gerarchia delle cartelle anche per una pi facile manutenzione. La nuova gerarchia dunque formata dalle varie directory di tutte le document library di tutte le comunit e poi al loro interno i documenti con le opportune estensioni. Inoltre, si fatto in modo che quando viene creata unentry cartella nelle document library del portale, questa non sia creata subito anche nella corrispondente cartella per i documenti da visualizzare, ma solamente alla prima aggiunta di un file al suo interno. Per eseguire le varie operazioni sul documento da visualizzare si sono appositamente modificati vari file relativi alla portlet della document library. In particolare, per le operazioni legate allentry del file si modificata la relativa action definita dalla classe EditFileEntryAction (essendo una action di una portlet, la classe estende PortletAction che, a sua volta, deriva dalla classe Action di Struts). In questultima mi sono interessato di due metodi: updateFileEntry, per laggiunta o laggiornamento (modifica nome e/o descrizione, spostamento) di un file; deleteFileEntry, per leliminazione di un file. Mediante il metodo updateFileEntry, dopo aver ottenuto dalla richiesta di upload (in questo caso si parla infatti di inserimento e aggiornamento di un file tramite un form di upload) il file e i suoi attributi accessori (come ad esempio titolo, descrizione, id della cartella, id della nuova cartella se si vuole spostarlo, ecc.), sono passato a salvarlo effettivamente su disco. Innanzitutto, ho creato (se non gi presenti) le cartelle necessarie a conservare il file. A tal proposito vengono create due cartelle, una generale (che consente di contenere tutte le varie cartelle della library, il cui path stato impostato su un campo statico stringa della classe) e una per la specifica directory dellentry file (identificata dallid della folder). Dopodich ci sono due casi da tenere in considerazione. Il primo linserimento di un nuovo file. Il metodo fa tutta una serie di controlli per vedere se lutente possiede i permessi necessari ad effettuare loperazione e per verificare se nella stessa cartella della library esiste un altro documento con lo stesso nome. Se a questo punto il metodo non lancia eccezioni, il file viene aggiunto a quella specifica cartella selezionata e con gli attributi (titolo, descrizione, ecc.) scelti dallutente. Ho quindi proceduto al salvataggio del file con la sua corretta estensione, copiando il file caricato nella cartella creata nel file system ed identificata da un valore intero (folderId). Il secondo caso riguarda laggiornamento di un file. In questa circostanza vengono considerati gli identificatori della cartella corrente e della nuova 84 di 113

7.2. VISUALIZZAZIONE DI UN DOCUMENTO (newFolderId). Se il parametro newFolderId recuperato dal form di upload diverso da 0, significa che lutente sta spostando il file dalla cartella folderId alla cartella newFolderId della document library. Tale spostamento pu riguardare lo stesso file (se non viene caricato alcun file, ma semplicemente si aggiorna lentry esistente cambiando, oltre alla cartella, anche il nome e/o la descrizione del documento) oppure un altro caricato per aggiornare quello precedente facendolo avanzare di versione. In entrambe le situazioni ho provveduto a copiare il file dalla vecchia alla nuova cartella (creata se non esistente) del file system, cancellando il file dalla vecchia cartella. Se, invece, newFolderId uguale a 0, la modifica del documento avviene nella stessa cartella. Il file caricato viene quindi copiato nel disco sovrascrivendo il precedente file. Rispetto a quando si cambia cartella, in tal caso, se non viene caricato alcun file, ma semplicemente viene aggiornata lentry esistente cambiando il nome e/o la descrizione, non ha senso sovrascrivere il file nella stessa cartella in quanto ha un contenuto identico al precedente. Il metodo deleteFileEntry ha il compito di eliminare lentry del file quando lutente ne ha la necessit. Ho quindi eliminato il file anche dalla cartella dei documenti. Le operazioni legate ad unentry cartella presente nella document library sono gestite dallaction class EditFolderAction della quale mi sono servito di uno dei suoi metodi: deleteFolder, per leliminazione di una cartella. Tramite questo metodo viene eliminata unentry cartella (cancellando tutti i file al suo interno) dal portale e, in corrispondenza di questa operazione, ho implementato anche leliminazione della corrispondente directory (denominata con lid della cartella nella library) allinterno della cartella dei documenti nel file system. Nel caso venga aggiunta una cartella nella document library, linserimento non viene rispecchiato subito anche nel disco, ma al primo inserimento di un documento allinterno della stessa. Quando, invece, unentry cartella viene aggiornata, non serve fare nessuna modifica in quanto laggiornamento (spostamento, modifica nome e/o descrizione) non fa cambiare lid associato ad essa (e quindi il nome alla cartella). Infine, per operazioni legate al contenuto del file, modificabile tramite lapplet creata, ho considerato la classe DLWebDAVStorageImpl apportando alcune modifiche a questo metodo: putResource, per aggiornare la risorsa nel server dopo averla modificata utilizzando il protocollo WebDAV. Il metodo putResource si occupa di aggiornare un file nella document library, dopo averlo modificato via WebDAV. Il metodo riceve in ingresso un parametro 85 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT che rappresenta la WebDAV request e da questa estrapola la richiesta HTTP associata. Tramite poi questultima ricava gli attributi legati al file che si modifica (il nome, la cartella di appartenenza, ecc.). Per aggiornare il file anche nella cartella dei documenti creata nel file system, ho salvato lo stream di input della richiesta HTTP (che era il file aggiornato) in un array di byte, nel seguente modo:
byte [] bytesArray = FileUtil . getBytes ( request . getInputStream () ) ;

In seguito, ho scritto il file nella specifica cartella, aggiornando il precedente, usando listruzione:
FileUtil . write ( new File ( docsRootPath + parentFolderId + " / " + name ) , bytesArray ) ;

Come si nota, name e parentFolderId sono rispettivamente il nome del documento e lid della cartella di appartenenza nella library. docsRootPath invece il percorso della cartella principale dei documenti visualizzabili, definito, come detto, come campo statico nelle varie classi viste. Tutte queste modifiche alle classi citate in precedenza servono quindi a mantenere consistente il file visualizzato tramite Google Docs Viewer con la versione pi recente dello stesso caricato nella document library. Nel caso di aggiornamenti del documento, infatti, questo sar visualizzato sempre correttamente.

2. Per accedere ai documenti da visualizzare come indirizzo web stato necessario mappare la cartella definita dal precedente campo docsRootPath. Per far ci allinterno della cartella tomcat/conf/Catalina/localhost/ si creato il file documenti.xml configurato come segue: <Context path=/documenti docBase=docsRootPath /> dove al posto di docsRootPath si deve mettere il percorso della cartella voluto. La cartella dei documenti visualizzabili si trova dunque allindirizzo: http://duezero.euris.it/documenti/

Dopo aver applicato queste necessarie correzioni, ho potuto integrare il visualizzatore allinterno della pagina, in una terza tab, come citato in precedenza. LURL di un certo documento stato cos recuperato allinterno della pagina:
String docUrl = themeDisplay . getPortalURL () + " / documenti / " + fileEntry . getFolderId () + " / " + fileEntry . getName () ;

86 di 113

7.3. SVILUPPO PORTLET Si noti come si utilizzi il path /documenti appositamente creato. In particolare, dalloggetto dellentry del file (fileEntry) si ottiene il suo nome (DLFE-n.ext, dove n un numero intero ed ext lestensione) e la cartella padre (tramite il metodo getFolderId). Le directory dei documenti visualizzabili rispecchiano infatti quelle della document library, essendo denominate con il loro identificativo e i nomi dei file al loro interno rispettano lo stesso pattern. Ho poi seguito la procedura per la creazione di URL personalizzati da inserire nel visualizzatore, disponibile allindirizzo https://docs.google.com/viewer. In primo luogo ho codificato la stringa precedente come URL, usando la codifica UTF-8:
String urlEncoded = URLEncoder . encode ( docUrl , " UTF -8 " ) ;

Ho quindi usato il tag HTML iframe per la visualizzazione embedded del documento:
< iframe title = " Document Viewer " id = " viewerIframe " src = " <%= " http :// docs . google . com / viewer ? url = " + urlEncoded + " & embedded = true " % > " height = " 600 " width = " 800 " / >

Si pu osservare come venga usato il parametro embedded che impostato a true facendo in modo tale che il visualizzatore sfrutti appunto uninterfaccia in modalit incorporata. Nellimmagine sottostante si pu vedere uno screenshot del viewer incorporato nella pagina (che in tal caso visualizza un file di estensione .pptx).

Figura 7.4: Viewer incorporato nella pagina.

87 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT

7.3

Sviluppo portlet
[ambiente Extension]

Nellultima parte dellattivit di stage ho realizzato diverse portlet, alcune delle quali servono a semplificare e velocizzare lutilizzo del portale, mentre altre implementano delle funzionalit aggiuntive incrementando cos la collaborazione tra il personale aziendale. Si pu fare riferimento alla sezione 4.1.2 per lelenco completo delle funzioni implementate. Per il loro sviluppo ho scelto di utilizzare lambiente Ext essenzialmente per due motivi: possibilit di importare anche le classi dalle librerie di Portal-Impl, che definiscono il core di Liferay (cosa non possibile nellambiente Plugins SDK a meno di non usare gli hooks); possibilit di eseguire il fast-deploy della componente ext-web usata per lo sviluppo della vista della portlet. Come accennato in pi occasioni nella stesura del documento, le portlet out of the box di Liferay sono sviluppate utilizzando il framework Struts. Framework elegante ed estensibile per la creazione di web application Java-based che, come visto, usa il pattern architetturale MVC. In particolare, in questo caso ho centrato lattenzione soprattutto nella parte view e nel definire la struttura della portlet, sviluppando delle JSP portlet, come descritto nel libro Liferay Portal 5.2 Systems Development [5]. Queste sono pi semplici rispetto alle Struts portlet poich, dopo aver fissato il modello dei dati, le portlet si costruiscono fondamentalmente attraverso delle pagine JSP. Come detto, queste ultime non solo altro che file HTML con tag speciali che contengono codice Java per fornire del contenuto dinamico alla pagina. Lambiente Ext risultato molto comodo a questo scopo, in quanto fornisce il target deploy-fast di Ant utile nelle situazioni in cui ci sono solamente file JSP e JavaScript da aggiornare nella cartella /ext/ext-web/docroot/html. Non occorre infatti riavviare lapplication server, poich basta cliccare prima sul precedente target Ant che esegue un deploy veloce della componente web, e successivamente fare il reload della pagina corrente nel browser, aggiornandola cos immediatamente. Inoltre, anche una JSP portlet costituita dalle componenti tipiche del pattern MVC: Model: oggetti Java messi a disposizione come request attributes; View: un template (ad esempio view.jsp) per la rappresentazione dei dati del modello; Controller: definisce laction della portlet. 88 di 113

7.3. SVILUPPO PORTLET La vista quindi fornisce un template JSP che avr il compito di generare il contenuto della portlet estrapolando i dati dinamici dagli attributi della render request. Il modello dei dati di una determinata portlet stato definito realizzando per ciascuna una classe Java che deriva dalla classe JSPPortlet del package com.liferay.util.bridges.jsp delle API di Liferay. Questa classe deriva dalla classe LiferayPortlet di com.liferay.portal.kernel.portlet che specifica appunto una portlet del portale. Tale classe, a sua volta, sottoclasse di GenericPortlet (si veda la sezione 2.4) dalla quale si importano le funzionalit di base della portlet. GenericPortlet una classe astratta che fornisce unimplementazione di default dellinterfaccia Portlet. Una sua sottoclasse dovrebbe dunque fare loverride di almeno uno dei suoi metodi, tipicamente uno dei seguenti: processAction, per gestire le action request; doView, per gestire le render request quando il portlet mode nello stato VIEW; doEdit, per le richieste di render quando lo stato EDIT; doHelp, per le render request quando lo stato HELP; init e destroy per gestire delle risorse tenute per il ciclo di vita della portlet. In questo caso, ho ridefinito solamente il metodo doView (gli altri stati vengono realizzati con impostazioni predefinite) che gestisce la vista della portlet. In questo metodo ho inserito il codice di business per creare opportunamente gli oggetti del modello dei dati da visualizzare in seguito nella vista. La classe che definisce il modello dei dati quindi cos strutturata:
1 2 3 public class MyPortlet extends JSPPortlet { /* ... campi e metodi utili a creare il modello dei dati ... */ public void doView ( RenderRequest renderRequest , RenderResponse renderResponse ) throws IOException , PortletException { 4 5 6 7 8 9 10 } } ... renderRequest . setAttribute ( " attName1 " , attValue1 ) ; renderRequest . setAttribute ( " attName2 " , attValue2 ) ; ... super . doView ( renderRequest , renderResponse ) ;

89 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT Come si pu osservare, dopo aver importato tutte le classi necessarie (dalle API di Java e Liferay), nella classe ho inserito dei campi dati e dei metodi per creare il modello dei dati. Con i diversi metodi ho quindi manipolato dei dati fino ad ottenere tutti gli oggetti necessari alla costituzione del Model che incapsula lo stato della portlet. In seguito, nel metodo doView ho creato gli oggetti che mi servivano e li ho esposti alla View perch essa potesse accederli. Per fare ci, ho inserito gli oggetti nella render request (vengono visti quindi come parametri) attribuendo loro un nome. Infine, ho delegato il rendering della portlet al metodo della superclasse. proprio attraverso loggetto di tipo RenderRequest che i valori impostati vengono passati alla vista della portlet, cio alla relativa pagina view.jsp. Per via di questo fatto, nella pagina necessario importare listanza RenderRequest (ed anche altri oggetti utili) aggiungendo il tag <portlet:defineObjects /> allinizio del file JSP. Dopo aver fatto questo, si pu ottenere un qualsiasi attributo dalla richiesta di render tramite il suo nome. A questo scopo viene utilizzato il metodo getAttribute il quale ritorna un oggetto generico di tipo Object e dunque per ottenere il tipo corretto del parametro necessario castare il valore ritornato dal metodo. Di seguito si riporta un esempio (nel caso lattributo sia una stringa):
< portlet : defineObjects / > <% String str = ( String ) renderRequest . getAttribute ( " attName2 " ) ; %>

I passi per creare una JSP Portlet sono i seguenti: 1) definizione della portlet (con attributi JSR-286 ) in portlet-ext.xml; 2) registrazione della portlet nel portale in liferay-portlet-ext.xml; 3) definizione del titolo della portlet per una sua identificazione, mappandolo su un valore specificato in Language-ext.properties; 4) aggiunta della portlet in una categoria agendo su liferay-display.xml; 5) creazione delle pagine JSP necessarie: view.jsp e init.jsp. Si descriveranno ora i vari passi, spigandoli da un punto di vista generale per tutte le portlet. Lultimo punto citato verr per esposto specificatamente per ciascuna portlet in quanto definisce limplementazione della stessa. Il primo punto citato riguarda la definizione della portlet e per questo usato il descrittore portlet-ext.xml nella cartella ext/ext-web/docroot/WEB-INF/. Un esempio di specifica di una portlet si pu vedere qui di seguito: 90 di 113

7.3. SVILUPPO PORTLET


< portlet > < portlet - name > EXT_2 </ portlet - name > < display - name > My JSPPortlet </ display - name > < portlet - class > com . ext . customportlet . MyPortlet </ portlet - class > < init - param > < name > view - jsp </ name > < value > html / portlet / ext / myportlet / view . jsp </ value > </ init - param > < expiration - cache > 300 </ expiration - cache > < supports > < mime - type > text / html </ mime - type > </ supports > < portlet - info > < title > My JSP Portlet </ title > </ portlet - info > < security - role - ref > < role - name > Power User </ role - name > </ security - role - ref > < security - role - ref > < role - name > User </ role - name > </ security - role - ref > </ portlet >

Si noti che le portlet sono univocamente identificate dal loro portlet-name (allinterno del portale questo anche riferito come lid della portlet). Questo attributo contiene quindi il nome canonico della portlet che deve essere unico allinterno dellapplicazione. Il parametro portlet-class permette invece di riferirsi alla classe che definisce il modello dei dati della portlet, ad esempio com.ext.customportlet.MyPortlet. Lattributo display-name contiene il nome breve che viene visualizzato e non necessita di essere univoco. Lelemento init-param racchiude una coppia nome-valore come parametro di inizializzazione della portlet e permette di specificare la pagina che essa dovr caricare (che specifica la vista). Gli altri attributi listati riguardano la definizione delle informazioni della portlet (portlet-info), la durata della cache in secondi (expiration-cache, la specifica definisce infatti un meccanismo di cache temporanea che in base alla terminologia ufficiale prende il nome di expiration-based caching mechanism), il supporto per specifici tipi di contenuto (supports) e la dichiarazione di regole di sicurezza (security-role-ref). In particolare, lattributo role-name specifica quali ruoli utente hanno accesso alla portlet (un Power User pu personalizzare il portale, mentre uno User no). Per registrare la portlet al portale si agito sul file liferay-portlet-ext.xml presente sempre dentro la precedente cartella, dove si inserito un elemento 91 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT portlet allinterno del tag liferay-portlet-app, come mostrato di seguito (qui, come per i punti successivi, si fa riferimento sempre alla portlet con identificativo EXT_2):
< liferay - portlet - app > ... < portlet > < portlet - name > EXT_2 </ portlet - name > </ portlet > ... < liferay - portlet - app >

Nel file Language-ext.properties in ext/ext-impl/src/content, si specificato il titolo della portlet definendo la seguente propriet:
javax . portlet . title . EXT_2 = Titolo

Attraverso il file liferay-display.xml si invece associata la portlet ad una determinata categoria del menu applicazioni. Questultimo raggiungibile facilmente dal pannello di controllo ed utile per inserire una portlet allinterno di una pagina del portale.
< display > ... < category name = " category . idCategoria " > < portlet id = " EXT_2 " / > ... </ category > ... < display >

Il tag display contiene quindi al suo interno tanti elementi category che specificano le varie categorie. Erano presenti ovviamente delle categorie predefinite per le portlet gi pronte ed utilizzabili in Liferay, ma in questo caso ho sentito la necessit di definirne altre per via delle particolari funzioni svolte dalle portlet da me sviluppate. Per aggiungere una categoria si considerato il file Language-ext.properties inserendo una direttiva di questo tipo:
category . idCategoria = nomeCategoria

Una categoria dunque descritta dalla parola category seguita da una stringa che fa da identificatore, e definita associando ad essa un nome. Il nome verr poi visualizzato nel menu delle applicazioni (si noti infatti lattributo name del tag category che richiama la definizione della categoria). Dopo aver seguito tutti questi passi preliminari, ho realizzato effettivamente la portlet creando il suo contenuto. Per fare ci ho innanzitutto creato una 92 di 113

7.3. SVILUPPO PORTLET cartella per essa sotto il percorso ext/ext-web/docroot/html/portlet/ext. La directory contiene le seguenti due pagine JSP: init.jsp, in cui ho aggiunto le seguenti righe di codice:
<% @ include file = " / html / common / init . jsp " % > < portlet : defineObjects / >

In questo modo vengono importate tutte le classi che servono e settate alcune variabili usate da tutte le portlet. In particolare, linclusione del file init.jsp di /html/common/ da accesso alle librerie di tag di Liferay; view.jsp, la pagina che rappresenta la vista della portlet, dove viene visualizzato il contenuto dinamico generato dai metodi definiti nella classe della portlet specificata con il tag <portlet-class> nel file di configurazione portlet-ext.xml. Tutte le portlet sviluppate verranno ora descritte, spiegando per ognuna di esse la funzionalit offerta e i principali metodi implementati per generare il relativo contenuto.

7.3.1

Portlet per le informazioni

Si tratta di una portlet che permette di mostrare alcune informazioni sulla comunit nella quale installata la portlet. In particolare, i dati visualizzati possono essere cos riassunti: numero degli utenti iscritti alla comunit; nome e cognome degli utenti che erano online in un determinato momento; ultimi tre messaggi del forum della comunit; ultimi tre post del blog della comunit. Ho quindi implementato degli opportuni metodi per ricavare le varie informazioni. Un valore passato come parametro alloggetto render request stato sicuramente quello che indicava il numero di membri appartenenti alla comunit in cui veniva inserita la portlet, ricavato in questo modo:
int n u m b e r O f U s e r s I n G r o u p = U s e r L o c a l S e r v i c e U t i l . ge tG ro up Us er sC ou nt ( portletGroupId ) ;

Per ottenerlo stato necessario dapprima estrarre lidentificativo della comunit in cui era presente questa portlet. Questultimo stato cos ottenuto:
ThemeDisplay themeDisplay = ( ThemeDisplay ) renderRequest . getAttribute ( WebKeys . THEME_DISPLAY ) ; long portletGroupId = themeDisplay . g etPort letGr oupId () ;

93 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT Dalla richiesta di render in ingresso al metodo doView ho ricavato il tema visualizzato dal quale ho potuto successivamente determinare lid voluto. Anche nelle altre portlet da me sviluppate ho avuto bisogno di questo identificatore in quanto le ho realizzate in modo che facessero riferimento alle risorse presenti in quella certa comunit in cui erano installate. Altri attributi impostati nella request sono stati delle stringhe che erano in pratica degli spezzoni di codice HTML passati alla vista per rappresentare il nome e cognome degli utenti online e gli ultimi tre messaggi del forum e post di quella comunit. Nella figura sottostante si pu vedere uno screenshot della portlet.

Figura 7.5: Portlet per le informazioni su una comunit. Ho realizzato anche una variante di questa portlet aggiungendo alcune informazioni personali sullo stesso utente autenticato che consulta la pagina, ovvero nome, cognome e data e ora della sua ultima visita al portale.

7.3.2

Portlet per la pagina daccesso

Una pesante assenza di cui soffriva il portale era relativa ad una pagina dingresso che potesse indicare e dare accesso istantaneamente alle comunit di cui un utente faceva parte. Infatti, lutente, dopo essersi autenticato, per muoversi tra le varie comunit doveva compiere una serie di passi effettuati a partire dal pannello di controllo che certamente rendevano un po irritante la cosa, non essendo in grado di entrare velocemente in una di esse. 94 di 113

7.3. SVILUPPO PORTLET Si pensato quindi di realizzare una portlet che servisse appunto a velocizzare questa operazione, offrendo inoltre altre funzionalit aggiuntive. La portlet, chiamata portalAccess, stata quindi impostata come pagina di accesso visibile da un utente dopo il suo login al portale. Essa mostra tutte le comunit di cui lutente membro in un modo semplice e chiaro, in maniera tale che siano facilmente accessibili. La figura qui sotto mostra la portlet nel mio specifico caso dove faccio parte di due comunit, Gruppo Euris e Idea Planning. Come si pu notare, ho fatto in modo di inserire anche la comunit personale dellutente che mostra risorse legate alla propria home page, al suo profilo e alla posta privata.

Figura 7.6: Portlet per laccesso alle comunit. In ogni area che rappresenta una comunit (di cui se ne pu vedere una singolarmente in figura 7.7) si sono posti dei collegamenti a contenuti specifici della stessa. Larea costituita da varie tab, una per ogni risorsa significativa presente in quella comunit (ad esempio quasi tutte condividevano il fatto di presentare un blog, un forum e una document library). Oltre a ci, si sono inseriti anche contenuti statici, come link a singole pagine della comunit. La scelta di quali risorse rendere visibili stata fatta dallazienda. Nel metodo doView ho utilizzato dei metodi delle API di Liferay per ottenere le varie risorse di cui necessitavo, alcuni dei quali si possono qui elencare: getBlogsEntries, metodo statico di BlogsEntryLocalServiceUtil usato per ritornare gli ultimi tre post inseriti o modificati nel blog della comunit; getMBMessages, metodo statico della classe MBMessageLocalServiceUtil utilizzato per ricavare gli ultimi tre messaggi inseriti o modificati nel forum; 95 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT getGroupFileEntries, metodo statico della classe DLFileEntryLocalSer viceUtil, per ottenere gli ultimi tre documenti presenti nella document library della comunit; getEvents, metodo statico della classe CalEventLocalServiceUtil, per ritornare gli ultimi tre eventi di calendario della comunit. In particolare, i metodi citati ritornavano ognuno una lista di oggetti a loro specifici (oggetti di tipo BlogsEntry per i post dei blog, MBMessage per i messaggi dei forum, DLFileEntry per i file delle document library e di tipo CalEvent per gli eventi di calendario). In seguito, per ottenere esattamente tre elementi per ogni risorsa e ordinarli per data ho utilizzato altri metodi ed opportuni oggetti. Infine, ho impostato tutti questi array (pi altri oggetti necessari) nella richiesta di render. Li ho poi recuperati nella vista dove, per quanto riguarda gli array, ho scorso i vari elementi creando la loro presentazione nella pagina.

Figura 7.7: Singola comunit visualizzata dalla portlet. Nella pagina view.jsp ho dunque realizzato dei blob HTML per visualizzare le diverse aree per le varie comunit. Come detto, unarea dotata di uninterfaccia a schede che rende pi facile la navigazione tra le risorse presenti nella comunit. Per costruirla mi sono servito di un apposito plugin di jQuery, idTabs (disponibile allindirizzo http://plugins.jquery.com/project/idTabs) utilizzato in una modalit per la quale una certa tab si attivava al passaggio del mouse sopra di essa. 96 di 113

7.3. SVILUPPO PORTLET Tale plugin funzionante su tutti i browser web pi diffusi (testato su Internet Explorer 6+ e su recenti release di Firefox e Chrome).

7.3.3

Portlet per gli interessi utente

Attraverso la portlet qui descritta, lazienda ha cercato di coinvolgere maggiormente il personale su diversi temi proposti che possono essere di loro interesse e riguardanti essenzialmente le tecnologie usate da Gruppo Euris per lo sviluppo di applicazioni. La portlet, denominata setUserInterests, fa in modo che un utente possa segnalare le proprie aree di interesse e competenza allinterno di un elenco tassativo presente allinterno del proprio profilo (la portlet stata infatti inserita nella comunit personale di ogni utente). Un interesse associato ad una determinata categoria del forum della comunit Gruppo Euris e relative discussioni. Pi precisamente, ho fatto in maniera tale che le categorie associate ai vari interessi debbano essere sottocategorie della categoria Community Sourcing pensata appunto a questo scopo. Qui sotto riportato uno screenshot delle categorie attualmente presenti.

Figura 7.8: Categorie associate agli interessi/competenze di un utente. Ogni volta che viene aperta una discussione nella stanza di forum relativa a 97 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT quellarea dinteresse (categoria e relative sottocategorie), viene inviato un alert (una mail) a tutti i collaboratori che lhanno segnata. Lutente pu poi disattivare manualmente lalert per un certo interesse, cancellandone la propria iscrizione. La portlet, visibile in figura 7.9, si compone di un form costituito da varie checkbox di scelta (una per ogni categoria dinteresse presente in Community Sourcing) e commento affiancato.

Figura 7.9: Portlet per gli interessi/competenze di un utente. Lo sviluppo di questa portlet stato accompagnato da altre modifiche: 1) aggiunta di un attributo personalizzato che contiene gli interessi al modello dei dati che descriveva lutente (oggetto User); 2) modifica del comportamento di default del forum per liscrizione alle categorie. Per laggiunta dellattributo personalizzato, denominato interestsTags, il modo pi semplice ed immediato di farlo attraverso il quadro di controllo (avendo gli opportuni permessi). Infatti, ho acceduto al portale come amministratore e dal pannello di controllo ho creato lattributo (di tipo array di stringhe) e lho associato a tutti i vari utenti (tramite unapposita impostazione anche ai nuovi iscritti in futuro). In questo modo, lattributo veniva quindi aggiunto in modo persistente come colonna della tabella User nel database. Inoltre, ho impostato i ruoli utente che possono ottenere, visualizzare e modificare lattributo. Come detto in precedenza, ho modificato anche il comportamento di default 98 di 113

7.3. SVILUPPO PORTLET del forum, facendo in modo che quando viene aggiunta una nuova categoria, tutti gli utenti che sono iscritti alla categoria padre di quella categoria vengano automaticamente iscritti anche a questultima (questo stato fatto per associare gli utenti aventi una certa competenza anche alle nuove sottocategorie aggiunte). Ho deciso di modificare il comportamento di tutti i forum delle diverse comunit (anche se allinizio era stato modificato solo quello del forum della comunit Gruppo Euris, forum al quale sono associate le iscrizioni alle categorie per gli interessi) in quanto ho pensato che fosse ragionevole farlo, essendo, a mio avviso, una funzionalit utile e sensata per ogni forum. Per far ci ho considerato laction class EditCategoryAction relativa alla portlet del forum focalizzandomi sul suo metodo updateCategory. Questultimo, nel caso in cui lutente richieda unaggiunta di una categoria, esegue linserimento invocando il metodo statico addCategory della classe MBCategoryServiceUtil, ottenendo per prima tutti i parametri necessari (ad esempio il nome e la descrizione impostati, lidentificativo della categoria padre ed altri). Proprio dallid della categoria padre, ho potuto ricavare quella nuova aggiunta e verificare se un certo utente era iscritto ad essa e, in caso positivo, iscriverlo alla categoria figlia appena creata. La mia modifica si quindi limitata a poche righe di codice. Infatti, dopo aver creato una lista contenente tutti gli utenti del portale, lho scorsa ottenendo per ognuno di essi lelenco delle categorie a cui erano iscritti. Se la lista delle categorie a cui lutente era iscritto conteneva la categoria padre, allora lo si associava anche alla nuova categoria. Per liscrizione ad una certa categoria del forum ho usufruito del metodo statico subscribeCategory della classe MBCategoryServiceUtil, che prendeva due parametri dingresso ossia lid dellutente e quello della categoria. Tramite la classe della portlet e in particolare grazie al metodo doView ho gestito ad ogni submit del form (ed in generale al caricamento della pagina) i valori delle checkbox da spuntare o meno (controllando e, se necessario, cambiando lo stato di iscrizione/non iscrizione alle relative categorie). Ho tenuto conto anche di situazioni in cui lazienda poteva aggiungere o eliminare delle categorie dinteresse e, quindi, variare la disposizione delle checkbox di conseguenza. Gli attributi personalizzati vengono denominati anche expando attributes, dal momento che possono estendere gli oggetti del portale (come in tal caso loggetto User) con propriet e campi customizzati. Queste propriet aggiuntive diventano quindi degli oggetti di Liferay disponibili alluso. Per recuperare lattributo impostato ho agito in questo modo:
String [] userIntrs = ( String []) loggedUser . getExpandoBridge () . getAttribute ( " interestsTags " ) ;

Alloggetto loggedUser di tipo User, che rappresenta lutente autenticato, ho applicato il metodo getExpandoBridge che ritorna un oggetto di tipo 99 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT ExpandoBridge. Tale classe, come dice il nome, fornisce un ponte per laggiunta, lottenimento e limpostazione di attributi personalizzati che estendono gli oggetti del portale. Ho potuto cos ottenere lattributo che avevo settato per tutti gli utenti tramite il metodo getAttribute al quale ho passato come parametro il nome dellattributo. Dopo che lutente clicca sul pulsante di submit del form, dalla request si ottengono i valori relativi alle varie checkbox per vedere quali sono spuntate e quali no. I valori sono le stringhe degli interessi (in quanto gli attributi value degli input sono stati impostati considerando tutti i possibili ambiti dinteresse). Si setta quindi opportunamente lattributo utente interestsTags a seconda delle checkbox selezionate:
loggedUser . getExpandoBridge () . setAttribute ( " interestsTags " , userInterests ) ;

Qui, come detto, userInterests larray di stringhe degli interessi che viene costruito tramite un ciclo for recuperando i valori delle checkbox con delle invocazioni del metodo getParameter (a cui viene passato di volta in volta il nome della checkbox) sulloggetto request. Dopo di questo, ho invocato un metodo da me realizzato per cambiare lo stato di iscrizione/non iscrizione dellutente alle varie categorie a seconda degli stati delle checkbox ricevuti. In tale metodo, che ho chiamato changeCategoriesSubscriptions, ho fatto in modo che quando un utente seleziona un ambito dinteresse, cio in pratica la categoria, automaticamente viene iscritto anche alle sottocategorie, cos come nel momento in cui lo deseleziona viene cancellata la sua iscrizione anche a tutte le relative sottocategorie. Se la pagina viene richiesta senza che il bottone del form venga cliccato, si ottengono le stringhe degli interessi che lutente aveva settato in precedenza (sempre tramite lattributo interestsTags) e, da questi valori, vengono impostate e visualizzate di conseguenza le checkbox.

7.3.4

Portlet per i feedback

Lultima portlet che ho realizzato ha lo scopo di permettere a determinati utenti che fanno parte di una comunit di inviare un feedback mensile al loro responsabile di progetto. Per far ci, gli utenti compilano un opportuno form (mostrato parzialmente in figura 7.10) e i dati dei campi vengono salvati come documento Excel che viene memorizzato automaticamente in unapposita cartella della document library della comunit nella quale installata la portlet. Lazienda, infatti, ha voluto far s che i feedback non venissero inviati direttamente al responsabile (ad esempio al suo indirizzo mail oppure inseriti nella document library della sua comunit personale) ma fossero posti appunto nella library di quella comunit. Ovviamente, il documento, una volta compilato, era modificabile solo dallutente che lo aveva inserito oppure dal responsabile. 100 di 113

7.3. SVILUPPO PORTLET

Figura 7.10: Portlet per linvio di feedback.

Il form si compone, tra le altre cose, di due select con le quali si possono selezionare il cliente e il relativo progetto. Le liste dei clienti e dei progetti corrispondenti vengono recuperate facilmente in quanto ogni cliente associato ad una pagina del nodo Clienti della Wiki della comunit in cui installata la portlet, mentre ogni progetto una pagina figlia della pagina del cliente. Lazienda, infatti, ancor prima dello sviluppo di questa portlet, utilizzava la Wiki come una sorta di vetrina dove venivano presentati e descritti i vari progetti e i clienti che li richiedevano. La gerarchia di cartelle che viene creata nella document library della comunit che ospita la portlet rispecchia la divisione tra i diversi clienti con i loro progetti. Infatti, la radice di questa gerarchia la cartella Feedback e dentro questultima ci sono le varie cartelle dei clienti. Allinterno delle directory dei clienti sono presenti le cartelle dei relativi progetti. Un percorso di cartelle cliente - progetto viene creato al primo invio di un feedback corrispondente a quel cliente su quel progetto. Il form per linvio di un feedback, oltre ai campi precompilati per il nome utente 101 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT e indirizzo mail costituito da questi altri: select per la scelta del cliente; select per la selezione del progetto relativo a quel determinato cliente; select per la scelta del mese e dellanno a cui si riferisce il feedback (si visualizza solo lanno corrente, a parte quando viene scelto il mese di Dicembre in corrispondenza del quale la scelta si estende anche allanno precedente); varie aree di testo per descrivere cosa doveva fare in quel mese per quel progetto, cosha fatto effettivamente e cosa invece no e perch, gli aspetti positivi e quelli negativi nellaffrontare il lavoro ed infine quali opportunit ne ha tratto. Nella pagina JSP della vista, lattributo action del form lho implementato in questa maniera (si veda la sezione 2.5.4):
< portlet : renderURL > < portlet : param name = " jspPage " value = " / html / portlet / ext / feedback / view . jsp " / > </ portlet : renderURL >

Come si vede, ho specificato dove mandare i dati del form dopo averne fatto il submit e questo lho potuto fare grazie al tag <portlet:renderURL>. In tal modo ho creato un portlet URL che riferisce la portlet stessa (infatti lazione viene descritta con il parametro di invocazione che ha lattributo value pari al percorso della vista stessa). Anche per la precedente portlet, laction del form stata impostata allo stesso modo modificando ovviamente il valore del parametro jspPage che puntava a quella portlet. Ho fatto in modo che i valori della select del progetto cambiassero dinamicamente. Infatti, dal momento che i progetti selezionabili dallutente variano a seconda del cliente scelto, ho catturato il cambiamento direttamente nella vista tramite una funzione JavaScript (posta su un altro file e opportunamente richiamata allinterno della pagina JSP). In particolare ho gestito un evento onchange sulla select dei clienti in questo modo:
< select id = " clienti " name = " clienti " onchange = " setPr ojectO ptions ( this . id ) " >

Quando il contenuto della select varia, cio nel momento in cui lutente seleziona unaltra option rispetto a quella corrente, viene invocata la funzione setProjectOptions passando ad essa lid del nuovo valore selezionato. In questa funzione, per cambiare lelenco dei progetti relativi a quel cliente ho dovuto eseguire un submit del form senza cliccare il bottone di invio, in quanto necessaria una computazione lato server per ottenerlo. Per far funzionare questo meccanismo ho previsto un hidden input allinterno del form, ossia: 102 di 113

7.3. SVILUPPO PORTLET


< input type = " hidden " id = " buttonClicked " name = " buttonClicked " value = " buttonClicked " / >

Questultimo, inizialmente posto ad un valore non nullo, serve a vedere quando viene fatto il submit del form e da cosa esso causato (dal cliccare il bottone di invio del feedback o dalla selezione di unaltra option della select clienti). La precedente funzione JavaScript pone ad un valore nullo lhidden input ed esegue il submit del form:
document . getElementById ( buttonClicked ) . value = " null " ; document . getElementById ( feedbackForm ) . submit () ;

In questo modo significa che il submit stato fatto per recuperare le informazioni dei progetti di quel particolare cliente selezionato. La gestione dei vari casi viene spiegata di seguito. Come per tutte le altre portlet sviluppate, anche per quella qui descritta ho creato una classe che estende JSPPortlet per creare gli oggetti di business da mettere a disposizione tramite la request e che ridefinisce il metodo doView per la gestione della vista. In particolare ho ricavato dapprima le informazioni personali dellutente grazie al campo statico di tipo stringa USER_INFO dellinterfaccia javax.portlet.PortletRequest, chiamando il metodo getAttribute sulloggetto render request:
Map userInfo = ( Map ) renderRequest . getAttribute ( PortletRequest . USER_INFO ) ;

Lottenimento delle informazioni si completa estraendo i valori corrispondenti alle chiavi user.name.full (per il nome completo dellutente), user.name.nic kName (il suo username) e user.business-info.online.email (per il suo indirizzo email), tramite il metodo get della mappa. Queste informazioni, oltre a servirmi per creare i primi due campi precompilati del form, mi sono stati utili in seguito nel momento del salvataggio del feedback. Ho poi recuperato dalla request il parametro buttonClicked e ho controllato se presentava un valore nullo o meno. Se era non nullo significava che lutente aveva premuto il pulsante di invio. In questo caso ho verificato se i campi obbligatori (cliente, progetto e le prime due aree di testo) erano riempiti, altrimenti si mostravano degli opportuni errori sotto ai campi vuoti e non veniva permesso di salvare il documento. Se tutti i campi obbligatori erano riempiti allora ho potuto procedere con lottenere tutti i vari campi del form. In seguito ho creato la stringa di testo da scrivere nel file Excel, inserendo in essa il titolo, le intestazioni e valori dei campi (opportunamente separati da \n per una nuova riga e tabulazioni \t per il cambio di cella). Ho quindi convertito la stringa (qui chiamata docStr) in un array di byte, costruendo conseguentemente loggetto per lo stream di output e scrivendo i byte dellarray dentro ad esso:
byte [] theByteArray = docStr . getBytes () ;

103 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT


B y t e A r r a y O u t p u t S t r e a m outStr = new B y t e A r r a y O u t p u t S t r e a m () ; outStr . write ( theByteArray ,0 , theByteArray . length ) ;

Ho controllato dunque se nella document library era gi presente la cartella di quel particolare cliente per quel dato progetto a cui il feedback si riferiva. Se non cera ho provveduto a creare, anche parzialmente, la gerarchia di cartelle necessaria sotto Documents Home, cartella root che conteneva tutte le altre. La gerarchia si componeva cos: Feedback -> Cartella del cliente -> Cartella del progetto. Il documento prodotto andava a finire nellultima cartella. Ad ogni passo ho dovuto ottenere le varie cartelle per arrivare allultima utilizzando il metodo statico getFolder della classe DLFolderLocalServiceUtil e gestendo leccezione di tipo NoSuchFolderException lanciata se quella directory voluta non era presente. Allinterno del corpo delleccezione ho quindi creato la cartella usufruendo del metodo statico addFolder associandole anche i relativi permessi di accesso tramite il metodo addFolderResources applicati sempre alla classe DLFolderLocalServiceUtil. Una volta create le necessarie cartelle, ho costruito il nome del file da salvare che cos composto: Feedback_anno _mese _nomeCognomeUtente _idUtente .xls Dal momento che in una cartella il nome di un file univoco, un utente (avente un identificatore anchesso univoco) non pu inviare due volte il feedback di uno stesso mese e anno di riferimento riguardante un progetto di un cliente. Successivamente ho salvato il file come entry della libreria attraverso il metodo statico addFileEntry della classe DLFileEntryLocalServiceUtil. Se la memorizzazione andava a buon fine ho poi visualizzato un messaggio che informava lutente dellavvenuto salvataggio del feedback. Ho posto infatti queste due operazioni allinterno di un blocco try-catch in quanto il metodo precedente poteva sollevare uneccezione di tipo DuplicateFileException. Questo significava che lutente aveva gi inserito il suo feedback per quel progetto di quel cliente relativo ad un certo mese e, in tal caso, ho mostrato a schermo un messaggio derrore. Se, invece, il submit era dovuto al semplice cambiamento del cliente, non occorreva fare nulla. In questo caso, per, come nella situazione in cui lutente ometteva uno o pi campi obbligatori, era necessario salvare i contenuti dei campi gi inseriti e farli visualizzare (per far s che lutente non dovesse reinserirli). Ci stato fatto grazie alla funzione JavaScript onload, chiamata automaticamente ad ogni caricamento della pagina. Infine, come detto, i valori delle option dei clienti e progetti sono stati recuperati dalle relative pagine Wiki, sempre tramite le API di Liferay. In particolare, inseriti in contesti opportuni, mi sono stati utili i seguenti metodi: getNode della classe WikiNodeServiceUtil, usato per ottenere il nodo Clienti della Wiki (se presente, altrimenti lo creo); 104 di 113

7.3. SVILUPPO PORTLET getPage, metodo statico della classe WikiPageServiceUtil, utilizzato per ricavare una certa pagina; getChildPages, che pu essere applicato ad un oggetto pagina Wiki (di tipo WikiPage) e che ritorna le sue sottopagine (un oggetto List<WikiPage>). Per rendere linterfaccia grafica consistente, ho gestito anche le situazioni in cui potevano non esserci clienti (e quindi neanche progetti, essendo rappresentati da pagine Wiki figlie) oppure in cui per un certo cliente non si avevano progetti attivi. Nel primo caso per entrambe le select ho posto ununica option non selezionabile, rispettivamente con la stringa Nessun cliente e Nessun progetto. Nellaltro caso invece nella select dei progetti relativi a quel cliente ho inserito una option, anchessa non selezionabile, con la scritta Nessun progetto attivo. Ovviamente, in caso di mancanza delluno o dellaltro campo, il feedback non veniva aggiunto alla library.

105 di 113

CAPITOLO 7. SVILUPPO DI NUOVE FUNZIONALIT

106 di 113

Capitolo 8
Conclusioni
Inizio col dire che lattivit di stage si rivelata essere molto importante sia sotto laspetto formativo sia per quello che riguarda lesperienza vissuta in azienda. Lo sviluppo del portale intranet stato interessante, in quanto ho potuto conoscere la piattaforma Liferay che sta prendendo sempre pi piede nel mercato globale dei portali dal momento che viene usata da molte realt aziendali. Linteresse nei suoi confronti continua ad aumentare tanto che nessuna software house che si occupi di sviluppo web di alto livello pu pi permettersi di non conoscerla. Quindi, lopportunit di sviluppare per tale piattaforma risultata essere molto attuale, soprattutto vista la sempre pi crescente diffusione di soluzioni di questo tipo. Inoltre, come ho potuto osservare, offre veramente numerosi strumenti che portano innumerevoli vantaggi per lorganizzazione che ne fa uso. Primo fra tutti, secondo il mio punto di vista, il livello di granularit molto fine per la gestione degli utenti e delle operazioni che possono compiere. Liferay pu essere completamente personalizzato per ciascun utente che si autentica al portale: ad esempio si pu decidere per ogni utente o loro gruppi quali portlet, documenti, contenuti, ecc. pu visualizzare o con quali pu interagire. Una pecca deriva per dal fatto che il team di Liferay rilascia quasi mensilmente una nuova versione, spesso non retrocompatibile, con lo scopo di sfruttare la community nellidentificazione e correzione dei bug. Le versioni stabili e consolidate convergono poi nella versione Enterprise. Chi decide di sviluppare su Liferay deve quindi preventivare anche un certo impegno nella risoluzione autonoma di problemi e bug di vario genere. Tuttavia, per me questo non ha rappresentato propriamente uno svantaggio poich, grazie alla risoluzione dei problemi che interessavano Euris Due.Zero, ho potuto famigliarizzare presto con la piattaforma, toccando con mano quasi subito i diversi aspetti del suo funzionamento. Sono stato in grado di passare alla realizzazione di nuove funzionalit possedendo dunque una buona infarinatura del contesto sul quale si basava il portale. 107 di 113

CAPITOLO 8. CONCLUSIONI Per lo sviluppo, stato significativo anche il proseguire con lutilizzo di Eclipse, IDE di cui ancora una volta ho potuto apprezzare le notevoli potenzialit e benefici. Posso dire inoltre che la letteratura specializzata su Liferay (in particolare si veda [5], [6] e [7]), si evidenziata molto buona in quanto mi ha permesso di studiare il funzionamento generale della piattaforma, presentando anche degli utili esempi applicativi per lo sviluppo. Molto scarsa invece la documentazione fornita con le API proprie di Liferay, non corredate da alcuna spiegazione sulla funzione eseguita da una determinata classe o metodo. Hanno giocato per un ruolo essenziale le informazioni reperite in rete, soprattutto quelle derivanti dal sito ufficiale [9], il quale mette a disposizione un forum ed una wiki, entrambi molto efficaci per la risoluzione di problemi. La community di Liferay molto attiva sotto questo aspetto, offrendo un supporto degno di nota, mettendo a disposizione allo stesso tempo numerosi approfondimenti. Per quanto concerne lambiente lavorativo, lazienda mi ha accolto benissimo, facendomi trovare a mio agio fin dallinizio. Grazie a ci ho vissuto in maniera estremamente positiva lattivit di stage, ponendomi in condizione di affrontare in maniera serena tutte le problematiche emerse durante lo sviluppo. Infine, posso dire quindi che lo stage stato molto utile, soprattutto perch mi ha permesso di accrescere le mie competenze teoriche e pratiche con le conoscenze acquisite durante la mia permanenza in azienda. Il profilo che ho maturato in questi tre anni di studio stato per fondamentale dal momento che luniversit, oltre a darmi le basi, mi ha insegnato anche il criterio per apprendere nuove tecnologie.

108 di 113

Glossario
AJAX Acronimo di Asynchronous JavaScript and XML. una tecnica di sviluppo per la realizzazione di applicazioni web interattive, che comprende una serie di tecnologie quali XHTML, XML, CSS, JavaScript. La tecnica prevede uno scambio di dati in background tra browser e server che permette laggiornamento dinamico di una pagina web, senza il caricamento esplicito da parte dellutente. API Acronimo di Application Program Interface. Insieme di funzioni software ad alto livello, di solito di pochissime istruzioni, che attivano a loro volta software di basso livello il quale gestisce lhardware. Deploy Il processo col quale un componente (unit software applicativa gestita da un contenitore) viene inserito e configurato in un ambiente operativo. Deployment descriptor File XML associato ad ogni modulo che descrive come deve avvenire il deploy dello stesso. Questo file utilizzato dallo strumento di deploy per configurare correttamente il modulo seguendo le propriet specificate. Nella programmazione di servlet (Java) il descrittore di deployment il file web.xml che contiene informazioni di configurazione (messa in opera) delle applicazioni web. Framework Struttura di supporto nello sviluppo di software il quale mette a disposizione codice e/o funzionalit evitandone la riscrittura. Hibernate un motore di persistenza utilizzato per lo pi per realizzare il mapping di tabelle preesistenti in forma di oggetti. Fornisce infatti una mappatura delle classi Java in tabelle di un database relazionale e sulla base di ci gestisce il salvataggio degli oggetti di tali classi sul database. Si occupa, inoltre, del reperimento degli oggetti dalla base di dati, producendo ed eseguendo le query necessarie e la successiva reistanziazione delloggetto precedentemente mappato. 109 di 113

Glossario LDAP Acronimo di Lightweight Directory Access Protocol, un insieme di protocolli usati per accedere alle informazioni conservate centralmente attraverso una rete. basato su standard X.500 per la condivisione della directory, ma meno complesso e richiede meno risorse. Lo standard LDAP organizza le informazioni attraverso una scala gerarchica e il beneficio principale nel suo uso rappresentato dal fatto che i dati per unintera organizzazione possono essere consolidati in un deposito centrale. Open source Indica un software i cui autori (pi precisamente i detentori dei diritti) ne permettono, anzi ne favoriscono il libero studio e lapporto di modifiche da parte di altri programmatori indipendenti. REST Acronimo di Representational State Transfer, un protocollo di collaborazione basato su HTTP che permette la manipolazione delle risorse. Ci viene eseguito tramite delle apposite richieste per ottenere il contenuto (GET ), inviare (creare - PUT e/o aggiornare - POST ) ed eliminare (DELETE) risorse. Servlet Una servlet un oggetto o un componente software applicativo che opera allinterno di un server web per potenziare le sue funzionalit. Generalmente usata per generare i contenuti delle pagine web in forma dinamica a seconda dei parametri della richiesta spedita dal browser. SOAP Acronimo di Simple Object Access Protocol, un protocollo di trasmissione di messaggi in formato XML. Un messaggio costituito da una trasmissione in un senso, dal mittente al ricevente, ma si possono avere uno o pi messaggi che definiscono anche il tipo di comunicazione che si sta stabilendo. SOAP un protocollo di alto livello ed completamente indipendente dal protocollo di trasmissione sottostante, che pu essere indifferentemente HTTP o altri. URL Acronimo di Uniform Resource Locator. un modo per denotare una risorsa sulla rete, che costituito da uno schema (che identifica il protocollo di comunicazione), un server e un percorso (che tipicamente corrisponde ad un singolo file su quel server). WAR Acronimo di Web Archives Repository, un formato di file (.war) che rappresenta un archivio contenente tutti i vari componenti utilizzati in fase di messa in opera di unapplicazione web, come ad esempio pagine JSP, file HTML, classi Java e file XML. 110 di 113

WYSIWYG Letteralmente: What You See Is What You Get. Termine inglese che in italiano significa: Ci che vedi ci che ottieni. Si tratta di una modalit di lavoro in cui ci che viene prodotto viene visualizzato nel modo in cui apparir allutente finale. XML-RPC un protocollo che consente di eseguire delle chiamate a procedure remote (RPC, Remote Procedure Call) attraverso la rete internet sfruttando file XML e il protocollo HTTP. XSL Acronimo di Extensible Stylesheet Language, un linguaggio per la creazione di fogli di stile per XML che permette trasformazioni semplici o complesse della struttura e della formattazione di un documento XML.

111 di 113

Glossario

112 di 113

Bibliografia
[1] Tim OReilly, What Is Web 2.0 - Design Patterns and Business Models for the Next Generation of Software, Settembre 2005, disponibile allindirizzo http://oreilly.com/web2/archive/what-is-web-20.html. [2] Toby Ward, Intranet 2.0 Global Survey 2010, Settembre 2010, disponibile allindirizzo http://www.prescientdigital.com. [3] Alejandro Abdelnur, Stefan Hepper, Java Portlet Specification, version 1.0, Ottobre 2003, disponibile allindirizzo http://jcp.org/aboutJava/ communityprocess/final/jsr168/index.html. [4] Stefan Hepper, Java Portlet Specification, version 2.0, Gennaio 2008, disponibile allindirizzo http://jcp.org/aboutJava/communityprocess/ final/jsr286/index.html. [5] Jonas X. Yuan, Liferay Portal 5.2 Systems Development, Maggio 2009, Packt Publishing. [6] Richard L. Sezov Jr., Liferay Administrators Guide, Maggio 2009, Liferay, Inc.. [7] Jonas X. Yuan, Xinsheng Chen, Frank Yu, Liferay User Interface Development, Novembre 2010, Packt Publishing. [8] L. Dusseault, HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV), published as RFC 4918, Giugno 2007, disponibile allindirizzo http://tools.ietf.org/rfc/rfc4918.txt. [9] Liferay Portal, sito ufficiale del progetto: http://www.liferay.com.

113 di 113