Sei sulla pagina 1di 102

Alma Mater Studiorum ` Universita di Bologna II Facolt` di Ingegneria a

Corso di Ingegneria Informatica Laurea in Sistemi Distribuiti

Sviluppo di app HTML5 per laccesso a un portale scientico XWiki

Candidato Marco Zaccheroni

Relatore Prof. Andrea Omicini Correlatore Stefano Mariani

Anno Accademico 2011/2012 - Sessione II

A Caterina, perch` non saprei come fare senza di lei, e ai miei genitori, che mi hanno permesso di arrivare no a qui, a tutti i miei amici, la cui provvidenziale ironia mi ricorda sempre di non prendermi troppo sul serio.

Indice
Introduzione 1 Background 1 2 3 Le novit` dellHTML 5 . . . . . . . . . . . . . . . . . . . . . . a 7 9 9

Le App HTML 5 . . . . . . . . . . . . . . . . . . . . . . . . . 11 Piattaforma XWiki . . . . . . . . . . . . . . . . . . . . . . . . 12 3.1 3.2 Architettura di XWiki . . . . . . . . . . . . . . . . . . 13 Estendere XWiki . . . . . . . . . . . . . . . . . . . . . 13 15

2 Internet e il mondo mobile 1 2 3

Di colt` e limiti nellaccesso ad un sito classico in mobilit` . . 15 a a Adattare il sito esistente o crearne uno ad hoc? . . . . . . . . 18 CASO REALE: accedere ad un portale scientico XWiki da dispositivo mobile . . . . . . . . . . . . . . . . . . . . . . . . . 20

3 Come sviluppare una app HTML5 1 2

23

Analisi dei requisiti e progettazione dellapp . . . . . . . . . . 23 Scelta degli strumenti . . . . . . . . . . . . . . . . . . . . . . . 24 2.1 2.2 Il Client . . . . . . . . . . . . . . . . . . . . . . . . . . 25 LApplication Server . . . . . . . . . . . . . . . . . . . 26 Client: jQuery mobile . . . . . . . . . . . . . . . . . . . 27 Application Server: Tomcat . . . . . . . . . . . . . . . 29 35

Implementazione . . . . . . . . . . . . . . . . . . . . . . . . . 26 3.1 3.2

4 App HTML5 per laccesso ad un portale scientico XWiki 1 2

Analisi dei requisiti . . . . . . . . . . . . . . . . . . . . . . . . 35 Progettazione . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

6 3

Indice Implementazione . . . . . . . . . . . . . . . . . . . . . . . . . 37 3.1 3.2 Congurazione Application Server . . . . . . . . . . . . 37 Client . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.3 3.4 Congurazione . . . . . . . . . . . . . . . . . 38 Elementi comuni a tutte le pagine . . . . . . . 40 Pagine dellapplicazione . . . . . . . . . . . . 42 Il foglio di stile . . . . . . . . . . . . . . . . . 45 lApplication Cache . . . . . . . . . . . . . . 46

Il DataBase di XWiki . . . . . . . . . . . . . . . . . . . 48 Le Servlets . . . . . . . . . . . . . . . . . . . . . . . . . 49 53 55 99 101

Conclusioni e sviluppi futuri Appendice - Codice completo Bibliograa Ringraziamenti

Introduzione
Fino a qualche anno fa era impensabile poter portare in tasca un dispositivo con capacit` computazionali paragonabili a quelle di un computer. Tutto ` a e cambiato durante il 2007, in una fredda giornata di gennaio un uomo chiamato Steve Jobs disse al mondo che Apple aveva intenzione di reinventare il telefono presentando liPhone. Non ` sbagliato dire che quello fu linizio di una vera e propria rivoluzioe ne nel mondo della comunicazione mobile, si pass` infatti da telefoni che si o comportavano come piccoli computer a piccoli computer che si comportano anche come telefoni. Gli smartphone si sono diusi a macchia dolio nella popolazione mondiale, un recente studio condotto dalla societ` di ricerca comScore ha infatti a evidenziato che solo negli Stati Uniti i possessori di smartphone sono passati dallessere appena 9 milioni nel Giugno del 2007 a circa 110 milioni nel Maggio del 2012.

Introduzione

Grazie alla possibilit` di collegarsi ad internet in qualsiasi momento e da a qualsiasi luogo, i dispositivi mobili hanno quindi portato un radicale cambiamento nel paradigma di utilizzo del web, introducendo la necessit` di a accedere in maniera pi` intuitiva e diretta hai contenuti. u Questo comporta un necessario cambiamento anche allinterno del web stesso, nella struttura delle sue pagine. Lo scopo di questa tesi ` quindi quello di mostrare in che modo sia possibie le, tramite le nuove tecnologie, cambiare il web per renderlo pi` adatto ad u una consultazione dai dispositivi mobili. Per farlo viene presentato il processo di sviluppo di una app HTML 5 per laccesso al portale APICe del Dipartimento di Informatica: Scienza e Ingegneria (DISI) dellAlma Mater Studiorum-Universit` di Bologna, che si appoggia sulla piattaforma XWiki. a Nellintento di chiarire e approfondire i temi nora solo accennati, la tesi si articola come segue: nel capitolo 1 vengono fornite le descrizioni sulle tecnologie che sono alla base della tesi: lo stato dellarte delle tecnologie del web e le caratteristiche di una piattaforma XWiki; nel capitolo 2 viene presentato il problema dellaccesso ad un sito classico da dispositivo mobile e si analizzano le possibili soluzioni, applicandole anche al caso reale di XWiki; nel capitolo 3 invece ci si concentra su cosa signichi sviluppare unapp HTML5 per un sito mobile e quali siano gli strumenti necessari, inne nel capitolo 4 viene mostrato il processo di sviluppo di una applicazione HTML5 per laccesso a un portale scientico XWiki.

Capitolo 1 Background
Il Web ` ben lungi dallessere fatto, e ` solo in una fase farraginosa di costruzione. e - Tim Berners-Lee -

In questo capitolo vengono introdotti i principali argomenti su cui si concerta questa tesi: si descrive dapprima che cosa ` lHTML5, quali sono le e principali innovazioni che ha introdotto e come queste lo rendono il protagonista del web di domani; in seguito viene presentata la piattaforma XWiki descrivendone il funzionamento e larchitettura.

Le novit` dellHTML 5 a

LHyperText Markup Language (HTML) ` un linguaggio di markup con il e ` quale ` possibile denire la struttura di una pagina web. E stato creato al e Cern nel 1991 da Tim Bernes-Lee ed ` diventato famoso nel 1994 grazie alla e diusione su larga scala di Internet. Negli anni si ` passato da un tipo di web orientato ai documenti, equivalene te ad un classico libro che lutente poteva semplicemente consultare, ad uno pi` orientato alle applicazioni, dove lutente oltre che a consultare pu` anche u o creare contenuti, grazie a strumenti web sempre pi` elaborati. u

10

Background

LHTML per` non ` riuscito a stare al passo con questo cambiamento, obo e bligando di fatto gli sviluppatori web ad utilizzare strumenti di terze parti, come Flash, plugin che per anni ` stato il punto di riferimento per la creae zione di animazioni, video e contenuti interattivi per il web. Per questo motivo nasce lHTML 5 [1], con il preciso scopo di fornire agli sviluppatori uno strumento e cace ed e ciente per poter realizzare soluzioni innovative che non necessitino di alcun strumento esterno. Nonostante il nome faccia pensare al contrario, questa innovazione non ` da e assegnare solo a miglioramenti del linguaggio di markup ma deriva anche dallenorme potenziale delle nuove funzionalit` del CSS 3 [2] e delle ultime a API di javascript [3]. Anche se ` ancora abbastanza lontano dalla sua forma nale (il W3C dovrebe be rilasciare le speciche denitive entro un anno o due) lHTML5 porta con se numerose novit` [4] ed ` utilizzato da un numero sempre maggiore di svia e luppatori, anche se non completamente supportato dalla totalit` dei browser. a Le principali innovazioni sono: semplicazione della struttura di una pagina, grazie allintroduzione di markup semantici (come <header>, <nav>, <footer>, <aside>); utilizzo delle pagine oine, possibilit` di salvare le (e dati) in locale; a possibilit` di creare un canale di comunicazione full-duplex tra client e a server, senza dover ricaricare ogni volta la pagina (Web Sockets); accesso diretto alle API dei device su cui viene visualizzato il sito, cos` da poter accedere, ad esempio, alla geolocalizzazione; supporto nativo per gli elementi multimediali, introduzione dei tag <video>, <audio> e <canvas>; supporto per lesecuzione di script in background (Web Workers).

1.2 Le App HTML 5

11

Le App HTML 5

Negli ultimi anni c` stato un aumento esponenziale dei dispositivi (e quindi e delle persone) connessi ad internet, questo ` stato possibile anche grazie ale lenorme successo dei dispositivi mobili (smartphone e tablet). E quindi indispensabile che i siti web possano essere facilmente utilizzabili anche in mobilit`, tenendo conto di tutte le dierenze che ci sono con la cona sultazione da desktop. Grande importanza hanno quindi le app HTML 5 (chiamate anche web app) ovvero siti web che mostrano funzionalit` ed interfaccia simile a quelle delle a applicazioni native installate sui dispositivi mobili, cos` da massimizzare le sperienza di visita e la possibilit` di accesso ai contenuti. a Pregi delle app HTML5: sono universali, non dipendono ne dallhardware ne del sistema operativo del dispositivo in cui vengono utilizzate, necessitano solo di un browser che supporti adeguatamente gli ultimi standard; sono pi` economiche e veloci da sviluppare rispetto alle app native u orendo funzionalit` del tutto similari; a non hanno il bisogno di sottoporsi al processo di approvazione del market (App store, Marketplace e Wikdows store) quindi possono contenere qualsiasi tipo di contenuto. Difetti: non hanno (ancora) il completo accesso alle API del device su cui viene utilizzata (rubrica, fotocamera, messaggi,...); sono meno reattive delle app native, dato che parte dellelaborazione della rete; hanno meno visibilit` e diusione, quindi minore possibilit` di guadaa a gno.

risiede sul server, le prestazioni dellapp dipendono molto dalla qualit` a

12

Background

Piattaforma XWiki

Uno spazio Wiki ` sito web (nella sua accezione pi` basilare, ovvero un insiee u me di documenti ipertestuali) in cui sono gli utenti stessi a creare e modicare i contenuti, realizzando cos` il vero obiettivo di Internet cio` la condivisione e della conoscenza. Lo spazio Wiki pi` famoso ` indubbiamente Wikipedia, lenciclopedia grau e tuita nata nel 2001 ` ora disponibile in 285 lingue diverse e conta pi` di e u 4.100.000 articoli per la sola versione Inglese (quella principale). Le pagine Wiki vengono scritte tramite un linguaggio di markup creato appositamente: il wikitext, che si basa sulla notazione [[...]] per inserire hyperlink ad altre pagine. Il wikitext si distingue dagli altri linguaggi dello stesso tipo perch non consente di applicare stili o di interagire con linguaggi e di scripting. Le pagine vengono interpretate dal motore wiki che si occupa di tradurle in semplici pagine HTML interpretabile da qualsiasi browser. Il vero limite di una piattaforma Wiki quindi deriva direttamente dai limiti del linguaggio con cui ne vengono create le pagine, i contenuti possono essere solo di tipo testuale e la struttura pu` essere solo quella di una semplice o enciclopedia. Per superare questi limiti nasce XWiki, una piattaforma open source basata su Java, come suggerisce il nome ha anchessa lobiettivo della creazione e condivisione della conoscenza ma lo mette in pratica con strumenti decisamente pi` potenti: le pagine possono essere infatti create sfruttando linguaggi u di scripting come Groovy e Velocity che, derivando direttamente da Java, permettono potenzialmente la creazione di qualsiasi tipo di contenuto. [5]

1.3.1 Architettura di XWiki

13

3.1

Architettura di XWiki

Come descritto nella relativa documentazione [6], XWiki ha unarchitettura di tipo modulare:
XWiki Enterprises Application

Core (JAR)

Plugins (JAR)

Modules - Set of Components (JAR)

Skins (Zip of CSS, vm, images, JS)

Templates Common to all skins (vm, CSS, JS, UI frameworks such as Prototype, SmartClient, YUI)

Applications - Set of wiki pages (XAR)

Service APIs XWiki Platform

User Interface

Container (e.g. Servlet Container)

La parte fondamentale ` costituita dal Wiki Platform dove sono contenuti e i pacchetti che formano le service APIs, cuore operativo della piattaforma, e la User Interface. Al Wiki Platform si collegheranno quindi diverse altre componenti a seconda del tipo di wiki che si vuole creare. Tra queste ` doveroso e citare XWiki Enterprise, che permette di creare un wiki professionale con caratteristiche avanzate come la gestione/creazione di blog, rights management, pdf export, skinning e con un motore molto avanzato per lo scripting scripting.

3.2

Estendere XWiki

Laspetto pi` importante della piattaforma XWiki ` che pu` essere liberau e o mente estesa, non solo nei contenuti ma proprio nella struttura. E infatti possibile creare componenti che interfacciandosi alla XWiki Platform ne estendono le funzionalit`. Questi componenti possono essere: a

14 Applicazioni (set di pagine); Plugin realizzati in Java; Script da inserire nelle pagine XWiki; Moduli scritti in Java.

Background

Skin o rielaborazioni di quelle esistenti;

Capitolo 2 Internet e il mondo mobile


Il Web ` pi` uninnovazione sociale e u che uninnovazione tecnica - Tim Berners-Lee -

In questo capitolo si analizzano dapprima le motivazioni per cui i siti classici non sono adatti per la navigazione da dispositivi mobili come smartphone e tablet, poi si ragiona sulla necessit` di creare soluzioni dedicate a questi dea vice e le modalit` con cui si possono realizzare. Inne si applicheranno questi a ragionamenti al caso pratico di un portale scientico XWiki, discutendo su come questo si possa adattare al mondo mobile.

Di colt` e limiti nellaccesso ad un sito a classico in mobilit` a

Per sito classico si intende un sito web con una forte componente statica, progettato e realizzato per essere consultato da un computer desktop (sso o portatile). Solitamente questi siti presentano un elevato numero di scritte e di collegamenti, perlopi` testuali. u Non ` di cile capire quali siano le motivazioni per cui queste tipologie di siti e non sono adatti alla consultazione da dispositivo mobile:

16

Internet e il mondo mobile

schermi troppo piccoli anche se negli ultimi tempi gli schermi di tablet e smartphone hanno raggiunto risoluzioni molto elevate, la loro grandezza sica resta decisamente inferiore a quella di un computer desktop, i contenuti delle pagine web risultano quindi molto di cili (se non impossibili) da consultare. dierente paradigma di interazione per anni linterazione sul web ha seguito solamente il paradigma del point & click, lutente utilizzando il mouse sposta il puntatore su di un elemento graco o testuale, per poi cliccare ed ottenere un risultato. Con lavvento degli schermi touch, per` linterazione ` mutata, seguendo un paradigma molto pi` naturao e u le, utilizzando delle dita. Bisogna notare il fatto che un dito umano ` e nettamente pi` grande del puntatore del mouse, questo rende notevolu mente probabile un errore nella selezione di un hyperlink piuttosto che un altro se sono disposti in maniera molto vicina tra loro. tecnologie non supportate a causa di limitazioni nella capacit` di elaa borazione o di decisioni aziendali, non tutti i tipi di contenuti sono supportati dai dispositivi mobili: tutti i device con sistema operativo iOS, non permettono la visualizzazione di contenuti Flash; app di terze parti; gli archivi compressi non sono gestibili, se non appoggiandosi ad alcune tipologie di documenti, anche multimediali (es .doc, .xls, e .wav) non sono supportati o non vengono gestiti correttamente.

Come indicato nei graci a pagina seguente, tratti dal rapporto Internet Trends pubblicato nel 2012 da Mary Meeker [7], il tra co web generato da dispositivi mobili aumenta notevolmente ogni anno, ` infatti passato dal 4% e a ne 2010 al 13% nel novembre 2012 e ben presto superer` quello generato a dai computer desktop, come ad esempio ` gi` successo in India. e a

2.1 Di colt` e limiti nellaccesso ad un sito classico in mobilit` a a

17

Global Mobile Traffic Growing Rapidly to 13% of Internet Traffic


Global Mobile Traffic as % of Total Internet Traffic, 12/08 11/12 15% 13% in 11/12

% of Internet Traffic

10% 4% in 12/10

5%

1% in 12/09

0% 12/08

6/09

12/09

6/10

12/10

6/11

12/11

6/12
15

Source: StatCounter Global Stats, 11/12

In India, Mobile Internet Traffic Surpassed Desktop Internet Usage in May, 2012 - Other Countries to Follow
India Internet Traffic by Type, Desktop vs. Mobile, 12/08 11/12
100%

80% % of Internet Traffic

60%

Desktop Internet Mobile Internet

40%

20%

0% 12/08

6/09

12/09

6/10

12/10

6/11

12/11

6/12
16

Source: StatCounter Global Stats, 11/12

18

Internet e il mondo mobile

Questa tendenza rende quindi indispensabile lesistenza di siti web dedicati alla navigazione da dispositivo mobile: nella prossima sezione verranno analizzate le possibili modalit` con cui questi possono essere creati. a

Adattare il sito esistente o crearne uno ad hoc?

Quando si decide di creare una versione mobile di un sito, bisogna innanzitutto scegliere se realizzare una versione adattata del sito normale, oppure se creare un sito ad hoc, appositamente concepito e strutturato per la visualizzazione su dispositivi mobili.

Adattare il sito esistente potrebbe essere la scelta pi` semplice, il lavoro u si concentrerebbe esclusivamente sul design da applicare alla struttura gi` a esistente nelle pagine. Il risultato sar` quindi il seguente: a
Computers desktop Mobile devices

stile DESKTOP (css & JS)

stile MOBILE (css & JS)

STRUTTURA <html>

DataBase

2.2 Adattare il sito esistente o crearne uno ad hoc?

19

Si noti per` che questa strada ` realmente semplice solo se il sito da cui si o e parte ` stato creato applicando una netta separazione tra codice (HTML) e e design (CSS), se cos` non ` stato questo processo di adattamento potrebbe e rivelarsi altamente complesso. Bisogna inoltre considerare che un sito concepito per lambiente desktop ha solitamente una struttura molto complessa ed articolata ed ` ricchissimo e di informazioni, situazione ben lontana da quella che permette unottimale consultazione da dispositivo mobile che richiede semplicit` e sintesi . a Altra problematica risiede nelle modalit` in cui vengono applicati i diversi a design al sito, non tutti i dispositivi mobili infatti gesticono correttamente gli attributi media e media queries attraverso i quali vengono attuali gli adattamenti. Questa soluzione comporta per` notevoli vantaggi in sede di manutenzione o del sito, dato che si avr` ununica piattaforma da gestire anzich due distinte. a e Creare un sito dedicato permette invece di avere un controllo totale sulla struttura e sul design di ci` che verr` visualizzato, cos` da poter garantire o a la migliore esperienza di visita allutente; sar` possibile eettuare una suda divisione pi` e cace dei contenuti ed una organizzazione pi` e ciente delle u u funzionalit` oerte dal sito. a Grazie al controllo sulla struttura delle pagine sar` pi` semplice seguire le a u linee guida per una ottimale consultazione del sito da dispositivi mobili [8], le principali sono: tagliare le caratteristiche, eliminare tutte le cose che non sono fondamentali per luso in mobilit`; a tagliare i contenuti, ridurre il numero di parole e rinviare informazioni secondarie a pagine secondarie; ingrandire gli elementi dellinterfaccia, cos` da evitare il problema del dito grosso di cui si ` anche parlato in precedenza. e I principali svantaggi di questa scelta sono in fase di creazione, dovendo costruire ex-novo il sito occorreranno tempi di sviluppo pi` lunghi e costi u maggiori, e in fase di manutenzione dove ovviamente si avranno due distinte

20

Internet e il mondo mobile

piattaforme da gestire: quella desktop e quella mobile. La struttura nale del sistema sito desktop/sito mobile sar` dunque il sea guente:
Computers desktop Mobile devices

stile DESKTOP (css & JS)

stile MOBILE (css & JS)

struttura DESKTOP <html>

struttura MOBILE <html>

DataBase

CASO REALE: accedere ad un portale scientico XWiki da dispositivo mobile

Come introdotto nel capitolo precedente, XWiki ore una piattaforma per la condivisione avanzata della conoscenza. Questo lo rende uno strumento perfetto per la creazione di un portale scientico dove la comunit` degli a studiosi pu` collaborare e pubblicare i risultati delle ricerche. o Un ottimo esempio ` APICe che, come riportato nella home page, tramite e XWiki realizza un laboratorio di ricerca che ospita, sicamente o virtualmente, singoli studiosi, gruppi di ricerca e progetti interdisciplinari, che includono studenti di dottorato, collaboratori e ricercatori, principalmente (ma non esclusivamente) appartenenti al Dipartimento di Informatica: Scienza e

2.3 CASO REALE: accedere ad un portale scientico XWiki da dispositivo mobile 21 Ingegneria (DISI) dellAlma Mater Studiorum-Universit` di Bologna. a La grande quantit` di funzionalit` e di informazioni allinterno di ogni pagia a na e la mancanza di un supporto nativo per la visualizzazione in mobilit`, a costituiscono un grosso ostacolo per la consultazione di un portale XWiki, e di conseguenza di APICe, tramite smartphone e tablet. Le alternative possibili per consentire un accesso ottimale ai contenuti della piattaforma tramite i dispositivi mobili sono: Modicare la skin di visualizzazione adattando la struttura preesistente delle pagine cos` da disporre i contenuti in maniera ottimale. Pu` essere realizzato tramite linserimento di uno script velocity allino terno del metodo view del motore XWiki, in modo che venga riconosciuto il tipo di dispositivo che eettua la richiesta di visualizzare la pagina, nel caso si tratti di smartphone o tablet viene poi caricata una skin dierente da quella classica, progettata appositamente per le caratteristiche di questi dispositivi. Creare unapp HTML 5 cos` da poter ricostruire liberamente la struttura delle pagine, eliminando funzioni e caratteristiche di cilmente utilizzabili in ambito mobile e organizzando in maniera pi` funzionale la u divisione dei contenuti. Pu` essere realizzata utilizzando uno dei tanti o framework disponibili per crerare web app e sfruttando le caratteristiche del Servlet Container, che sta alla base della piattaforma XWiki, per accedere al DataBase in cui i dati sono memorizzati.

Nei seguenti capitoli di questa tesi si ` scelto di mostrare un esempio ime plementativo di una semplice app HTML5 per laccesso ad un portale scientico, per le seguenti motivazioni: permette una maggiore libert` nella divisione ed organizzazione dei cona tenuti, in modo da garantire pi` facilmente le caratteristiche di sintesi u e semplicit` per le pagine; a consente di creare uninterfaccia utente del tutto simile a quella delle app native, rendendo pi` intuitiva la navigazione nel sito; u

22

Internet e il mondo mobile ` pi` performante, salvando sul dispositivo mobile tutti i componenti e u statiche) in modo da minimizzare il tra co dati.

statici dellapplicazione (immagini, le di scripting e di stile, pagine

E invece possibile trovare un esempio riguardo alla modica di una skin di visualizzazione nella tesi Congurazione di un portale XWiki per la visualizzazione su dispositivi mobili: il caso di APICe di Buscarini Andrea.

Capitolo 3 Come sviluppare una app HTML5


Chiedersi se un computer possa pensare non ` pi` interessante del chiedersi e u se un sottomarino possa nuotare. - Edsger Dijkstra -

Lo scopo di questo capitolo ` quello di mostrare le tappe principali nello e sviluppo di unapp HTML5, dalle fasi preliminari di analisi e progettazione alla fase implementativa in cui si scelgono gli strumenti ottimali e si realizzano i componenti, in particolare questultima parte verr` accompagnata da piccoli a esempi pratici.

Analisi dei requisiti e progettazione dellapp

Prima di tutto occorre stabilire che cosa deve essere in grado di fare lapp HTML 5 che si ha intenzione di sviluppare. Si devono decidere le caratteristiche principali e il tipo di funzionalit` che essa dovr` orire. a a In seguito si passa alla denizione di come devono essere realizzate queste funzionalit`, Questa fase prende il nome di progettazione ed ha lobiettivo di a

24

Come sviluppare una app HTML5

determinare quale sar` la struttura operativa dellapplicazione. a Possiamo riconoscere principalmente due tipologie di app: client-only, sono applicazioni autosu cienti, non hanno il bisogno di prelevare contenuti da fonti esterne (es. database) ed hanno quindi una struttura semplice ad un solo livello, il client appunto. client/server, sono quelle applicazioni in cui c` una divisione sica e (oltre che logica) tra la parte che si occupa dellinterfaccia graca e delle dei contenuti. In base a come (e dove) viene implementata la business logic (insieme degli algoritmi che si occupano della creazione dinamica dei contenuti) queste applicazioni possono avere una struttura a due o 3 livelli logicofunzionali: 2-tier architecture il client si collega direttamente al sistema database dove sono conservati i dati. 3-tier architecture il client si occupa solamente della GUI e dellimpaginazione dei contenuti che ottiene connettendosi ad un application server in cui risiede la business logic dellapp che eettua il collegamento al database. Indubbiamente larchitettura pi` interessante ` quella 3-tier architecture, u e in quanto permette una migliore suddivisione dei compiti tra i vari componenti funzionali dellapplicazione, facilitando non solo il processo di creazione ma anche quelli successivi di gestione ed estensione. funzionalit` semplici e la parte che si occupa della gestione/creazione a

Scelta degli strumenti

Una volta denite caratteristiche e struttura dellapp si pu` passare alla o fase di implementazione; prima per` ` di fondamentale importanza scegliere oe accuratamente gli strumenti con cui realizzarne le componenti, in modo da poter coniugare al meglio prestazioni e funzionalit`. a

3.2.1 Il Client

25

2.1

Il Client

Nei capitoli precedenti si ` detto diverse volte che il principale vantaggio dello e sviluppo di una web app ` quello di poter realizzarne ununica applicazioe ne che pu` essere utilizzata da pi` dispositivi, a prescindere dallhardware e o u dal Sistema Operativo che hanno. Questo per` non ` completamente vero, ` o e e necessario considerare sempre quali sono le caratteristiche del browser utilizzato e la di colt` nellaggiornare il software da parte degli utenti con scarse a capacit` tecniche (che a causa della diusione mainstream di smartphone e a tablet sono la maggioranza). Occorre quindi prestare molta attenzione alla scelta del framework con il quale implementare lapp, tra quelli esistenti attualmente, i pi` interessanti u sono: ` jQuery Mobile E il pi` famoso ed utilizzato, come suggerisce il nome ` leu e voluzione di jQuery e consente di creare applicazioni che orono buone funzionalit` su un numero piuttosto elevato di device (non solo di a ultima generazione). Utilizza un approccio basato sul progressive enhancement 1 , dove viene data importanza fondamentale ai contenuti, per questo sono stati suddivisi i device in base alle loro capacit`, i pi` a u evoluti fruiranno di una esperienza e di una interfaccia pi` compleu ta rispetto a quelli obsoleti, ma tutti potranno comunque accedere ai contenuti e alle funzionalit` dellapplicazione. a Sencha Touch Figlio del famoso ExtJS ` un framework basato quasi come pletamente su JavaScript che permette di creare applicazioni molto complete con uninterfaccia che pochissimo ha da invidiare a quelle native. Tutte le caratteristiche dellapp vengono denite tramite il linguaggio di scripting, lasciando allHTML il solo compito di includere lo script, questo permette una incredibile libert` di implementazione ma a genera anche un handicap non indierente, infatti funziona esclusivamente sui browser che implementano WebKit, quindi solo sugli ultime versioni di Safari (iOS) e Chrome (Android).
1

per approfondimenti: Aaron Gustafson (2008), Understanding Progressive En-

hancement, http://www.alistapart.com/articles/understandingprogressiveenhancement;

26

Come sviluppare una app HTML5

2.2

LApplication Server

Come detto parlando della fase di progettazione, lApplication Server costituisce il vero cuore dellapplicazione. A dierenza di un classico Web Server, lApplication Server non si limita solamente a rispondere alle richieste del client con una semplice pagina HTML, ma ` capace di eseguire algoritmi di calcolo, ricerche ed elaborazioni e complesse sui dati. Fornisce un vero e proprio ambiente di esecuzione per implementare la business logic, permettendo di utilizzare linguaggi di alto livello (come Java)) per generare pagine dinamiche, in grado di cambiare aspetto e contenuti in base alle decisioni dellutente. Il pi` diuso ` sicuramente Tomcat, ` un application server open source u e e sviluppato dalla Apache Software Foundation. Basato su Java e sulle speciche della tecnologia J2EE, ` tecnicamente un Servlet Container e JSP e Engine, cio` un software capace di gestire lato server le web app costituite e da componenti Servlet e da pagine JSP [10]. Le Servlet sono classi Java che vengono eseguite ogni qualvolta lapplication server riceve una richiesta particolare, costituiscono il cuore della business logic, in cui vengono eettuate tutte le operazioni destinate alla ricerca ed elaborazione dei dati. Le JSP (Java Server Page) sono invece pagine in cui convivono HTML e Java, con lo scopo di creare pagine web dinamiche che cambiano in base alle necessit` dellutente. a

Implementazione

Verranno ora mostrati due esempi di realizzazione dei due livelli funzionali, client e server, introdotti nella sezione precedente. Per la realizzazione del lato client, si ` deciso di utilizzare jQuery mobile e per le sue caratteristiche HTML5-oriented e per la elevata compatibilit` con a quasi la totalit` dei dispositivi attualmente sul mercato. a

3.3.1 Client: jQuery mobile

27

3.1

Client: jQuery mobile

jQuery Mobile sfrutta la struttura semantica delle pagine del nuovo standard HTML5 e dei suoi metadata (grazie agli attributi data-*) per denire le varie parti dellinterfaccia, in questo modo per creare una semplice applicazione sar` su ciente scrivere del normale codice HTML5, senza il bisogno a di utilizzare tecnologie particolari [9]. Per rendere pi` chiaro il funzionamento del framework, di seguito ` riportato u e il codice per denire la struttura di una semplice pagina:
<! DOCTYPE html > < html > < head > < title > Web app name </ title > < meta name = " viewport " content = " width = device - width , initial - scale =1.0 , maximum scale =1.0 , minimum - scale =1.0 , user - scalable = no " > < link rel = " stylesheet " href = " http :// code . jquery . com / mobile /1.0 b3 / jquery . mobile -1.0 b3 . min . css " / > < script type = " text / javascript " src = " http :// code . jquery . com / jquery -1.6.3. min . js " > </ script > < script type = " text / javascript " src = " http :// code . jquery . com / mobile /1.0 b3 / jquery . mobile -1.0 b3 . min . js " > </ script > </ head > < body > < div data - role = " page " > < div data - role = " header " data - position = " fixed " data - id = " head " > < h1 > Page Title </ h1 > </ div > < div data - role = " content " > < h1 > Page Content </ h1 > </ div > < div data - role = " footer " data - position = " fixed " data - id = " foot " > < div data - role = " navbar " data - iconpos = " top " > < ul > < li > <a href = " # " data - icon = " home " > Button 1 </ a > </ li >

28

Come sviluppare una app HTML5


< li > <a href = " page2 . html " data - icon = " grid " > Button 2 </ a > </ li > < li > <a href = " page3 . html " data - icon = " search " > Button 3 </ a > </ li > </ ul > </ div > </ div >

</ div > </ body > </ html >

La prima porzione di codice interessante ` quella relativa al meta tag viewe port, qui vengono impostate alcune caratteristiche di default per la visualizzazione della pagina, in questo caso viene settata la larghezza della pagina deve coincidere con la grandezza dello schermo e viene disabilitato lo zoom. Vengono poi importati i le del framework, il foglio di stile del tema di default e i due le con gli funzioni javascript di jquery e jquery mobile. Passando al body invece si pu` facilmente notare il largo utilizzo degli ato tributi data-*, essi hanno lo scopo di impostare i metadata relativi ai vari elementi della pagina; metadata che verranno utilizzati dal framework per interpretare gli elementi ed assegnare loro la giusta posizione. Analizziamo ora il signicato dei principali attributi data-* utilizzati: data-role, assegna un valore semantico al tag di aggregazione (solitamente div) a cui viene assegnato: page identica il corpo complessivo della pagina, ` infatti possibile e anche specicare pi` pagine in uno stesso le html; u header, header e navbar creano gli elementi dellinterfaccia graca, rispettivamente la barra in alto, quella in basso e loggetto che contiene i pulsanti per la navigazione tra le viste (pagine) dellapp. data-position, utilizzato esclusivamente per header e footer, assestatico questo elemento, impedendo al browser di ricarcarlo; data-icon e data-iconpos, inseriscono delle icone ai pulsati che vengono aggiunti alla pagina, il primo specica il tipo di icona mentre il secondo la sua posizione. gnando lo stesso valore data-id su pagine diverse permette di rendere

3.3.2 Application Server: Tomcat il risutato dellinterpretazione della pagina sar` il seguente: a

29

3.2

Application Server: Tomcat

Per ogni utente che si collega alla web app, Tomcat istanzia un contenitore chiamato Sessione per tutta la durata del suo collegamento. Quando lutente eettua una richiesta, allinterno di questo contenitore vengono creati due oggetti: uno di nome request che corrisponde alla richiesta eettuata e uno di nome response come reazione. A questo punto entrano in azione le Servlets, ` necessario indirizzare request e e response al giusto Contesto in cui sono presenti le risorse necessarie a soddisfare la richiesta, ci sono tre scenari possibili al momento della generazione delloutput: La Servlet esaudisce correttamente la richiesta e assegna a Tomcat il nella forma di ipertesto HTML;

compito di consegnare direttamente il risultato al client, ad esempio

30

Come sviluppare una app HTML5 La risorsa non ` presente allinterno del contesto, Tomcat si occuper` e a la procedura di input/output; La richiesta pu` essere soddisfatta allinterno del contesto indicato ma o una forward verso unaltra risorsa (ad esempio verso una JSP che si occuper` di interpretare e integrare i risultati di una query con una a struttura HTML). non con la risorsa richiesta (almeno non interamente) viene generata

quindi di eettuare una nuova ricerca in un contesto esterno, riavviando

Vediamo ora un piccolo esempio, supponiamo di avere un database MYSQL con una sola tabella, come rappresentato qui sotto: DB: supereroi Nome Iron Man Batman Capitan America Green Arrow Wolverine Alter ego Tony Stark Bruce Wayne Steve Rogers Oliver Queen Logan Universo Marvel DC Marvel DC Marvel

tabella: Anagrafe

Come prima cosa occorre denire il contesto della risorsa, aggiungendo al le <Tomcat Home>/conf/context.xml le seguenti righe:
< Resource name = " jdbc / eroifumetti " auth = " Container " type = " javax . sql . DataSource " maxActive = " 100 " maxIdle = " 30 " maxWait = " 120000 " username = " root " password = " root " driverClassName = " org . gjt . mm . mysql . Driver " url = " jdbc:mysql: // localhost / supereroi />

In questo modo sar` possibile eettuare la connessione al database dalla sera vlet passando il semplice riferimento al contesto.

3.3.2 Application Server: Tomcat

31

Ora viene mostrata una semplice servlet con il compito di ottenere dal DB tutti i nomi dei supereroi e di passare questi risultati ad una pagina JSP che in cui verranno impaginati; per semplicit` non si ` riportata la gestione delle a e eccezioni:
1 2 public class HeroesName extends HttpServlet { public void doGet ( H tt 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 ServletException , IOException { 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 } } } dbconn . close () ; // passaggio dei risultati all oggetto request request . setAttribute ( " results " , res ) ; // che viene rimandato alla pagina JSP dove a RequestDispatcher req uestDi spatch er = get Servle tConte xt () . g e t R e q u e s t D i s p a t c h e r ( " / nomisupereoi . jsp " ) ; requestDispatcher . forward ( request , response ) ; InitialContext initCtx = new InitialContext () ; DataSource dataSource = ( DataSource ) initCtx . lookup ( " java : comp / env / jdbc / supereroi " ) ; Class . forName ( " org . gjt . mm . mysql . Driver " ) ; Connection dbconn = dataSource . getConnection () ; PreparedStatement sql = dbconn . prepareStatement ( " select Nome from Anagrafe ; " ) ; ResultSet results = sql . executeQuery () ; while ( results . next () ) { // inserimento dei risultati in una struttura dati di nome " res "

Il metodo doGet(...) viene richiamato ogni qualvolta viene eettuata una richiesta alla servlet; osservando il codice alla riga 4 si pu` notare il riferio mento al contesto creato in precedenza, seguito dallesecuzione della query. Inne avviene lassegnazione dei risultati alloggetto request che viene poi consegnato alla pagina JSP dove vengono mostrati allutente. A nch` la web app possa eseguire correttamente la Servlet, ` fondamentae e le seguire una precisa organizzazione dei le allinterno di una directory in

32 [Tomcat Home]/webapps/.

Come sviluppare una app HTML5

Lorganizzazione dovr` essere la seguente: a


webapps webapp Name Client les WEB-INF web.xml classes lib

La cartella WEB-INF contiene tutti i le non visualizzabili dal Client per motivi di sicurezza del sistema: Il le web.xml viene denito deployment descriptor e permette a Tomcat di eseguire le Servlet descrivendone percorsi e argomenti necessari per linizializzazione. Allinterno di classes sono invece presenti tutti i compilati Java per il funzionamento delle Servlets. Nel caso in cui Servlet e classi Java si supporto siano inseriti allinterno cartella lib. Per utilizzare la Servlet inserita sopra occorrer` modicare il le web.xml a come segue:
<web - app xmlns = " http: // java . sun . com / xml / ns / j2ee " xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance " xsi:schemaLocation = " http: // java . sun . com / xml / ns / j2ee http: // java . sun . com / xml / ns / j2ee / web - app_2_4 . xsd " version = " 2.4 " > < description > Super Heroes App </ description >

di uno o pi` archivi Jar, questi dovranno essere inseriti allinterno della u

3.3.2 Application Server: Tomcat


< servlet > < servlet - name > MainServlet </ servlet - name > < servlet - class > HeroesName </ servlet - class > </ servlet > < servlet - mapping > < servlet - name > MainServlet </ servlet - name > <url - pattern >/ HeroesName </ url - pattern > </ servlet - mapping > </ web - app >

33

Cos` facendo per richiamare la Servlet sar` su ciente includerla in un attri a buto href, nel seguente modo:
<a href = " HeroesName " > Heroes Name </ a >

Concludendo, nella pagina nomisupereoi.jsp nale, sar` necessario recupea rare lattributo results che gli ` stato passato dalla servlet ed elaborarlo per e inserirlo nel contesto della pagina:
<% String [] names ; if ( request . getAttribute ( " results " ) != null ) { names = ( String []) request . getAttribute ( " results " ) ; for ( int i = 0; i < names . length ; i ++) // elaborazione e stampa dei contenuti } else { out . println ( " error " ) ; } %>

Capitolo 4 App HTML5 per laccesso ad un portale scientico XWiki


La disumanit` del computer sta nel fatto che, a una volta programmato e messo in funzione, si comporta in maniera perfettamente onesta. - Isaac Asimov -

Lo scopo di questo capitolo ` di fornire un esempio pratico di come una app e HTML5 per laccesso ad un portale scientico possa essere implementata concretamente. Lobiettivo ` quello di creare una applicazione che permetta e di accedere allo spazio pubblicazioni del portale APICe.

Analisi dei requisiti

Lapplicazione dovr` fornire tutti i contenuti riguardanti le pubblicazioni a disponibili su APICe. Le pubblicazioni dovranno essere: suddivise per tipologia:

Articoli di rivista Articoli in serie Articoli di conferenze Capitoli di libro Volumi curati

Indicizzate per: co-autore;

36

App HTML5 per laccesso ad un portale scientico XWiki co-curatori; riviste & serie; tag.

Dovr` anche essere possibile eettuare la ricerca di una o pi` pubblicazioni a u ltrando per parole chiave, anno e stato di pubblicazione.

Progettazione

Per poter fornire le informazioni riguardo alle pubblicazioni ` ovviamente e necessario accedere al DataBase di XWiki, ` necessario quindi realizzare un e modello client/server. Per permettere una implementazione pi` ordinata, con una adeguata diviu sione tra interfaccia utente e business logic, ` opportuno strutturare lapplie cazione secondo una architettura three-tier: Presentation Tier: ` il livello pi` e u esterno dellapplicazione, qui viene creata ` linterfaccia utene te con la principale funzione di tradurre i task e i risultati in qualcosa facilmente comprensibile; Logic tier: livello che coordina lapplicazione, in cui ` realizzata la e business logic, processa le richieste dellutente e crea le query da consegnare al DB, elabora poi i risultati e li passa al presentation tier ; Data Tier: qui risiede il database in cui vengono conservati i dati. Riceve le query dal logic tier e passa i risultati che verranno per lelaborazione.
DataBase Application Server Client

Presentation Tier

Logic Tier

Data Tier

4.3 Implementazione

37

Il Client verr` realizzato utilizzando il framework jQuery mobile per le a sue caratteristiche HTML5-oriented e per la elevata compatibilit` con quasi a la totalit` dei dispositivi attualmente sul mercato. a Come Application Server verr` invece utilizzato Tomcat, in quanto graa zie alle tecnologie JSP e Servlets permette limplementazione della business logic tramite Java. Allinterno dellapplicazione verr` eettuato laccesso diretto al DataBase a MySQL di XWiki, senza utilizzare il middleware. Tale scelta punta semplicemente ad una pi` rapida e semplice implementazione della business u logic.

3
3.1

Implementazione
Congurazione Application Server

Come spiegato nel capitolo precedente per un corretto funzionamento dellapplicazione ` necessario modicare alcuni le di congurazione di Tomcat. e Per impostare il giusto Contesto in cui sono presenti le risorse (ovvero il database di xwiki) dove poter recuperare i dati necessari allapplicazione si ` modicato il le [Tomcat Home]/conf/context.xml aggiungendo le e seguenti righe:
< Resource name = " jdbc / ApiceHTML5 " auth = " Container " type = " javax . sql . DataSource " maxActive = " 100 " maxIdle = " 30 " maxWait = " 120000 " username = " xwiki " password = " xwiki " driverClassName = " org . gjt . mm . mysql . Driver " url = " jdbc:mysql: // localhost / xwiki ? useServerPrepStmts = false & amp ; useUnicode = true & amp ; c haract erEnco ding = UTF -8& amp ; sessionVariables = sql_mode = " />

38

App HTML5 per laccesso ad un portale scientico XWiki

I valori per i parametri di congurazione del contesto sono stati prelevati direttamente dal e hibernate.cfg.xml di XWiki. Inoltre occorre anche creare un le web.xml da inserire nella cartella WEBINF nella ROOT dellapplicazione, il le dovr` contenere i parametri base a dellapp e la descrizione delle Servlets, come segue:
<web - app xmlns = " http: // java . sun . com / xml / ns / j2ee " xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance " xsi:schemaLocation = " http: // java . sun . com / xml / ns / j2ee http: // java . sun . com / xml / ns / j2ee / web - app_2_4 . xsd " version = " 2.4 " > < display - name > Apice Publications Space </ display - name > < description > Simple app HTML5 to access the publication space inside APICe XWiki </ description > < servlet > < servlet - name > MainServlet </ servlet - name > < servlet - class > PubsList </ servlet - class > </ servlet > < servlet - mapping > < servlet - name > MainServlet </ servlet - name > <url - pattern >/ PubsList </ url - pattern > </ servlet - mapping > ... < session - config > < session - timeout > 30 </ session - timeout > </ session - config > </ web - app >

3.2
3.2.1

Client
Congurazione

Come gi` detto diverse volte nelle pagine precedenti, una web app pu` avere a o funzionalit` ed interfaccia del tutto simili a quelli delle app native. Cona

4.3.2 Client

39

gurando di alcuni parametri alliinterno dell<head> ` possibile permettere e allutente di aprire lapplicazione come se fosse realmente installata nel telefono, senza doverla ogni volta caricare con il browser. Tramite i browser di iOS e Android ` infatti possibile creare dei collegamenti (chiamati Web Clip) e direttamente dalla Home Screen, con tanto di icona personalizzabile, splash screen allapertura e visualizzazione a tutto schermo. Per specicare la visualizzazione non scalabile a tutto schermo, senza i comandi del browser:
< meta name = " viewport " content = " width = device - width , initial - scale =1.0 , maximum - scale =1.0 , minimum - scale =1.0 , user - scalable = no " > < meta name = " apple - mobile - web - app - capable " content = " yes " >

Per specicare diverse icone, a seconda della risoluzione del dispositivo:


< link rel = " apple - touch - icon - precomposed " sizes = " 72 x72 " href = " images / icon_72 . png " > < link rel = " apple - touch - icon - precomposed " sizes = " 114 x114 " href = " images / icon_114 . png " > < link rel = " apple - touch - icon - precomposed " href = " images / icon_57 . png " >

Per specicare diverse splash screen, in base al tipo di dispositivo (rilevato tramite lutilizzo di una media query in CSS3):
<! -- iPhone -- > < link rel = " apple - touch - startup - image " media = " ( device - width : 320 px ) " href = " images / splash_320x460 . png " > <! -- iPhone ( Retina ) -- > < link rel = " apple - touch - startup - image " media = " ( device - width : 320 px ) and ( - webkit - device - pixel ratio : 2) " href = " images / splash_640x920 . png " > <! -- iPad ( portrait ) -- > < link rel = " apple - touch - startup - image " media = " ( device - width : 768 px ) and ( orientation : portrait )" href = " images / splash_768x1004 . png " >

40

App HTML5 per laccesso ad un portale scientico XWiki

Inne ` necessario anche inserire i riferimenti ai le del framework ed al le e di stile personalizzato:


< link rel = " stylesheet " href = " css / themes / default / jquery . mobile -1.2.0. css " / > < link rel = " stylesheet " href = " css / style . css " / > < script src = " js / jquery . js " > </ script > < script src = " js / jquery . mobile -1.2.0. js " > </ script >

3.2.2

Elementi comuni a tutte le pagine

Per consentire una semplice navigazione allinterno dellapp sono stati aggiunti alcuni elementi statici: Header barra orizzontale nella parte superiore della pagina, in cui ` presente e il logo dellapp e compaiono i tasti per tornare indietro o per tornare alla home, nel caso in cui non sia presente il footer.
< div data - role = " header " data - position = " fixed " data - id = " head " id = " head " > <a href = " index . jsp " data - icon = " back " data - iconpos = " notext " data - rel = " back " id = " bt_back " > back </ a > < img src = " images / logo . png " > <a href = " index . jsp " data - icon = " home " data - iconpos = " notext " </ div > id = " bt_home " > home </ a >

Analisi dei meta-tag signicativi: data-position=fixed e data-id, indicano al browser di non coinvolgere lelemento nelle animazioni per le transizioni e di non ricaricare ogni volta. data-rel=back, serve per la navigazione allinterno della crono-

logia, in modo che venga caricata la pagina visitata precedentemente, se questa funzionalit` non ` supportata dal browser verr` a e a caricata la pagina index.jsp.

Il prodotto dellelaborazione da parte del framework sar`: a

4.3.2 Client

41

Footer barra orizzontale nella parte inferiore della pagine, contiene una navbar in cui ci sono i collegamenti per le tre viste principali dellapp. Non viene visualizzata nelle pagine in cui ` presente un qualsiasi elenco e di pubblicazioni.
< div data - role = " footer " data - position = " fixed " data - id = " foot " id = " foot " > < div data - role = " navbar " data - iconpos = " top " > < ul > < li > <a href = " # " data - icon = " home " class = " ui - btn active ui - state - persist " id = " bt_nav " > Publications </ a > </ li > < li > <a href = " indexes . jsp " data - icon = " grid " id = " bt_nav " data - transition = " slide " > Indexes </ a > </ li > < li > <a href = " search . jsp " data - icon = " search " id = " bt_nav " data - transition = " slide " > Search </ a > </ li > </ ul > </ div > </ div >

Analisi dei meta-tag signicativi: data-transition, specica il tipo di transizione nelaccedere alla to attivo del pulsante a cui viene assegnato, utilizzato in una navbar indica allutente la pagina in cui ` attualmente. e Il prodotto dellelaborazione da parte del framework sar`: a pagina indicata nellattributo href. class=ui-btn-active ui-state-persist, serve a forzare lo sta-

42 3.2.3

App HTML5 per laccesso ad un portale scientico XWiki Pagine dellapplicazione

Lapplicazione ` costituita da tre viste principali: e Publications in cui ` presente una list view dove tramite la quale si pu` e o visualizzare lelenco di tutte le pubblicazioni, oppure solamente di una particolare tipologia, questa ` anche lhome page dellapplicazione; e Indexes che contiene una list view per accedere allelenco dei co-autori, dei co-curatori, delle riviste & serie oppure dei tag; Search da cui, tramite la compilazione di un form ` possibile eettuare una e ricerca per parole chiave, anno o stato di pubblicazione. A titolo di esempio qui di seguito viene riportato parte del codice, del content della pagina Search, in quanto permette di fare alcune osservazioni interessanti sul funzionamento della tecnologia JSP e dellApplication Server. Per lintero codice di tutte le pagine si rimanda allappendice.
< form name = " Search " action = " PubsList ? type = search " transition = " slidefade " > < input type = " search " name = " text " id = " text " / > < div id = " advanced - search " > < div data - role = " fieldcontain " > < select name = " year " id = " year " > < option value = " " > Year </ option > <% int year = Calendar . getInstance () . get ( Calendar . YEAR ); for (; year > 1979; year - -) out . println ( " < option value =\ " " + year + " \ " >" + year + " </ option > " ) ; %> </ select > </ div > < div data - role = " fieldcontain " > < select name = " status " id = " status " > < option value = " " > Status </ option > < option value = " In press " > In press </ option > ... </ select > </ div > </ div > data -

4.3.2 Client
< input type = " submit " value = " Search " data - theme = " a " data icon = " search " / > </ form >

43

Grazie allattributo action della form, ` possibile analizzare un esempio di e comunicazione con le Servlets, il tutto avviene in maniera molto trasparente, ` infatti su ciente inserire il nome della servlet come se si trattasse di e una semplice pagina del sito (aggiungendo eventualmente dei parametri da passargli) , lApplication Server poi prender` in carico la richiesta ed eseguir` a a la classe Java corrispondente. In questo esempio ` inoltre possibile osservare e la potenza delle JSP, queste infatti permettono di utilizzare del codice Java (delimitato da <% %>) allinterno dellHTML per eettuare semplici calcoli o elaborazioni. Il prodotto dellelaborazione da parte del framework sar`: a

Sono inoltre presenti altre due pagine, che permettono la creazione dei contenuti dinamici, in base ai risultati che vengono consegnati dalle Servlet: Publications Founded ` la pagina che dinamicamente crea una list view, e i cui elementi sono i collegamenti alle singole pubblicazioni; Publication contiente tutte le informazioni riguardo ad una specica pubblicazione, tra cui il collegamento al le pdf (se presente), alla pagina di XWiki corrispondente e a tutte le pubblicazioni con gli stessi tag.

44

App HTML5 per laccesso ad un portale scientico XWiki

Per capire in che modo queste pagine dinamiche funzionano si supponga di richiedere allapplicazione, tramite il form visto sopra, tutte le pubblicazioni del 2012. La servlet PubsList interroga il database e inserisce i risultati in un array, che in seguito viene consegnato alla pagina pubsfounded.jsp per creare la listview sopracitata. Per motivi di chiarezza il codice per la creazione dinamica della listview viene mostrato in una versione semplicata, rimandando allappendice per la versione completa e correttamente funzionante.
if ( request . getAttribute ( " results " ) != null ) { ListItem [] results = ( ListItem []) request . getAttribute ( " results " ) ; for ( int i = 0; i < results . length ; i ++) { out . println ( " <li > < a href =\" PubInfo ? id = " + results [ i ]. getId () + " & name = " + results [ i ]. getName () + " \" class =\" " + results [ i ]. getName () + " \" > < h2 > " + results [ i ]. getTitle () + " </ h2 > <p > <b > " + results [ i ]. getYear () + " </b > " + results [ i ]. getAuthor () + " </p > </a > </ li > " ) ; } }

Ottenendo un risultato simile a:

Allo stesso modo, una volta che si seleziona un elemento in particolare dalla listview, si eettua una richiesta ad una servlet, questa volta chiamata

4.3.2 Client

45

PubInfo per le informazioni, speciche di quella particolare pubblicazione. Viene eettuata unaltra interrogazione al database e questa volta viene passato un oggetto Java Publication alla pagina publication.jsp. 3.2.4 Il foglio di stile

Introducendo un foglio di stile personalizzato, oltre a quello del framework, ` possibile sfruttare le potenzialit` delle media queries1 introdotte con il e a CSS3, queste permettono di denire allinterno di un unico le stili dierenti, a seconda delle dimensioni dello schermo coi cui si accede alla pagina. Per impostare regole particolari per la visualizzazione su schermi larghi al massimo 480px sar` su ciente inserire il comando: a @media only screen and (max-device-width: 480px) { ... } E possibile vedere un semplice esempio nella pagina in cui vengono mostrati i dettagli di una pubblicazione. Nel caso questa venga consultata ad esempio da un iPhone (il cui schermo anche se realmente ha 960px di larghezza, nel CSS viene considerato da 480px con doppia densit` di pixel) la sezione con a i dettagli viene visualizzata in colonna, mentre se viene consultata da un dispositivo con risoluzione maggiore sar` disposta su due colonne. a

Visualizzazione su iPad

per approfondimenti: http://www.w3.org/TR/css3-mediaqueries/

46

App HTML5 per laccesso ad un portale scientico XWiki

Visualizzazione su iPhone

3.2.5

lApplication Cache

E una delle tante novit` dellHTML5, ` unestensione della cache normale. a e Indicando esplicitamente al browser quali le salvare, senza che questi debbano essere per forza visitati, lappication cache permette la consultazione pi` o meno completa di un sito anche oine. u Il suo funzionamento ` piuttosto semplice, ` su ciente creare un le alline e terno del quale si specica la lista di le che il browser deve salvare nella sua memoria e che deve mostrare anche quando si ` oine, il formato ` il e e seguente: CACHE MANIFEST CACHE: index.jsp indexes.jsp search.jsp error.jsp nofound.jsp offline.jsp

4.3.2 Client ... FALLBACK: / offline.jsp

47

Il le deve contenere obbligatoriamente nella prima riga il testo CACHE MANIFEST e puoi essere suddiviso in tre sezioni: CACHE: i le indicati sotto verranno inseriti nella cache; NETWORK: contiente i le che non devono essere salvati ma che richiedono la connessione internet; FALLBACK: permette di indicare una risorsa di fallback da caricare nel caso in cui i le che corrispondono al pattern indicato (il pattern / indica tutti i le), che non sono stati inseriti nella cache, non siano raggiungibili. Una volta creato il le ` necessario specicarlo come attributo del tag html e nella homepage dellapplicazione, cos` da creare la cache non appena si accede la prima volta:
< html manifest = " cache . manifest " >

Inne ` necessario congurare lApplication Server in modo che riconosca il e formato del le, per farlo occorre aprire il le [Tomcat Home]/conf/web.xml ed inserire:
< mime - mapping > < extension > manifest </ extension > < mime - type > text / cache - manifest </ mime - type > </ mime - mapping >

48

App HTML5 per laccesso ad un portale scientico XWiki

3.3

Il DataBase di XWiki

Allinterno del database di XWiki ad ogni pagina corrisponde un oggetto, cio` un record nella tabella xwikiobjects; per trovare le pubblicazioni sar` e a necessario controllare se il campo XWO CLASSNAME contiene la stringa Publications.PublicationClass. Il campo XWO ID rappresenta invece lid univoco delloggetto, tramite il quale si eettua il join con le altre tabelle ed ` possibile recuperare tutte e le informazioni riguardo ad ogni singola pubblicazione, come titolo, autori, estratto, anno, etc. Allinterno poi della tabella xwikiproperties ` possibile e trovare lintero elenco delle propriet` delloggetto, con il relativo classtype, a necessario per sapere in quale tabella ` conservato il dato, ad esempio il e titolo di una pubblicazione ` di tipo string ed ` contenuto nella tabella e e xwikistrings. Per una migliore comprensione di quanto appena detto, di seguito viene riportato lo schema E/R della parte signicativa del database.

4.3.4 Le Servlets

49

3.4

Le Servlets

Allinterno dellapplicazione sono presenti tre diverse Servlet: PubsList ha il compito di ricercare le informazioni base di ogni pubblicazione (titolo, anno e autori) per creare lelenco dinamico allinterno della pagina pubsfounded.jsp; Indexes interroga il database per indicizzare le pubblicazioni, tenendo anche il conto di quante pubblicazioni ci siano per ogni elemento di un indice; PubInfo ha il compito ultimo di ricercare tutte le informazioni disponibili per una particolare pubblicazione che verranno poi passate alla pagina publication.jsp per limpaginazione. A titolo di esempio viene di seguito analizzato il codice relativo alla Servlet PubsList. Questa servlet si occupa di creare la lista delle pubblicazioni disponibile, ltrando i risultati in base alle richieste dellutente. Le varie richieste vengono distinte tramite il parametro type che viene passato nellurl del link con cui viene evocata la servlet: type = all, tutte le pubblicazioni;

type = articles, solo gli articoli di riviste; type = series, solo gli articoli in serie type = books, solo i capitoli di libro; type = edite, solo i volumi curati type = papers, solo gli articoli di conferenze;

type = search, solo le pubblicazioni che corrispondono ai ltri settari nel form di ricerca, qui vengono passati anche i parametri text, year e status; type = authors, solo le pubblicazioni di un certo autore, attraverso il parametro name; type = editors, solo le pubblicazioni con un certo curatore, attraverso il parametro name; type = js, solo le pubblicazioni pubblicate su una particolare rivista o serie, attraverso il parametro name; metro name; type = tags, solo le pubblicazioni con un certo tag, attraverso il para-

50

App HTML5 per laccesso ad un portale scientico XWiki

Come prima cosa viene recuperato dalla request il parametro type e a seconda del suo valore viene preparata la query, per semplicit` di lettura ` ria e portato solamente il caso in cui type sia all, per il codice completo si rimanda allappendice:
1 2 public class PubsList extends HttpServlet { public void doGet ( H tt pS er vl et Re qu es t request , Ht tp S e rv l e tR e s po n s e response ) throws ServletException , IOException { 3 4 5 6 7 8 9 10 String jspPage = " " ; String select = " " ; String from = " " ; String condition = " " ; String join = " " ; String type = request . getParameter ( " type " ) ; if ( type . equals ( " all " ) ) { select = " O . XWO_ID as ID , O . XWO_NAME as NAME , S . XWS_VALUE as TITLE , L . XWL_VALUE as YEAR , LS . XWL_VALUE as AUTHOR " ; 11 12 from = " xwikistrings as S , xwikilongs as L , xwikilargestrings as LS , xwikiobjects as O " ; condition = " S . XWS_NAME = title and L . XWL_NAME = year and LS . XWL_NAME = author and O . XWO_CLASSNAME = Publications . PublicationClass and O . XWO_NAME <> P u b l i c a t i o n C l a s s T e m p l a t e " ; 13 14 } join = " S . XWS_ID = O . XWO_ID and L . XWL_ID = O . XWO_ID and LS . XWL_ID = O . XWO_ID " ;

Successivamente viene indicato il contesto specicato nel le di congurazione di Tomcat, si eettua la connessione al database e si esegue la query, si noti lapertura del blocco try/catch per poter gestire le eccezioni:
15 16 17 18 19 20 21 22 try { if (! select . equals ( " " ) ) { InitialContext initCtx = new InitialContext () ; DataSource dataSource = ( DataSource ) initCtx . lookup ( " java : comp / env / jdbc / ApiceHTML5 " ) ; Connection dbconn ; ResultSet results ; PreparedStatement sql ; Class . forName ( " org . gjt . mm . mysql . Driver " ) ;

4.3.4 Le Servlets
23 24 25 try { dbconn = dataSource . getConnection () ;

51

sql = dbconn . prepareStatement ( " select " + select + " from " + from + " where " + condition + " and " + join + " order by YEAR desc ; " ) ; results = sql . executeQuery () ;

26

In seguito si controlla che la query abbia prodotto risultati, in caso positivo questi vengono inseriti in un array di ListItem, oggetto creato ad hoc per contenere i campi signicativi delle pubblicazioni, che viene assegnato come attributo della request. Nel caso in cui non ci siano risultati invece si assegna alla variabile che indica la pagina verso cui inviare il forwarding il riferimento ad una pagina di errore: nofound.jsp.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 ... dbconn . close () ; request . setAttribute ( " results " , res ) ; jspPage = " / pubsfounded . jsp ? type = " + type ; } else { if ( results . next () ) { results . last () ; int size = results . getRow () ; int i = 0; ListItem [] res = new ListItem [ size ]; results . beforeFirst () ; while ( results . next () ) { id = results . getString ( " ID " ) ; name = results . getString ( " NAME " ) ; title = results . getString ( " TITLE " ) ; year = results . getString ( " YEAR " ) ; author = results . getString ( " AUTHOR " ) ; ... // impostazione parametri da consegnare alla JSP res [ i ] = new ListItem () ; res [ i ]. setId ( id ) ; res [ i ]. setName ( name ) ; res [ i ]. setTitle ( title ) ; res [ i ]. setYear ( year ) ; res [ i ]. setAuthor ( author ) ; i ++; }

52
54 55 }

App HTML5 per laccesso ad un portale scientico XWiki


jspPage = " / nofound . jsp " ;

Inne c` la gestione delle eccezioni, nel caso si entri nel ramo del catch si e imposta il caricamento di una pagina dove viene mostrato il messaggio di errore. Alla ne del metodo avviene poi il forwarding verso il riferimento che si trova dentro alla variabile jspPage passando i parametri request e response.
56 57 58 59 60 61 62 63 64 65 66 67 68 } } } request . setAttribute ( " from " , " PubsList " ) ; RequestDispatcher requestDi spatch er = get Servle tConte xt () . g e t R e q u e s t D i s p a t c h e r ( jspPage ) ; requestDispatcher . forward ( request , response ) ; } } } catch ( Exception err ) { jspPage = " / error . jsp " ; } catch ( SQLException s ) { request . setAttribute ( " error " , s ) ; jspPage = " / error . jsp " ;

Conclusioni e sviluppi futuri


Giunti al termine ` opportuno analizzare il lavoro svolto, cercando di indie viduare i risultati raggiunti e quelli mancati: in modo da orire interessanti spunti per delle future argomentazioni che integrino ulteriormente il presente trattato confermandone o confutandone il contenuto. Innanzitutto ` bene ricordare lobiettivo della tesi, al ne di poter valutare e correttamente se esso sia stato raggiunto o meno: come ` stato gi` detto, il e a proposito principale era quello di mostrare quali siano i metodi e le tecnologie per rendere il web pi` adatto al nuovo tipo di utilizzo che ne viene fatto, u tramite i dispositivi mobili. Quello appena enunciato pu` essere considerato o lo scopo di pi` alto livello della tesi, ma non ` il solo. Un secondo obiettiu e vo, non meno importante e sicuramente pi` concreto, ` la presentazione del u e processo di sviluppo di una app HTML5 per i dispositivi mobili, capace di semplicare la navigazione e massimizzare la fruizione dei contenuti anche allinterno di uno spazio complesso ed articolato come un portale scientico XWiki. Si conda nel raggiungimento di tali obiettivi, ad opera dei seguenti capitoli: il capitolo 2 dovrebbe aver descritto in maniera esaustiva le motivazioni che rendono necessaria la creazione di soluzioni web mirate al mondo mobile e le modalit` secondo cui queste possono essere realizzate; a il capitolo 3 dovrebbe aver denito in maniera non ambigua gli strumenti essenziali allo scopo; inne il capitolo 4 dovrebbe aver mostrato un utile esempio di sviluppo di una app HTML5 per una piattaforma XWiki.

54

Conclusioni e sviluppi futuri

Analizzando il risultato ultimo della tesi, ovvero lapplicazione per laccesso al portale scientico APICe realizzata in HTML5, ` opportuno eettuare ale cune osservazioni. Al ne di usufruire di un ottimale grado di libert` nellorganizzazione dei a contenuti, depurandoli dalla struttura delle pagine di XWiki, ` stato nee cessario prelevarli direttamente dalla fonte, ovvero dal DataBase. Questo per` ha implicato la totale rinuncia a tutte le funzionalit` di modica e cono a divisione che vengono fornire dai vari componenti della piattaforma. E bene notare quindi che, seppure lapplicazione garantisce laccesso ai contenuti del portale scientico, questo viene eettuato in modalit` sola lettura. a A tale proposito si possono individuare alcune interessanti prospettive verso cui sviluppare ulteriormente questa applicazione: Tramite linserimento del supporto al middleware e gestendo adeguatamente laccesso al DataBase, potrebbe essere possibile aggiungere ad alcune delle funzionalit` XWiki che si appoggiano al DB; a Considerando le caratteristiche fortemente HTML-based del framework jQuery mobile, potrebbe essere possibile implementarlo direttamente allinterno di una skin di XWiki, in modo tale che linterazione tra le due tecnologie possa portare ad una comunque ottimale organizzazione dei contenuti. direttamente allinterno dellapp la creazione di contenuti e il supporto

Appendice - Codice completo


In questa appendice si riporta il codice completo di ogni componente creato nello sviluppo delapp HTML5 allinterno del capitolo 4.

Pagine del Client


index.jsp
Homepage dellapplicazione, da cui ` possibile accedere allelenco delle pube blicazioni, divise per tipologia.
1 2 3 4 5 <! DOCTYPE html > < html manifest = " cache . manifest " > < head > < title > Publications </ title > < meta name = " viewport " content = " width = device - width , initial scale =1.0 , maximum - scale =1.0 , minimum - scale =1.0 , user scalable = no " > 6 7 8 9 10 11 12 13 <! -- iPhone -- > < link rel = " apple - touch - startup - image " < meta name = " apple - mobile - web - app - capable " content = " yes " > < meta name = " apple - mobile - web - app - status - bar - style " content = " black " > < link rel = " apple - touch - icon - precomposed " sizes = " 72 x72 " href = " images / icon_72 . png " > < link rel = " apple - touch - icon - precomposed " sizes = " 114 x114 " href = " images / icon_114 . png " > < link rel = " apple - touch - icon - precomposed " href = " images / icon_57 . png " >

56
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 media = " ( device - width : 320 px ) "

Appendice - Codice completo

href = " images / splash_320x460 . png " > <! -- iPhone ( Retina ) -- > < link rel = " apple - touch - startup - image " media = " ( device - width : 320 px ) and ( - webkit - device pixel - ratio : 2) " href = " images / splash_640x920 . png " > <! -- iPad ( portrait ) -- > < link rel = " apple - touch - startup - image " media = " ( device - width : 768 px ) and ( orientation : portrait ) " href = " images / splash_768x1004 . png " > <! -- iPad ( landscape ) -- > < link rel = " apple - touch - startup - image " href = " images / splash_1024x748 . png " media = " screen and ( min - device - width : 481 px ) and ( max - device - width : 1024 px ) and ( orientation : landscape ) " / > <! -- iPad ( Retina , portrait ) -- > < link rel = " apple - touch - startup - image " media = " ( device - width : 768 px ) and ( orientation : portrait ) and ( - webkit - device - pixel - ratio : 2) " href = " images / splash_1536x2008 . png " > <! -- iPad ( Retina , landscape ) -- > < link rel = " apple - touch - startup - image " href = " images / splash_2048x1496 . png " media = " screen and ( min - device - width : 481 px ) and ( max - device - width : 1024 px ) and ( orientation : landscape ) and ( - webkit - min - device - pixel - ratio : 2) " / > < link rel = " stylesheet " href = " css / themes / default / jquery . mobile -1.2.0. css " / > < link rel = " stylesheet " href = " css / style . css " / > < script src = " js / jquery . js " > </ script > < script src = " js / jquery . mobile -1.2.0. js " > </ script > </ head > < body > < div data - role = " page " class = " pages " id = " home " >

Appendice - Codice completo


51 52 53 54 55 56 57 < div data - role = " content " > < h1 > Publications </ h1 > < div data - role = " header " data - position = " fixed " data - id = " head " id = " head " > < img src = " images / logo . png " > </ div > <! -- / header -- >

57

<p > Research and development work in APICe involves the use of a large amount of scientific publications , and produces a lot of original scientific materials . </ p >

58

<p > In order to help the many activities in APICe , a handy and precise representation of such a huge collection of pieces of scientific literature is certainly more than useful . </ p >

59

<p > This Publications space in the APICe space is meant to address such needs , by containing the scientific material considered relevant for the scientific and technical activities in APICe , either published directly by APICe people or by other researchers in the world . </ p >

60 61 62 63 64 65 66 67 68 69 70 71 72

< br > < br > < ul data - role = " listview " > < li > <a href = " PubsList ? type = all " data - transition = " slidefade " > All Publications </ a > </ li > < li > <a href = " PubsList ? type = articles " data - transition = " slidefade " > Journal Articles </ a > </ li > < li > <a href = " PubsList ? type = series " data - transition = " slidefade " > Series Articles </ a > </ li > < li > <a href = " PubsList ? type = papers " data - transition = " slidefade " > Conferences Paper </ a > </ li > < li > <a href = " PubsList ? type = books " data - transition = " slidefade " > Book Chapters </ a > </ li > < li > <a href = " PubsList ? type = edited " data - transition = " slidefade " > Edited Volumes </ a > </ li > </ ul > </ div > <! -- / content -- > < div data - role = " footer " data - position = " fixed " data - id = " foot " id = " foot " > < div data - role = " navbar " data - iconpos = " top " >

58
73 74 < ul >

Appendice - Codice completo

< li > <a href = " # " data - icon = " home " class = " ui - btn - active ui - state - persist " id = " bt_nav " > Publications </ a > </ li >

75 76 77 78 79 80 81 82 83 </ body > </ html >

< li > <a href = " indexes . jsp " data - icon = " grid " id = " bt_nav " data - transition = " slide " > Indexes </ a > </ li > < li > <a href = " search . jsp " data - icon = " search " id = " bt_nav " data - transition = " slide " > Search </ a > </ li > </ ul > </ div > <! -- / navbar -- > </ div > <! -- / footer -- > </ div > <! -- / page -- >

indexes.jsp
Pagina da cui si accede allelenco delle pubblicazioni, indicizzate per coautori, co-curatori, riviste & serie e tag.
1 2 3 4 5 <! DOCTYPE html > < html > < head > < title > Indexes </ title > < meta name = " viewport " content = " width = device - width , initial scale =1.0 , maximum - scale =1.0 , minimum - scale =1.0 , user scalable = no " > 6 7 8 9 10 11 12 13 < link rel = " stylesheet " href = " css / themes / default / jquery . mobile -1.2.0. css " / > < meta name = " apple - mobile - web - app - capable " content = " yes " > < meta name = " apple - mobile - web - app - status - bar - style " content = " black " > < link rel = " apple - touch - icon - precomposed " sizes = " 72 x72 " href = " images / icon_72 . png " > < link rel = " apple - touch - icon - precomposed " sizes = " 114 x114 " href = " images / icon_114 . png " > < link rel = " apple - touch - icon - precomposed " href = " images / icon_57 . png " >

Appendice - Codice completo


14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 < div data - role = " footer " data - position = " fixed " data - id = " foot " id = " foot " > < div data - role = " navbar " data - iconpos = " top " > < ul > < div data - role = " content " > < h1 align = " center " > Indexes </ h1 > < ul data - role = " listview " > < li > <a href = " Indexes ? type = authors " data - transition = " slidefade " > Authors </ a > </ li > < li > <a href = " Indexes ? type = editors " data - transition = " slidefade " > Editors </ a > </ li > < li > <a href = " Indexes ? type = js " data - transition = " slidefade " > Journals & Series </ a > </ li > < li > <a href = " Indexes ? type = tags " data - transition = " slidefade " > Tags </ a > </ li > </ ul > </ div > <! -- / content -- > < div data - role = " header " data - position = " fixed " data - id = " head " id = " head " > < img src = " images / logo . png " > </ div > <! -- / header -- > < link rel = " stylesheet " href = " css / style . css " / > < script src = " js / jquery . js " > </ script > < script src = " js / jquery . mobile -1.2.0. js " > </ script > </ head > < body > < div data - role = " page " class = " pages " id = " home " >

59

< li > <a href = " index . jsp " data - icon = " home " id = " bt_nav " data - transition = " slide " data - direction = " reverse " > Publications </ a > </ li >

39 40 41 42 43 44

< li > <a href = " # " data - icon = " grid " id = " bt_nav " class = " ui - btn - active ui - state - persist " > Indexes </ a > </ li > < li > <a href = " search . jsp " data - icon = " search " id = " bt_nav " data - transition = " slide " > Search </ a > </ li > </ ul > </ div > <! -- / navbar -- > </ div > <! -- / header -- >

60
45 46 47 48 49 </ div > <! -- / page -- > </ body > </ html >

Appendice - Codice completo

search.jsp
Contiene il form per eettuare la ricerca di una o pi` pubblicazioni in partiu colare.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 < div data - role = " content " > < h1 > Search </ h1 > < div data - role = " header " data - position = " fixed " data - id = " head " id = " head " > < img src = " images / logo . png " > </ div > <! -- / header -- > %> </ head > < body > < div data - role = " page " class = " pages " id = " home " > < link rel = " stylesheet " href = " css / themes / default / jquery . mobile -1.2.0. css " / > < link rel = " stylesheet " href = " css / style . css " / > < script src = " js / jquery . js " > </ script > < script src = " js / jquery . mobile -1.2.0. js " > </ script > <% @ page import = " java . util . Calendar " <! DOCTYPE html > < html > < head > < title > Search </ title > < meta name = " viewport " content = " width = device - width , initial scale =1 " > < meta name = " apple - mobile - web - app - capable " content = " yes " > < meta name = " apple - mobile - web - app - status - bar - style " content = " black " >

Appendice - Codice completo


26 27 28 29 30 31 32 33 34 <% < form name = " Search " action = " PubsList ? type = search " data - transition = " slidefade " > < input type = " search " name = " text " id = " text " / > < div id = " advanced - search " > < div data - role = " fieldcontain " > < select name = " year " id = " year " > < option value = " " > Year </ option >

61

int year = Calendar . getInstance () . get ( Calendar . YEAR ) ; for (; year > 1979; year - -) out . println ( " < option value =\ " " + year + " \ " >" + year + " </ option > " ) ;

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59

%> </ select > </ div > < div data - role = " fieldcontain " > < select name = " status " id = " status " > < option value = " " > Status </ option > < option value = " In press " > In press </ option > < option value = " Proof " > Proof </ option > < option value = " Camera - ready sent " > Camera - ready sent </ option > < option value = " Revised " > Revised </ option > < option value = " Accepted " > Accepted </ option > < option value = " Accepted with revision " > Accepted with revision </ option > < option value = " Rejected " > Rejected </ option > < option value = " Submitted " > Submitted </ option > < option value = " Draft " > Draft </ option > < option value = " Note " > Note </ option > </ select > </ div > </ div > < input type = " submit " value = " Search " data - theme = " a " data - icon = " search " / > </ form > </ div > <! -- / content -- >

62
60 61 62 63

Appendice - Codice completo


< div data - role = " footer " data - position = " fixed " data - id = " foot " id = " foot " > < div data - role = " navbar " data - iconpos = " top " > < ul > < li > <a href = " index . jsp " data - icon = " home " id = " bt_nav " data - transition = " slide " data - direction = " reverse " > Publications </ a > </ li >

64

< li > <a href = " indexes . jsp " data - icon = " grid " id = " bt_nav " data - transition = " slide " data - direction = " reverse " > Indexes </ a > </ li >

65 66 67 68 69 70 71 72 73 74 </ body > </ html >

< li > <a href = " # " data - icon = " search " id = " bt_nav " class = " ui - btn - active ui - state - persist " > Search </ a > </ li > </ ul > </ div > <! -- / navbar -- > </ div > <! -- / header -- > </ div > <! -- / page -- >

pubsfounded.jsp
Crea dinamicamente la lista delle pubblicazioni tramite lattributo results che gli viene passato dalle Servlets.
1 2 3 4 5 6 7 8 9 10 11 12 13 %> < head > < title > <% // impostazione del titolo della pagina in base al contenuto String pub_type = request . getParameter ( " type " ) ; String name = request . getParameter ( " name " ) ; <! DOCTYPE html > < html > <% @ page import = " java . io .* " import = " java . sql .* " import = " apice . ListItem "

Appendice - Codice completo


14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 %> </ title > } } } } else if ( pub_type . equals ( " tags " ) ) { if ( name == null ) { out . println ( " Tags Index " ) ; } else { out . println ( " Publications with tag : " + name ) ; }; } else if ( pub_type . equals ( " js " ) ) { if ( name == null ) { out . println ( " J & S Index " ) ; } else { out . println ( " Published in " + name ) ; } } else if ( pub_type . equals ( " editors " ) ) { if ( name == null ) { out . println ( " Editors Index " ) ; } else { String [] n = name . split ( " ," ) ; out . println ( " Edited by " + n [0]) ; if ( pub_type . equals ( " all " ) ) { out . println ( " All Publications " ) ; } else if ( pub_type . equals ( " articles " ) ) { out . println ( " Journal Articles " ) ; } else if ( pub_type . equals ( " series " ) ) { out . println ( " Series Articles " ) ; } else if ( pub_type . equals ( " papers " ) ) { out . println ( " Conferences Papers " ) ; } else if ( pub_type . equals ( " books " ) ) { out . println ( " Book Chapters " ) ; } else if ( pub_type . equals ( " edited " ) ) { out . println ( " Edited Volumes " ) ; } else if ( pub_type . equals ( " authors " ) ) { if ( name == null ) { out . println ( " Authors Index " ) ; } else { String [] n = name . split ( " ," ) ; out . println ( n [0] + " s Publications " ) ;

63

64
55 56 < meta charset = " ISO -8859 -1 " >

Appendice - Codice completo

< meta name = " viewport " content = " width = device - width , initial scale =1.0 , maximum - scale =1.0 , minimum - scale =1.0 , user scalable = no " >

57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

< meta name = " apple - mobile - web - app - capable " content = " yes " > < meta name = " apple - mobile - web - app - status - bar - style " content = " black " > < link rel = " stylesheet " href = " css / themes / default / jquery . mobile -1.2.0. css " / > < link rel = " stylesheet " href = " css / style . css " / > < script src = " js / jquery . js " > </ script > < script src = " js / jquery . mobile -1.2.0. js " > </ script > </ head > < body > < div data - role = " page " class = " pages " id = " home " > < div data - role = " header " data - position = " fixed " data - id = " head " id = " head " > <a href = " index . jsp " data - icon = " back " data - iconpos = " notext " data - rel = " back " id = " bt_back " > back </ a > < img src = " images / logo . png " > <a href = " index . jsp " data - icon = " home " data - iconpos = " notext " id = " bt_home " > home </ a > </ div > <! -- / header -- > < div data - role = " content " > < h1 > <% if ( pub_type . equals ( " all " ) ) { out . println ( " All Publications " ) ; } else if ( pub_type . equals ( " articles " ) ) { out . println ( " Journal Articles " ) ; } else if ( pub_type . equals ( " series " ) ) { out . println ( " Series Articles " ) ; } else if ( pub_type . equals ( " papers " ) ) { out . println ( " Conference Papers " ) ; } else if ( pub_type . equals ( " books " ) ) { out . println ( " Book Chapters " ) ; } else if ( pub_type . equals ( " edited " ) ) { out . println ( " Edited Volumes " ) ;

Appendice - Codice completo


89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 } if ( request . getAttribute ( " results " ) != null ) { results = ( ListItem []) request . getAttribute ( " results " ) ; %> </ h1 > < ul data - role = " listview " data - filter = " true " > <% ListItem [] results ; String from = " " ; if ( request . getAttribute ( " from " ) != null ) { from = ( String ) request . getAttribute ( " from " ) ; } } } } else if ( pub_type . equals ( " tags " ) ) { if ( name == null ) { out . println ( " Tags Index " ) ; } else { }; } else if ( pub_type . equals ( " js " ) ) { if ( name == null ) { out . println ( " Journal & Series Index " ) ; } else { } } else if ( pub_type . equals ( " editors " ) ) { if ( name == null ) { out . println ( " Editor s Index " ) ; } else { } else if ( pub_type . equals ( " authors " ) ) { if ( name == null ) { out . println ( " Author s Index " ) ; } else {

65

out . println ( " Publications by <b > " + name + " </b > " );

out . println ( " Publications edited by <b > " + name + " </b > " ) ;

out . println ( " Published in \ " <b >" + name + " \ " </b > ");

out . println ( " Publications with tag \ " <b >" + name + " \ " </b > " ) ;

66
125 126 127

Appendice - Codice completo


for ( int i = 0; i < results . length ; i ++) { if ( from . equals ( " Indexes " ) ) { out . println ( " <li > < a href =\ " PubsList ? type = " + pub_type + " & name = " + results [ i ]. getName () + " \ " ><h2 > " + results [ i ]. getName () + " </ h2 > < span class =\ " ui - li - count \ " >" + results [ i ]. getCount () + " </ span > </a > </ li > " ) ;

128 129

} else if ( from . equals ( " PubsList " ) ) { out . println ( " <li > < a href =\ " PubInfo ? id = " + results [ i ]. getId () + " & name = " + results [ i ]. getName () + " \ " class =\ " " + results [ i ]. getName () + " \ " ><h2 > " + results [ i ]. getTitle () + " </ h2 > <p > <b > " + results [ i ]. getYear () + " </b > " + results [ i ]. getAuthor () + " </p > </a > </ li > " ) ;

130 131 132 133 134 135 136 137 138 139 140 141 142 </ body > </ html > } %> </ ul > }

} } else { out . println ( " error - missing query results " ) ;

</ div > <! -- / content -- > </ div > <! -- / page -- >

publication.jsp
Ha il compito nale di costruire la pagina della pubblicazione.
1 2 3 4 5 6 7 8 %> <! DOCTYPE html > < html > <% @ page import = " java . io .* " import = " java . util . ArrayList " import = " java . util . LinkedHashMap " import = " apice . Publication "

Appendice - Codice completo


9 10 11 12 13 14 15 16 17 18 19 20 21 %> < head > < title > < %= pub . getName () % > </ title > < meta charset = " ISO -8859 -1 " > } <% Publication pub ;

67

if ( request . getAttribute ( " publication " ) != null ) { pub = ( Publication ) request . getAttribute ( " publication " ) ; } else { out . println ( " error - missing publication details " ) ; pub = new Publication () ;

< meta name = " viewport " content = " width = device - width , initial scale =1.0 , maximum - scale =1.0 , minimum - scale =1.0 , user scalable = no " >

22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

< meta name = " apple - mobile - web - app - capable " content = " yes " > < meta name = " apple - mobile - web - app - status - bar - style " content = " black " > < link rel = " stylesheet " mobile -1.2.0. css " / > < link rel = " stylesheet " href = " css / style . css " / > < script src = " js / jquery . js " > </ script > < script src = " js / jquery . mobile -1.2.0. js " > </ script > </ head > < body > < div data - role = " page " class = " pages " id = " home " > href = " css / themes / default / jquery .

< div data - role = " header " data - position = " fixed " data - id = " head " id = " head " > <a href = " indexes . html " data - icon = " back " data - iconpos = " notext " data - rel = " back " id = " bt_back " > back </ a > < img src = " images / logo . png " alt = " APICe " > <a href = " index . jsp " data - icon = " home " data - iconpos = " notext " id = " bt_home " > home </ a > </ div > <! -- / header -- > < div data - role = " content " >

68
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 %> < div class = " details " > < div class = " pub_details " > <% <% %> </ h2 > < hr > } <% String author = pub . getAuthor () ; String editor = pub . getEditor () ; if (! author . equals ( " " ) ) { < h1 > < %= pub . getTitle () % > </ h1 > < h2 class = " author " >

Appendice - Codice completo

author = author . replace ( " ," , " " ) ; author = author . replace ( " and " , " , " ) ; author = author . replace ( " AND " , " , " ) ; out . println ( author ) ; } else if ( editor != null ) { editor = editor . replace ( " ," , " " ) ; editor = editor . replace ( " and " , " , " ) ; editor = editor . replace ( " AND " , " , " ) ; out . println ( editor + " ( eds ) " ) ;

if (! pub . getAbstract () . equals ( " " ) ) out . println ( " <p > " + pub . getAbstract () + " </p > < hr > " ) ;

ArrayList < String > not_print = new ArrayList < String > () ; not_print . add ( " title " ) ; not_print . add ( " status " ) ; not_print . add ( " doi " ) ; not_print . add ( " url " ) ; not_print . add ( " issn " ) ; not_print . add ( " issn - online " ) ; not_print . add ( " isbn " ) ; not_print . add ( " pdf - local " ) ; not_print . add ( " url - pdf " ) ; LinkedHashMap < String , String > map = pub . getDetails () ; for ( String str : pub . getDetailsLabels () ) {

Appendice - Codice completo


80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 <% if ( pub . hasWEB () ) { out . println ( " < div class =\ " box \ " id =\ " web \ " >< div class =\ " titlebox \ " ><b > Web </ b > </ div > " ) ; </ div > %> </ div > < div id = " boxbar " > < div class = " box " id = " status " > < div class = " titlebox " > <b > Status </ b > </ div > < %= pub . getStatus () % > } } String value = map . get ( str ) ; if ( str . equals ( " editor " ) ) { value = value . replace ( " ," , " " ) ; value = value . replace ( " and " , " , " ) ; value = value . replace ( " AND " , " , " ) ;

69

if (! not_print . contains ( str ) ) out . println ( " <h4 > <b > " + str + " : </b > < br > " + value + " </ h4 > " ) ;

if ( pub . getDoi () != null ) out . println ( " DOI <a href =\ " http :// dx . doi . org / " + pub . getDoi () + " \ " target =\ " _blank \ " >" + pub . getDoi () + " </a > < br > " ) ;

102

if ( pub . getUrl () != null ) out . println ( " <a href =\ " " + pub . getUrl () + " \ " target =\ " _blank \ " > Publisher s Page </ a > " ) ; out . println ( " </ div > " ) ; } if ( pub . hasBiBlio () ) { out . println ( " < div class =\ " box \ " id =\ " biblio \ " >< div class =\ " titlebox \ " ><b > Biblio </ b > </ div > " ) ; if ( pub . getIssn () != null ) out . println ( " ISSN < br > " + pub . getIssn () + " <br > " ) ; if ( pub . getIssn_online () != null ) out . println ( " ISSN on - line < br > " + pub . getIssn_online () + " <br > " ) ; if ( pub . getIsbn () != null ) out . println ( " ISBN < br > " + pub . getIsbn () + " <br > " ) ;

103 104 105 106 107 108 109

70
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 < div class = " buttons " > <% if ( pub . hasPDF () ) { %> } if ( pub . hasBibTex () ) { out . println ( " </ div > " ) ;

Appendice - Codice completo

out . println ( " < div class =\ " box \ " id =\ " bibtex \ " >< div class =\ " titlebox \ " ><b > BibTeX </ b > </ div > " ) ; out . println ( " BibTeX ID < br > <i > " + pub . getUniID () + " </i > < br > " ) ; out . println ( " BibTeX Category < br > <i > " + pub . getCategory () + " </i > < br > " ) ; out . println ( " </ div > " ) ; }

pub . setUrlPDFlocal ( " http :// apice . unibo . it / xwiki / bin / download / Publications / " + pub . getName () + "/");

126

out . println ( " <a href =\ " " + pub . getPDF () + " \ " class =\ " pdf \ " target =\ " _blank \ " data - role =\ " button \ " data - inline =\ " true \ " id =\ " btn_img \ " > Download < img src =\ " images / pdf . png \ " alt =\ " PDF \ " id =\ " pdf_img \ " > </a > " ) ;

127 128 129 130 %>

<a href = " http ://137. 20 4. 10 7. 27 / xwiki / bin / view / Publications / <%= pub . getName () % > " class = " to_xwiki " target = " _blank " data - role = " button " data - inline = " true " id = " btn_img " > < div > Go to APICe < br > xWiki Page < / div > </ a >

131 132 133 134 135 136 137

</ div > </ div > </ div > < hr > <% if (! pub . getTags () . isEmpty () ) { out . println ( " < div id =\ " tags \ " ><b > Tags : </b > < br > " ) ;

Appendice - Codice completo


138 139 for ( String tag : pub . getTags () ) {

71

out . println ( " <a href =\ " PubsList ? type = tags & name = " + tag + " \ " class =\ " tag \ " data - role =\ " button \ " data - inline =\ " true \ " >" + tag + " </a > " ) ;

140 141 142 143 144 145 146 147 148 149 150 </ body > </ html > %>

} out . println ( " </ div > < hr > " ) ; }

</ div > <! -- / content -- > </ div > <! -- / page -- >

nofound.jsp
Pagina evocata nel caso in cui la query eettuata nel database risulti vuota.
1 2 3 4 5 6 <! DOCTYPE html > < html > < head > < title > Nothing Found </ title > < meta charset = " ISO -8859 -1 " > < meta name = " viewport " content = " width = device - width , initial scale =1.0 , maximum - scale =1.0 , minimum - scale =1.0 , user scalable = no " > 7 8 9 10 11 12 13 14 15 16 </ head > < body > < div data - role = " page " class = " pages " id = " home " > < meta name = " apple - mobile - web - app - capable " content = " yes " > < meta name = " apple - mobile - web - app - status - bar - style " content = " black " > < link rel = " stylesheet " href = " css / themes / default / jquery . mobile -1.2.0. css " / > < link rel = " stylesheet " href = " css / style . css " / > < script src = " js / jquery . js " > </ script > < script src = " js / jquery . mobile -1.2.0. js " > </ script >

72
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 </ body > </ html > </ div > <! -- / page -- > < div data - role = " content " > < div id = " not - found - message " >

Appendice - Codice completo


< div data - role = " header " data - position = " fixed " data - id = " head " id = " head " > <a href = " index . jsp " data - icon = " back " data - iconpos = " notext " data - rel = " back " id = " bt_back " > back </ a > < img src = " images / logo . png " > <a href = " index . jsp " data - icon = " home " data - iconpos = " notext " id = " bt_home " > home </ a > </ div > <! -- / header -- >

< img id = " notfound - img " src = " images / notfound . png " > < div id = " text - msg " > < h1 id = " message " > <b > Nothing Found </ b > </ h1 > < h1 id = " subs " > go back and refine your search </ h1 > </ div > </ div > </ div > <! -- / content -- >

oine.jsp
Viene caricata su indicazione del le manifest dellapp, nel caso in cui ci sia qualche risorsa non accessibile.
1 2 3 4 5 6 <! DOCTYPE html > < html > < head > < title > Offline </ title > < meta charset = " ISO -8859 -1 " > < meta name = " viewport " content = " width = device - width , initial scale =1.0 , maximum - scale =1.0 , minimum - scale =1.0 , user scalable = no " > 7 8 < meta name = " apple - mobile - web - app - capable " content = " yes " > < meta name = " apple - mobile - web - app - status - bar - style " content = " black " >

Appendice - Codice completo


9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 </ body > </ html > < div data - role = " content " > < div id = " not - found - message " > < img id = " notfound - img " src = " images / offline . png " > < div id = " text - msg " > < h1 id = " message " > <b > No Connection </ b > </ h1 > < h1 id = " subs " > check your settings </ h1 > </ div > </ div > </ div > <! -- / content -- > </ div > <! -- / page -- > </ head > < body > < div data - role = " page " class = " pages " id = " home " > < div data - role = " header " data - position = " fixed " data - id = " head " id = " head " > <a href = " index . jsp " data - icon = " back " data - iconpos = " notext " data - rel = " back " id = " bt_back " > back </ a > < img src = " images / logo . png " > <a href = " index . jsp " data - icon = " home " data - iconpos = " notext " id = " bt_home " > home </ a > </ div > <! -- / header -- > < link rel = " stylesheet " href = " css / themes / default / jquery . mobile -1.2.0. css " / > < link rel = " stylesheet " href = " css / style . css " / > < script src = " js / jquery . js " > </ script > < script src = " js / jquery . mobile -1.2.0. js " > </ script >

73

File .manifest per lApplication Cache


1 2 3 4 CACHE : CACHE MANIFEST # ver 10 -12 -12

74
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 FALLBACK : / offline . jsp images / logo . png images / notfound . png images / error . png images / offline . png images / pdf . png css / style . css js / jquery . js js / jquery . mobile -1.2.0. js index . jsp indexes . jsp search . jsp error . jsp nofound . jsp offline . jsp

Appendice - Codice completo

css / themes / default / jquery . mobile -1.2.0. css css / themes / default / images / ajax - loader . gif css / themes / default / images / icons -18 - black . png css / themes / default / images / icons -18 - white . png css / themes / default / images / icons -36 - black . png css / themes / default / images / icons -36 - white . png

Foglio di stile
1 2 3 4 5 6 7 8 9 10 } # head { height : 70 px ; } * { font - family : georgia , serif ;

Appendice - Codice completo


11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 # notfound - img { margin : 0 px auto ; display : block ; width : 200 px ; height : auto ; } # not - found - message { width : 300 px ; height : 200 px ; position : absolute ; left : 50%; top : 50%; margin : -100 px 0 0 -150 px ; } # bt_home { margin - top : 20%; margin - right : 5%; } # bt_back { margin - top : 20%; margin - left : 5%; } . ui - btn - active { background : #2 F6799 ; color : white ; } # head { background : #2 F6799 ; color : white ; } # head img { margin :0 px auto ; display : block ; width : auto ; height : 70 px ;

75

76
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 h2 . author { text - align : center ; } [ data - role = " content " ] h2 { font - size : small ; font - style : italic ; color : #5 B5B5B ; background - color : transparent ; } [ data - role = " content " ] h1 { text - align : center ; padding - top : 0 px ; margin - top : 0 px ; padding - bottom : 10 px ; font - size : large ; } # err - img { margin : 0 auto ; display : block ; } # err - msg { text - align : center ; } # subs { text - align : center ; font - size : medium ; color : #5 B5B5B ; } } # message { text - align : center ; font - size : xx - large ; padding : 0 px ; padding - bottom : 20 px ;

Appendice - Codice completo

Appendice - Codice completo


93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 . box { text - align : right ; text - shadow : none ; background : silver ; color : black ; padding - left :5 px ; } } # boxbar { width : 250 px ; margin :0 auto ; vertical - align : top ; display : inline - block ; . pub_details { width : 400 px ; margin :0 auto ; display : inline - block ; background : silver ; text - shadow : none ; padding : 10 px ; border - radius : 5 px ; } [ data - role = " content " ] h4 { font - size : smaller ; font - style : italic ; font - weight : normal ; color : black ; background - color : transparent ; } [ data - role = " content " ] h3 { font - size : medium ; font - weight : normal ; color : black ; background - color : transparent ; }

77

78
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 } # tags { text - align : center ; margin : 0 auto ; } [ data - role = " fieldcontain " ] { text - align : center ; } } # advanced - search { margin : 0 auto ; . buttons { margin : 0 auto ; max - width : 700 px ; text - align : center ; } . details { max - width : 700 px ; margin :0 auto ; } . box a { font - size : smaller ; } . titlebox { background : grey ; color : black ; margin - left : -5 px ; margin - right : -5 px ; padding - right :5 px ; } padding - right :5 px ; margin : 10 px 5 px ; width : 250 px ; display : inline - block ;

Appendice - Codice completo

Appendice - Codice completo


175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 } # boxbar { width : 270 px ; display : block ; } . pub_details { min - width : 250 px ; width : auto ; display : block ; /* iPhone [ portrait + landscape ] */ @media only screen and ( max - device - width : 480 px ) { } } /* iPad [ portrait + landscape ] */ @media only screen and ( min - device - width : 768 px ) and ( max device - width : 1024 px ) { # head , # head img { height : 90 px ; } # ext_img { width : 25 px ; } # pdf_img { width : 50 px ; } # btn_img { width : 170 px ; height : 65 px ; vertical - align : middle ; # btn_img img { vertical - align : middle ; }

79

80
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 } } # subs { font - size : small ; } # message { font - size : large ; } # text - msg { height : 50 px ; position : absolute ; display : inline - block ; margin - top : -150 px ; margin - left : 120 px ; } # notfound - img { height : 180 px ; width : auto ; margin - left : -80 px ; margin - top : 40 px ; display : inline ; } # not - found - message { width : 350 px ; height : 200 px ; /* iPhone [ landscape ] */ } } . box { display : block ;

Appendice - Codice completo

@media only screen and ( max - device - width : 480 px ) and ( orientation : landscape ) {

Appendice - Codice completo

81

Servlets
PubsList
Ha il compito di ricercare le informazioni base di ogni pubblicazione (titolo, anno e autori) per creare lelenco dinamico allinterno della pagina pubsfounded.jsp.
1 2 3 4 5 6 7 8 9 10 11 12 13 public void doGet ( H tt 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 ServletException , IOException { 14 15 16 17 18 19 20 21 22 23 24 25 select = " O . XWO_ID as ID , O . XWO_NAME as NAME , S . XWS_VALUE as TITLE , L . XWL_VALUE as YEAR , LS . XWL_VALUE as AUTHOR " ; 26 27 28 from = " xwikistrings as S , xwikilongs as L , xwikilargestrin gs as LS , xwikiobjects as O " ; String type = request . getParameter ( " type " ) ; if ( type . equals ( " all " ) ) { String jspPage = " " ; String select = " " ; String from = " " ; String condition = " " ; String join = " " ; public class PubsList extends HttpServlet { import java . io .*; import java . sql .*; import javax . naming . Context ; import javax . naming . InitialContext ; import javax . sql . DataSource ; import javax . servlet .*; import javax . servlet . http .*; import apice . ListItem ;

82
29

Appendice - Codice completo


condition = " S . XWS_NAME = title and L . XWL_NAME = year and LS . XWL_NAME = author and O . XWO_CLASSNAME = Publications . PublicationClass and O . XWO_NAME <> P u b l i c a t i o n C l a s s T e m p l a t e " ;

30 31 32 33 34 35 36 select = " O . XWO_ID as ID , O . XWO_NAME as NAME , S . XWS_VALUE as TITLE , L . XWL_VALUE as YEAR , LS . XWL_VALUE as AUTHOR " ; 37 38 from = " xwikistrings as S , xwikistrings as S1 , xwikistrings as S2 , xwikilongs as L , xwikilargestrings as LS , xwikiobjects as O " ; 39 40 condition = " O . XWO_NAME <> P u b l i c a t i o n C l a s s T e m p l a t e and S . XWS_NAME = title and S1 . XWS_NAME = journal and S1 . XWS_VALUE <> and S2 . XWS_NAME = status and S2 . XWS_VALUE = Published and L . XWL_NAME = year and LS . XWL_NAME = author and O . XWO_CLASSNAME = Publications . PublicationClass " ; 41 42 join = " S . XWS_ID = O . XWO_ID and S1 . XWS_ID = O . XWO_ID and S2 . XWS_ID = O . XWO_ID and L . XWL_ID = O . XWO_ID and LS . XWL_ID = O . XWO_ID " ; 43 44 45 46 47 select = " O . XWO_ID as ID , O . XWO_NAME as NAME , S . XWS_VALUE as TITLE , L . XWL_VALUE as YEAR , LS . XWL_VALUE as AUTHOR " ; 48 49 from = " xwikistrings as S , xwikistrings as S1 , xwikistrings as S2 , xwikilongs as L , xwikilargestrings as LS , xwikiobjects as O " ; 50 } else if ( type . equals ( " series " ) ) { } else if ( type . equals ( " articles " ) ) { join = " S . XWS_ID = O . XWO_ID and L . XWL_ID = O . XWO_ID and LS . XWL_ID = O . XWO_ID " ;

Appendice - Codice completo


51 condition = " O . XWO_NAME <> P u b l i c a t i o n C l a s s T e m p l a t e

83

and S . XWS_NAME = title and S1 . XWS_NAME = series and S1 . XWS_VALUE <> and S2 . XWS_NAME = status and S2 . XWS_VALUE = Published and L . XWL_NAME = year and LS . XWL_NAME = author and O . XWO_CLASSNAME = Publications . PublicationClass " ; 52 53 join = " S . XWS_ID = O . XWO_ID and S1 . XWS_ID = O . XWO_ID and S2 . XWS_ID = O . XWO_ID and L . XWL_ID = O . XWO_ID and LS . XWL_ID = O . XWO_ID " ; 54 55 56 57 58 select = " O . XWO_ID as ID , O . XWO_NAME as NAME , S . XWS_VALUE as TITLE , L . XWL_VALUE as YEAR , LS . XWL_VALUE as AUTHOR " ; 59 60 from = " xwikistrings as S , xwikistrings as S1 , xwikistrings as S2 , xwikilongs as L , xwikilargestrin gs as LS , xwikiobjects as O " ; 61 62 condition = " O . XWO_NAME <> P u b l i c a t i o n C l a s s T e m p l a t e and S . XWS_NAME = title and S1 . XWS_NAME = category and S1 . XWS_VALUE = inproceedings and S2 . XWS_NAME = status and S2 . XWS_VALUE = Published and L . XWL_NAME = year and LS . XWL_NAME = author and O . XWO_CLASSNAME = Publications . PublicationClass " ; 63 64 join = " S . XWS_ID = O . XWO_ID and S1 . XWS_ID = O . XWO_ID and S2 . XWS_ID = O . XWO_ID and L . XWL_ID = O . XWO_ID and LS . XWL_ID = O . XWO_ID " ; 65 66 67 68 69 select = " O . XWO_ID as ID , O . XWO_NAME as NAME , S . XWS_VALUE as TITLE , L . XWL_VALUE as YEAR , LS . XWL_VALUE as AUTHOR " ; 70 71 from = " xwikistrings as S , xwikistrings as S1 , } else if ( type . equals ( " books " ) ) { } else if ( type . equals ( " papers " ) ) {

84

Appendice - Codice completo


xwikistrings as S2 , xwikistrings as S3 , xwikilongs as L , xwikilargestri ngs as LS , xwikiobjects as O " ;

72 73

condition = " O . XWO_NAME <> P u b l i c a t i o n C l a s s T e m p l a t e and S . XWS_NAME = title and S1 . XWS_NAME = booktitle and S1 . XWS_VALUE <> and S2 . XWS_NAME = status and S2 . XWS_VALUE = Published and S3 . XWS_NAME = category and S3 . XWS_VALUE <> book and S3 . XWS_VALUE like % proceedings % and L . XWL_NAME = year and LS . XWL_NAME = author and O . XWO_CLASSNAME = Publications . PublicationClass " ;

74 75 join = " S . XWS_ID = O . XWO_ID and S1 . XWS_ID = O . XWO_ID and S2 . XWS_ID = O . XWO_ID and S3 . XWS_ID = O . XWO_ID and L . XWL_ID = O . XWO_ID and LS . XWL_ID = O . XWO_ID " ; 76 77 78 79 80 select = " O . XWO_ID as ID , O . XWO_NAME as NAME , S . XWS_VALUE as TITLE , L . XWL_VALUE as YEAR , S1 . XWS_VALUE as AUTHOR " ; 81 82 from = " xwikistrings as S , xwikistrings as S1 , xwikistrings as S2 , xwikilongs as L , xwikilargestrings as LS , xwikiobjects as O " ; 83 84 condition = " O . XWO_NAME <> P u b l i c a t i o n C l a s s T e m p l a t e and S . XWS_NAME = title and S1 . XWS_NAME = editor and S1 . XWS_VALUE <> and S2 . XWS_NAME = status and S2 . XWS_VALUE = Published and L . XWL_NAME = year and LS . XWL_NAME = author and LS . XWL_VALUE = and O . XWO_CLASSNAME = Publications . PublicationClass " ; 85 86 join = " S . XWS_ID = O . XWO_ID and S1 . XWS_ID = O . XWO_ID and S2 . XWS_ID = O . XWO_ID and L . XWL_ID = O . XWO_ID and LS . XWL_ID = O . XWO_ID " ; 87 88 89 } else if ( type . equals ( " search " ) ) { } else if ( type . equals ( " edited " ) ) {

Appendice - Codice completo


90 91 92 93 94 String text = request . getParameter ( " text " ) ; String year = request . getParameter ( " year " ) ; String status = request . getParameter ( " status " ) ;

85

select = " distinct O . XWO_ID as ID , O . XWO_NAME as NAME , S . XWS_VALUE as TITLE , L . XWL_VALUE as YEAR , LS . XWL_VALUE as AUTHOR " ;

95 96 from = " xwikistrings as S , xwikistrings as S1 , xwikilongs as L , xwiki larges trings as LS , xwikilargestrin gs as LS1 , xwikiobjects as O " ; 97 98 condition = " O . XWO_NAME <> P u b l i c a t i o n C l a s s T e m p l a t e and S . XWS_NAME = title and S1 . XWS_NAME = status and S1 . XWS_VALUE like % " + status + " and L . XWL_NAME = year and L . XWL_VALUE like % " + year + " and LS . XWL_NAME = author and LS1 . XWL_VALUE like % " + text + " % and O . XWO_CLASSNAME = Publications . PublicationClass " ; 99 100 join = " S . XWS_ID = O . XWO_ID and S1 . XWS_ID = O . XWO_ID and L . XWL_ID = O . XWO_ID and LS . XWL_ID = O . XWO_ID and LS1 . XWL_ID = O . XWO_ID " ; 101 102 103 104 105 106 String name = request . getParameter ( " name " ) ; select = " O . XWO_ID as ID , O . XWO_NAME as NAME , S . XWS_VALUE as TITLE , L . XWL_VALUE as YEAR , LS . XWL_VALUE as AUTHOR " ; 107 108 109 110 condition = " S . XWS_NAME = title and L . XWL_NAME = year and LS . XWL_NAME = author and O . XWO_CLASSNAME = Publications . PublicationClass and O . XWO_NAME <> P u b l i c a t i o n C l a s s T e m p l a t e and LS . XWL_VALUE like \"% " + name + " %\" " ; 111 from = " xwikistrings as S , xwikilongs as L , xwikilargestrin gs as LS , xwikiobjects as O " ; } else if ( type . equals ( " authors " ) ) {

86
112 113 114 115 116 117 118

Appendice - Codice completo


join = " S . XWS_ID = O . XWO_ID and L . XWL_ID = O . XWO_ID and LS . XWL_ID = O . XWO_ID " ; } else if ( type . equals ( " editors " ) ) { String name = request . getParameter ( " name " ) ; select = " O . XWO_ID as ID , O . XWO_NAME as NAME , S . XWS_VALUE as TITLE , L . XWL_VALUE as YEAR , LS . XWL_VALUE as AUTHOR " ;

119 120 from = " xwikistrings as S , xwikistrings as S1 , xwikilongs as L , xwiki larges trings as LS , xwikiobjects as O " ; 121 122 condition = " S . XWS_NAME = title and L . XWL_NAME = year and LS . XWL_NAME = author and O . XWO_CLASSNAME = Publications . PublicationClass and O . XWO_NAME <> P u b l i c a t i o n C l a s s T e m p l a t e and S1 . XWS_NAME = editor and S1 . XWS_VALUE like \"% " + name + " %\" " ; 123 124 125 126 127 128 129 130 String name = request . getParameter ( " name " ) ; select = " O . XWO_ID as ID , O . XWO_NAME as NAME , S . XWS_VALUE as TITLE , L . XWL_VALUE as YEAR , LS . XWL_VALUE as AUTHOR " ; 131 132 from = " xwikistrings as S , xwikistrings as S1 , xwikilongs as L , xwiki larges trings as LS , xwikiobjects as O " ; 133 134 condition = " S . XWS_NAME = title and L . XWL_NAME = year and LS . XWL_NAME = author and O . XWO_CLASSNAME = Publications . PublicationClass and O . XWO_NAME <> P u b l i c a t i o n C l a s s T e m p l a t e and ( S1 . XWS_NAME = journal or S1 . XWS_NAME = series ) and S1 . XWS_VALUE } else if ( type . equals ( " js " ) ) { join = " S . XWS_ID = O . XWO_ID and S1 . XWS_ID = O . XWO_ID and L . XWL_ID = O . XWO_ID and LS . XWL_ID = O . XWO_ID " ;

Appendice - Codice completo


like \"% " + name + " %\" " ; 135 136 137 138 139 140 141 142 String name = request . getParameter ( " name " ) ; } else if ( type . equals ( " tags " ) ) { join = " S . XWS_ID = O . XWO_ID and S1 . XWS_ID = O . XWO_ID and L . XWL_ID = O . XWO_ID and LS . XWL_ID = O . XWO_ID " ;

87

select = " distinct O . XWO_ID as ID , O . XWO_NAME as NAME , S . XWS_VALUE as TITLE , L . XWL_VALUE as YEAR , LS . XWL_VALUE as AUTHOR " ;

143 144 from = " xwikistrings as S , xwikistrings as S1 , xwikilongs as L , xwiki larges trings as LS , xwikiobjects as O , xwikiobjects as T , xwikilistitems as I " ; 145 146 condition = " S . XWS_NAME = title and L . XWL_NAME = year and LS . XWL_NAME = author and O . XWO_CLASSNAME = Publications . PublicationClass and O . XWO_NAME <> P u b l i c a t i o n C l a s s T e m p l a t e and T . XWO_CLASSNAME = XWiki . TagClass and I . XWL_NAME = tags and I . XWL_VALUE like \"% " + name + " %\" " ; 147 148 join = " S . XWS_ID = O . XWO_ID and S1 . XWS_ID = O . XWO_ID and L . XWL_ID = O . XWO_ID and LS . XWL_ID = O . XWO_ID and O . XWO_NAME = T . XWO_NAME and I . XWL_ID = T . XWO_ID " ; 149 150 151 152 153 154 155 156 157 158 159 160 } try { if (! select . equals ( " " ) ) { InitialContext initCtx = new InitialContext () ; DataSource dataSource = ( DataSource ) initCtx . lookup ( " java : comp / env / jdbc / ApiceHTML5 " ) ; Connection dbconn ; ResultSet results ; PreparedStatemen t sql ; Class . forName ( " org . gjt . mm . mysql . Driver " ) ; try { dbconn = dataSource . getConnection () ;

88
161

Appendice - Codice completo


sql = dbconn . prepareStatement ( " select " + select + " from " + from + " where " + condition + " and " + join + " order by YEAR desc ; " ) ; results = sql . executeQuery () ; if ( results . next () ) { results . last () ; int size = results . getRow () ; int i = 0; ListItem [] res = new ListItem [ size ]; results . beforeFirst () ; String id = " " ; String name = " " ; String title = " " ; String year = " " ; String author = " " ; while ( results . next () ) { id = results . getString ( " ID " ) ; name = results . getString ( " NAME " ) ; name = name . replace ( " Publications . " , " " ) ; title = results . getString ( " TITLE " ) ; if ( results . getString ( " YEAR " ) == null ) { year = " " ; } else { year = results . getString ( " YEAR " ) ; } author = results . getString ( " AUTHOR " ) ; author = author . replace ( " ," , " " ) ; author = author . replace ( " and " , " , " ) ; author = author . replace ( " AND " , " , " ) ; if ( type . equals ( " edited " ) ) author = author + " ( eds ) " ;

162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198

// impostazione parametri da passare res [ i ] = new ListItem () ; res [ i ]. setId ( id ) ;

Appendice - Codice completo


199 200 201 202 203 204 205 206 207 i ++; } dbconn . close () ; if ( type . equals ( " authors " ) || type . equals ( " res [ i ]. setName ( name ) ; res [ i ]. setTitle ( title ) ; res [ i ]. setYear ( year ) ; res [ i ]. setAuthor ( author ) ;

89

editors " ) || type . equals ( " js " ) || type . equals ( " tags " ) ) { 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 } } } } catch ( Exception err ) { request . setAttribute ( " error " , err ) ; jspPage = " / error . jsp " ; } request . setAttribute ( " from " , " PubsList " ) ; RequestDispatcher req uestDi spatch er = get Servle tConte xt () . g e t R e q u e s t D i s p a t c h e r ( jspPage ) ; requestDispatcher . forward ( request , response ) ; } } } catch ( SQLException s ) { request . setAttribute ( " error " , s ) ; jspPage = " / error . jsp " ; } request . setAttribute ( " results " , res ) ; jspPage = " / pubsfounded . jsp ? type = " + type ; } else { jspPage = " / nofound . jsp " ; request . setAttribute ( " name " , name ) ;

Indexes
Interroga il database per indicizzare le pubblicazioni, tenendo anche il conto di quante pubblicazioni ci siano per ogni elemento di un indice. Viene caricata

90

Appendice - Codice completo

su indicazione del le manifest dellapp, nel caso in cui ci sia qualche risorsa non accessibile.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public void doGet ( H tt pS er vl et Re qu es t request , Ht tp S e rv l e tR e s po n s e response ) throws ServletException , IOException { 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 condition = " LS . XWL_NAME = author and LS . XWL_VALUE <> and O . XWO_CLASSNAME = Publications . PublicationClass " ; 32 33 34 35 } else if ( type . equals ( " editors " ) ) { join = " LS . XWL_ID = O . XWO_ID " ; select = " LS . XWL_VALUE as NAMES " ; from = " xwikilargestri ngs as LS , xwikiobjects as O " ; if ( type . equals ( " authors " ) ) { String type = request . getParameter ( " type " ) ; String select = " " ; String from = " " ; String condition = " " ; String join = " " ; public class Indexes extends HttpServlet { import java . io .*; import java . sql .*; import java . util . ArrayList ; import java . util . LinkedHashMap ; import java . util . Collections ; import javax . naming . Context ; import javax . naming . InitialContext ; import javax . sql . DataSource ; import javax . servlet .*; import javax . servlet . http .*; import apice . ListItem ;

Appendice - Codice completo


36 37 38 39 40 41 condition = " S . XWS_NAME = editor and S . XWS_VALUE <> and O . XWO_CLASSNAME = Publications . PublicationClass " ; 42 43 44 45 46 47 48 49 50 51 from = " xwikistrings as S , xwikiobjects as O " ; select = " S . XWS_VALUE as NAME , count (*) as NUM " ; } else if ( type . equals ( " js " ) ) { join = " S . XWS_ID = O . XWO_ID " ; select = " S . XWS_VALUE as NAMES " ; from = " xwikistrings as S , xwikiobjects as O " ;

91

condition = " ( S . XWS_NAME = journal or S . XWS_NAME = series ) and S . XWS_VALUE <> and O . XWO_CLASSNAME = Publications . PublicationClass group by S . XWS_VALUE order by S . XWS_VALUE " ;

52 53 54 55 56 57 58 59 60 61 condition = " P . XWO_CLASSNAME = Publications . PublicationClass and T . XWO_CLASSNAME = XWiki . TagClass and L . XWL_NAME = tags group by L . XWL_VALUE " ; 62 63 64 65 66 if (! select . equals ( " " ) ) { } join = " P . XWO_NAME = T . XWO_NAME and L . XWL_ID = T . XWO_ID "; select = " L . XWL_VALUE as NAME , count (*) as NUM " ; from = " xwikiobjects as P , xwikiobjects as T , xwikilistitems as L " ; } else if ( type . equals ( " tags " ) ) { join = " S . XWS_ID = O . XWO_ID " ;

92
67 68 69 70 71 72 73 74 75 76 77 78 79 String jspPage = " " ; String query = " " ;

Appendice - Codice completo

try { InitialContext initCtx = new InitialContext () ; DataSource dataSource = ( DataSource ) initCtx . lookup ( " java : comp / env / jdbc / ApiceHTML5 " ) ; Connection dbconn ; ResultSet results ; PreparedStatement sql ; Class . forName ( " org . gjt . mm . mysql . Driver " ) ; // Class . forName (" com . mysql . jdbc . Driver ") ; try { dbconn = dataSource . getConnection () ; sql = dbconn . prepareStatement ( " select " + select + " from " + from + " where " + join + " and " + condition + " ; " ) ;

80 81 82 83 84 85 86 87 88 89 90 91 92 93

results = sql . executeQuery () ; ArrayList < String > List = new ArrayList < String >() ; // oggetto per tenere conto del numero di occorrenze di un autore / editore LinkedHashMap < String , Integer > map = new LinkedHashMap < String , Integer >() ; int i = 0; if ( results . next () ) { results . beforeFirst () ; while ( results . next () ) { if ( type . equals ( " authors " ) || type . equals ( " editors " ) ) { String names = results . getString ( " NAMES " ) ; String [] n = names . split ( " ( and | AND ) " ) ; for ( i = 0; i < n . length ; i ++) { n [ i ] = n [ i ]. trim () ; // toglie gli spazi all inizio o alla fine Integer count = map . get ( n [ i ]) ; // count indica il numero di volte che abbiamo incontrato l autore

94 95 96

if ( count == null ) { map . put ( n [ i ] , 1) ; // se e la prima volta lo inseriamo nella LinkedHashMap con valore 1

Appendice - Codice completo


97 98 } else { map . put ( n [ i ] , ++ count ) ; // altrimenti incrementiamo il conteggio 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 } } if ( type . equals ( " authors " ) || type . equals ( " editors " ) ) { Collections . sort ( List ) ; String [] names = ( String []) List . toArray ( new String [ List . size () ]) ; ListItem [] res = new ListItem [ List . size () ]; for ( i = 0; i < res . length ; i ++) { res [ i ] = new ListItem () ; res [ i ]. setName ( names [ i ]) ; } } else if ( type . equals ( " js " ) || type . equals ( " tags " ) ) { String name = results . getString ( " NAME " ) ; String count = results . getString ( " NUM " ) ; List . add ( name + " ~ " + count ) ; } } if (! List . contains ( n [ i ]) ) { List . add ( n [ i ]) ;

93

res [ i ]. setCount ( map . get ( names [ i ]) ) ; // con map . get ( res [ i ]) ci restituisce il valore del contatore che corrisponde alla stringa in res [ i ]

118 119 120 121 122 123 124 125 126

} request . setAttribute ( " results " , res ) ; } else if ( type . equals ( " js " ) || type . equals ( " tags ")){ String [] ls = ( String []) List . toArray ( new String [ List . size () ]) ; ListItem [] res = new ListItem [ List . size () ]; for ( i = 0; i < res . length ; i ++) { // divido la stringa in due , con ; // il primo elemento e il nome , il secondo il conteggio String [] el = ls [ i ]. split ( " ~ " ) ;

94
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 } } } } } } catch ( Exception err ) { } dbconn . close () ; } catch ( SQLException s ) { } }

Appendice - Codice completo


res [ i ] = new ListItem () ; res [ i ]. setName ( el [0]) ; res [ i ]. setCount ( Integer . parseInt ( el [1]) ) ; request . setAttribute ( " results " , res ) ; jspPage = " / pubsfounded . jsp ? type = " + type ; } else { jspPage = " / nofound . jsp " ;

request . setAttribute ( " error " , s ) ; jspPage = " / error . jsp " ;

request . setAttribute ( " error " , err ) ; jspPage = " / error . jsp " ; request . setAttribute ( " from " , " Indexes " ) ; RequestDispatcher req uestDi spatch er = get Servle tConte xt () . g e t R e q u e s t D i s p a t c h e r ( jspPage ) ; requestDispatcher . forward ( request , response ) ;

PubInfo
Ha il compito ultimo di ricercare tutte le informazioni disponibili per una particolare pubblicazione che verranno poi passate alla pagina Viene caricata su indicazione del le manifest dellapp, nel caso in cui ci sia qualche risorsa non accessibile.
1 2 3 4 import java . io .*; import java . sql .*; import java . util . ArrayList ; import java . util . LinkedHashMap ;

Appendice - Codice completo


5 6 7 8 9 10 11 12 13 14 15 16 17 public void doGet ( H tt 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 ServletException , IOException { 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 from = " xwikilongs as L , xw ikilar gestri ngs as LS , xwikilargestrin gs as LS1 " ; select = " LS . XWL_VALUE as AUTHOR , LS1 . XWL_VALUE as ABSTRACT , L . XWL_VALUE as YEAR " ; Publication pub = new Publication ( id , request . getParameter ( " name " ) ) ; String id = request . getParameter ( " id " ) ; String jspPage = " / error . jsp " ; String select = " " ; String from = " " ; String condition = " " ; String join = " " ; public class PubInfo extends HttpServlet { import java . util . Collections ; import javax . naming . Context ; import javax . naming . InitialContext ; import javax . sql . DataSource ; import javax . servlet .*; import javax . servlet . http .*; import apice . Publication ;

95

condition = " L . XWL_ID = " + id + " and L . XWL_NAME = year and LS . XWL_NAME = author and LS1 . XWL_NAME = abstract " ;

36 37 join = " LS . XWL_ID = L . XWL_ID and LS1 . XWL_ID = L . XWL_ID " ;

96
38 39 40 41 42 43 44 45 46 47 48 49 try {

Appendice - Codice completo

InitialContext initCtx = new InitialContext () ; DataSource dataSource = ( DataSource ) initCtx . lookup ( " java : comp / env / jdbc / ApiceHTML5 " ) ; Connection dbconn ; ResultSet results ; PreparedStatement sql ; Class . forName ( " org . gjt . mm . mysql . Driver " ) ; // Class . forName (" com . mysql . jdbc . Driver ") ; try { dbconn = dataSource . getConnection () ; sql = dbconn . prepareStatement ( " select " + select + " from " + from + " where " + join + " and " + condition + " ; " ) ;

50 51 52 53 54 55 56 57 58 59

results = sql . executeQuery () ; if ( results . next () ) { results . beforeFirst () ; while ( results . next () ) { pub . setAuthor ( results . getString ( " AUTHOR " ) ) ; pub . setAbstract ( results . getString ( " ABSTRACT " ) ) ; pub . setYear ( results . getString ( " YEAR " ) ) ; } sql = dbconn . prepareStatement ( " select XWS_NAME as NAME , XWS_VALUE as VALUE from xwikistrings where XWS_ID = " + id + " and XWS_VALUE <> ; " ) ;

60 61 62 63 64 65 66 67 68 69

results = sql . executeQuery () ; while ( results . next () ) { pub . addDetails ( results . getString ( " NAME " ) , results . getString ( " VALUE " ) ) ; } select = " I . XWL_VALUE as VALUE " ; from = " xwikiobjects as T , xwikilistitems as I " ; condition = " T . XWO_NAME = Publications . " + pub . getName () + " and T . XWO_CLASSNAME = XWiki . TagClass and I . XWL_NAME = tags " ;

70

Appendice - Codice completo


71 72 73 join = " I . XWL_ID = T . XWO_ID " ;

97

sql = dbconn . prepareStatement ( " select " + select + " from " + from + " where " + join + " and " + condition + " ; " ) ; results = sql . executeQuery () ; while ( results . next () ) { pub . addTag ( results . getString ( " VALUE " ) ) ; } request . setAttribute ( " publication " , pub ) ; jspPage = " / publication . jsp " ; } else { jspPage = " / nofound . jsp " ; } dbconn . close () ; } catch ( SQLException s ) { request . setAttribute ( " error " , s ) ; jspPage = " / error . jsp " ; } } catch ( Exception err ) { request . setAttribute ( " error " , err ) ; jspPage = " / error . jsp " ; } RequestDispatcher req uestDi spatch er = get Servle tConte xt () . g e t R e q u e s t D i s p a t c h e r ( jspPage ) ; requestDispatcher . forward ( request , response ) ;

74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 } }

Bibliograa
[1] HTML 5 Specication, http://www.w3.org/TR/html5/; [2] Introduction to CSS3, http://www.w3.org/TR/2001/WD-css3-roadmap-20010523/; [3] Javascript APIs, http://www.w3.org/TR/#tr Javascript APIs; [4] WHY HTML5 ROCKS, http://www.html5rocks.com/en/why; [5] XWiki Documentation, http://www.xwiki.org/xwiki/bin/view/Main/Documentation; [6] XWiki Architecture, http://platform.xwiki.org/xwiki/bin/view/DevGuide/Architecture; [7] Mary Meeker (2012), Internet Trends, Standford BASES; http://kpcb.com/insights/2012-internet-trends-update [8] Jakob Nielsen (2012), Mobile Site vs. Full Site, http://www.useit.com/alertbox/mobile-vs-full-sites.html; [9] jQuery Mobile: Demo and Documentation, http://jquerymobile.com/demos/1.2.0/; [10] Apache Tomcat Documentation, http://tomcat.apache.org/tomcat-6.0-doc/index.html;

Ringraziamenti
Bene. Siamo arrivati dunque alla parte pi` importante e signicativa della u tesi, probabilmente anche alla pi` di cile per me da scrivere (e vi assicuro u che le pagine precedenti non sono state aatto facili). Cercher` comunque di o fare del mio meglio, sperando di non dimenticare nessuno... Grazie alla Cate, per limmensa pazienza dimostrata nellaiutarmi a scrivere questa tesi e per essermi accanto in ogni momento, sempre pronta (o quasi) ad assorbire tutti i miei sfoghi. Grazie ai miei genitori, per non avermi mai fatto mancare niente e per avermi permesso di arrivare no a questo punto. Grazie ai miei nonni, per avermi supportato ed aiutato in qualsiasi occasione, senza farmi mai sentire solo. Grazie al Prof. Omicini, per la Sua inesauribile disponibilit` e per la Sua a simpatia e grazie anche a Nazzareno Pompei, senza il cui aiuto non sarei mai riuscito ad avere la meglio su XWiki. :) Grazie ai miei compagni di avventura: Ste (che in questa tesi ` anche il mio e Correlatore, doppi ringraziamenti per lui!), Busca, Campo (ma se tu fossi la corrente, da che parte andresti?), Piero e Richard per aver reso divertenti e piacevoli tutti i giorni passati allUniversit`, senza di voi ingegneria sarebbe a stata un vero incubo! Grazie ad Ale, Cianca, Gaia, Giova, Harry, Mike e Pira, i fratelli che non ho mai avuto, per tutti i momenti memorabili vissuti assieme e per avermi insegnato a ridere di cuore anche nelle situazioni pi` di cili. u

Grazie a tutto il Wuber: Sacco, Johnny, Ross, Zatto, Mela, Naccio, David, Dulo, Riccio, Mazzo, Masi, Edo, Greggione, Coach Ca strarmi. Grazie a quel bellissimo pot-pourri di pelo che ` la Birba, per i suoi bu e miagolii quando vede un piccione e per avermi insegnato che laetto incondizionato ` una cosa meravigliosa, anche se ` un animalino a dartelo. e e e Capitan Cangini, perch certe volte giocare assieme a voi era lunico modo per riuscire a die