Realizzazione di un software in ambiente web per la
Transcript
Realizzazione di un software in ambiente web per la
Università degli Studi di Napoli Federico II Facoltà di Scienze MM.FF.NN. Corso di Laurea in Informatica Tesi sperimentale di Laurea Triennale Realizzazione di un software in ambiente web per la gestione delle presenze di un corso di formazione Relatori Candidato Prof. Guido Russo Dott.ssa Vania Boccia Gargiulo Marco matr. 566/1465 Anno Accademico 2011-2012 Indice generale Premessa......................................................................................................................................5 Introduzione................................................................................................................................6 1 Il problema della rilevazione automatica delle presenze.........................................................8 1.1 La rilevazione automatica delle presenze: cenni storici e attualità .................................8 1.2 Rilevazione automatica delle presenze nei corsi di formazione.....................................14 1.2.1 L'acquisizione dei dati di presenza.........................................................................15 1.2.2 Elaborazione e gestione dei dati di presenza..........................................................16 1.3 Architettura di un sistema di gestione delle presenze ...............................................16 1.3.1 Schema funzionale..................................................................................................17 1.3.2 Acquisizione online................................................................................................17 1.3.3 Acquisizione offline................................................................................................18 1.3.4 Transazione ............................................................................................................18 1.3.5 Flusso dei dati.........................................................................................................20 1.3.6 Backup giornaliero automatizzato..........................................................................21 1.3.7 Backup a caldo........................................................................................................21 1.3.8 Badge di identificazione.........................................................................................22 2 Panoramica sugli strumenti software per i sistemi di gestione presenze ..............................27 2.1 Soluzioni Proprietarie.....................................................................................................27 2.1.1 SmartSuite Business Edition – Bioenable Technologies........................................27 2.1.2 Orange HRM Live – OrangeHRM inc...................................................................28 2.1.3 Tulip – Bloomtech s.n.c.........................................................................................29 2.1.4 OrangeHRM – OrangeHRM inc.............................................................................30 2.2 Soluzioni FOSS..............................................................................................................31 2.2.1 SmartSuite Community Edition – Bioenable Technologies...................................32 3 Analisi dei Requisiti nel caso di studio..................................................................................33 3.1 Analisi dei requisiti funzionali........................................................................................33 3.2 Analisi dei requisiti non funzionali.................................................................................35 3.3 Analisi dei requisiti nel caso di studio di un corso di formazione a frequenza obbligatoria...........................................................................................................................36 3.3.1 Attori del Sistema e Casi d'uso...............................................................................36 3.3.2 I casi d’uso per lo studente ....................................................................................38 3.3.3 I casi d’uso per il docente.......................................................................................38 3.3.4 Spiegazione casi d’uso per lo studente...................................................................39 3.3.5 Spiegazione casi d’uso per il docente.....................................................................40 3.4 Definizioni delle tabelle di Cockburn............................................................................41 4. Gli strumenti utilizzati...........................................................................................................50 4.1 Il progetto Liferay...........................................................................................................50 4.2 I Portali...........................................................................................................................54 4.2.1 La struttura dei portali............................................................................................56 4.3 Java Portlet e Portlet Container.....................................................................................59 4.3.1 Gli standard per sviluppare una portlet...................................................................62 4.4 Java Server Pages (JSP)..................................................................................................62 Gargiulo Marco 566/1465 Pagina 2 di 135 4.4.1 Come funzionano le JSP ........................................................................................63 5 Dettagli implementativi della soluzione software realizzata ...............................................63 5.1 Servizi generali...............................................................................................................63 5.1.1 Servizio di autenticazione.......................................................................................63 5.1.2 Iterazione tra il frontend ed il backend del sistema................................................65 5.1.3 Servizio di registrazione.........................................................................................68 5.1.4 Servizio di cambio password..................................................................................73 5.2 Servizi per lo studente....................................................................................................75 5.3 Servizi per il docente......................................................................................................79 Conclusioni...............................................................................................................................86 Appendice A Configurazione dell'ambiente di lavoro..............................................................87 A.1 Installazione Application Server Apache Tomcat 6.......................................................87 A.2 Installazione di Liferay in ambiente linux utilizzando apache tomcat 6 e MySQL 5.1 88 A.3 Installazione dei package di Liferay..............................................................................89 Appendice B - Il codice del sistema presenze...........................................................................93 File “registrazione.jsp”.........................................................................................................93 File “verifica7.jsp”...............................................................................................................97 File “cambia_password0.jsp”.............................................................................................106 File “visualizza_registrazioni4.jsp”....................................................................................109 File “iscrizione_corso.jsp”..................................................................................................111 File “visualizza_corsi_attivi.jsp”........................................................................................113 File “nuova_lezione.jsp”....................................................................................................117 File“visualizza_presenze.jsp”(Lato studenti).....................................................................119 File “visualizza_presenze2.jsp”(Lato studenti)..................................................................120 File “elimina_corso.jsp”.....................................................................................................125 File “visualizza_corsi.jsp”(Lato docente)..........................................................................127 File “dettaglio_corso.jsp”...................................................................................................130 File “visualizza_lezioni.jsp”(Lato docente).......................................................................132 BIBLIOGRAFIA E SITOGRAFIA.........................................................................................135 Gargiulo Marco 566/1465 Pagina 3 di 135 Ringraziamenti... Desidero ringraziare il Prof. Guido Russo e la Dott.ssa Vania Boccia per avermi dato la possibilità di svolgere questo lavoro e per tutto l'aiuto che mi hanno dato nello svolgimento dello stesso. Un ringraziamento speciale va alla mia fidanzata Martina che mi è stata vicina sia nei momenti difficili, aiutandomi a superare le difficoltà incontrate nel corso di questi anni, sia nei momenti belli in cui abbiamo condiviso la gioia insieme. Un ringraziamento doveroso va alla mia famiglia che mi ha sempre sostenuto sia moralmente che soprattutto economicamente durante il periodo universitario. Un ringraziamento speciale va anche ai miei amici e colleghi Pasquale, Marco e Daniele Gargiulo Marco 566/1465 Pagina 4 di 135 Premessa L'istituto Nazionale di Fisica Nucleare, l'Università degli Studi di Napoli “Federico II” e l'Università degli Studi di Bari “Aldo Moro” hanno vinto uno dei progetti PON della programmazione 2007-2013 di potenziamento infrastrutturale presentando un progetto denominato “ReCasRete di Calcolo per SuperB ed altre applicazioni). Nell'ambito del progetto è previsto anche un piano formazione denominato “CASAP” :Calcolo Scientifico ad Alte Prestazioni” avente lo scopo di formare , mediante l'istituzione di Master di primo e secondo livello, un certo numero di figure professionali specializzate in tematiche inerenti il Calcolo Scientifico ad alte prestazioni. I master di primo e secondo livello sono stati istituiti rispettivamente presso l'Università “Federico II” di Napoli e l'Università Aldo Moro di Bari e per l'anno accademico 2012/2013. Per entrambe i Master Universitari ed i periodi di stage successivi ai Master c'è, per i formando, l'obbligo di presenza. Relativamente al Master di Napoli, esso ha come obiettivo quello di qualificare personale tecnico scientifico nel settore ICT, in particolare dei sistemi di calcolo ad alte prestazioni. I formandi acquisiranno competenze specifiche nello sviluppo, nell'utilizzo e nella gestione di servizi ICT e piatteforme di calcolo ad alte prestazioni per il supporto alla ricerca, alle imprese ed alle PA locali e centrali. In linea con le attività previste dal Progetto di Potenziamento Infrastrutture ReCaS è prevista la formazione di Tecnologi in possesso di un livello di competenze specialistiche nei settori di riferimento, prioritariamente per le applicazioni del supercalcolo agli esperimenti di Fisica di prossima generazione, e di altre applicazioni. Gargiulo Marco 566/1465 Pagina 5 di 135 Introduzione Il lavoro oggetto del presente tirocinio, effettuato presso la Control Room del progetto S.Co.P.E, ha avuto come obiettivo la progettazione e lo sviluppo di una “web application” per la gestione delle presenze di un corso di formazione. Il caso di studio esaminato è il Master di 1° Livello CASAP legato al progetto PON ReCaS. Al giorno d'oggi software con funzioni di questo tipo sono utilizzate sempre in più anche in realtà lavorative con benefici quantificabili subito come la riduzione del tempo impiegato per la gestione del personale, ottimizzando i compiti delle amministrazioni. Questi vantaggi sono dovuti all'eliminazione del supporto cartaceo: i dipendenti non devono più segnare a penna orari di ingresso o di uscita e un maggiore controllo sulla legalità dei dipendenti, dall'altro canto la segreteria non deve sobbarcarsi il lavoro del calcolo delle ore di lavoro effettive per ricavare il quantitativo netto delle ore lavorative, tutto viene automatizzato. Il codice sviluppato durante questo tirocinio, dunque, è adatto in qualsiasi ambito applicativo in cui ci sia l'esigenza di sistemi di controllo delle presenze. L'attività svolta si divide in tre fasi temporali: la prima di studio del problema e di ricerca degli strumenti software (commerciali e non) utilizzati per la gestione delle presenze. Sono stati analizzati anche i requisiti funzionali dell'applicativo da realizzare e individuati gli strumenti disponibili per la realizzazione di sistemi per la gestione delle presenze. Da un'accurata analisi di mercato è emersa la presenza di molti strumenti a pagamento che si occupano della gestione delle presenze ma tali software presentano lo svantaggio di dover essere continuamente adattati, a pagamento, dagli sviluppatori nel corso degli anni sulla base delle esigenze dei committenti, e questo li rende poco Gargiulo Marco 566/1465 Pagina 6 di 135 competitivi rispetto a prodotti open source. La seconda fase dell'attività ha riguardato la ricerca di strumenti open source più adatti alla realizzazione del prodotto software. Durante la seconda fase è stata effettuata l'analisi dei requisiti funzionali e non, relativi a diversi casi d'uso dell'applicazione, e la relativa progettazione del modello dati adatto al contesto. In tale fase sono stati anche scelti gli strumenti software per la realizzazione del progetto di tirocinio. Infine durante l'ultima fase del tirocinio è stata costruita l'applicazione vera e propria. Questa tesi è organizzata come segue: Nel Capitolo 1 viene riportata una panoramica anche storica sulle metodologie di acquisizione e gestione delle presenze in vari ambiti; nel Capitolo 2 è riportato lo stato dell'arte relativamente agli strumenti che servono per realizzare un sistema di gestione delle presenze, focalizzando l'attenzione anche su strumenti commerciali; nel Capitolo 3 si focalizza l'attenzione sui requisiti funzionali e non funzionali che un sistema di gestione delle presenze deve possedere; nel Capitolo 4 sono illustrate le scelte implementative (gli strumenti software e i linguaggi scelti); nel Capitolo 5 viene descritta la parte implementativa dell'attività di tirocinio, riportando l'analisi descrittiva del software realizzato di cui in Appendice B è riportato il codice. Gargiulo Marco 566/1465 Pagina 7 di 135 1 Il problema della rilevazione automatica delle presenze 1.1 La rilevazione automatica delle presenze: cenni storici e attualità Il concetto di rilevazione presenze in ambiti come le fabbriche è vecchio più o meno come la rivoluzione industriale. Quando il numero di persone che lavorano in un'azienda diventa consistente e si vuole tenere sotto controllo "se, chi e quando" le persone si recano in azienda, gestire in modo flessibile gli orari di lavoro, la mobilità richiesta ai dipendenti il ricorso sempre più frequente a collaboratori esterni, la necessità di ridurre il costo del lavoro e le spese di gestione richiedono un sistema di rilevazione presenze evoluto ed efficace. Solo grazie alla rilevazione esatta delle presenze è infatti possibile pagare ai dipendenti esattamente quanto gli spetta riuscendo a contare anche gli straordinari. I dipendenti hanno così un documento sul quale poter fare sempre affidamento per riuscire a far valere i loro diritti e i datori di lavoro sono a conoscenza dell'operato di ogni singolo lavoratore. Inizialmente la presenza dei lavoratori, si rilevava in modo “manuale” e avveniva tramite il così detto foglio firma o foglio di presenza. Il foglio di presenza era organizzato nel modo seguente: veniva annotato il nominativo del dipendente, l'orario di inizio e veniva apportata la firma del dipendente. La stessa procedura veniva eseguita al termine dell'orario di lavoro. Questo modo di rilevare le presenze non era né efficiente, né affidabile in quanto richiedeva uno spreco di tempo per la segnatura, ma anche l'assunzione da parte della fabbrica di un dipendente che aveva il compito di visionare il corretto operato dei dipendenti durante la fase di firma. L'inefficienza di tale sistema, si riscontrava anche per il calcolo delle ore totali di lavoro, dei singoli dipendenti, alla fine del mese per il calcolo degli stipendi. Gargiulo Marco 566/1465 Pagina 8 di 135 Il dipendente che aveva il compito di calcolare le ore di presenza dei dipendenti doveva districarsi con molteplici fogli di presenza e gli errori erano frequenti. Illustrazione 1: Foglio firma. Successivamente l'acquisizione di presenze è passata da manuale a meccanica grazie all'invenzione e costruzione di appositi macchinari Il macchinario più utilizzato per controllare le presenze è senza dubbio il “timbracartellino”. Il “timbra-cartellino” è una sorta di orologio sul quale viene stampata sia l'ora d'ingresso che quella di uscita dei dipendenti. Gargiulo Marco 566/1465 Pagina 9 di 135 Illustrazione 2 : Timbra-cartellino. E' possibile anche scegliere un marcatempo che può stampare l'ora e la data oltre che sui cartellini anche su qualsiasi altra tipologia di documento. Con la nascita di sempre nuove forme di lavoro e con il diffondersi di lavori in mobilità come ad esempio l'assistenza domiciliare, le imprese delle pulizie o le attività logistiche però i timbra-cartellini non sono sempre la scelta più giusta. E' possibile infatti in questi casi controllare la presenza in sede del dipendente ad inizio e fine turno ma non è possibile controllare niente durante il turno stesso. Proprio per questo motivo sono stati studiati alcuni macchinari tascabili di rilevazione delle presenze che oltre all'orario di inizio e fine turno possono anche immagazzinare dati relativi alle varie attività svolte. I dati devono in seguito ovviamente essere scaricati su un computer sul quale sia stato installato un apposito software di gestione delle presenze. I macchinari portatili sono un'ottima soluzione anche per tutte le attività nelle quali si cambia spesso sede di lavoro come avviene per esempio per i cantieri edili. In questo modo il controllo delle presenze è assicurato in modo continuativo. Timbra-cartellini, marcatempo e macchinari tascabili di ultima generazione sono tutti molto robusti e riescono a sopportare condizioni climatiche e di temperatura anche Gargiulo Marco 566/1465 Pagina 10 di 135 estreme. Non temono neanche la sporcizia né la maggior parte degli agenti chimici. In questo modo viene garantita loro una lunga vita e un perfetto funzionamento in qualsiasi tipologia di luogo di lavoro. Con l'avvento dell'informatica, la maggior parte delle grandi e medie aziende è passata ai "badge magnetici". Questo passaggio di tecnologia ha anche modificato i normali gesti quotidiani nell'atto di manifestare la propria presenza dei lavoratori: da compiere un gesto di inserimento del cartellino nell'orologio marcatempo ad un gesto più fluido e disinvolto di “strisciare” il badge magnetico in lettori di badge magnetici personali. Illustrazione 3: Badge Magnetico Tramite appositi terminali posti all'ingresso delle sedi di lavoro, passando il badge sui sensori predisposti sul terminale, che possono essere magnetici, ottici, sistemi a contatto o wireless, il terminale è in grado di segnalare al computer centrale chi è entrato o uscito in azienda. La memorizzazione dei dati di presenza avviene automaticamente ad intervalli di tempo predefiniti. Gargiulo Marco 566/1465 Pagina 11 di 135 Illustrazione 4 : Sistema di trasmissione dati. In ambienti di lavoro nei quali la rilevazione della presenza è una questione più delicata, poiché legata ad esempio a problemi di sicurezza, sono stati inoltre studiati metodi più sofisticati. In alcuni casi, infatti, è indispensabile stabilire che la persona entrata con un determinato nome sia effettivamente ciò che dice di essere. Si pone il problema che un dipendente possa prendere il badge di qualcun altro ed entrare a nome suo anche non essendo autorizzato a farlo. In questi casi vengono utilizzati ad esempio tecniche di tipo "biometrico". Un primo tipo di rilevamento biometrico utilizza come segno distintivo della persona utilizza le impronte digitali. In questo caso, al posto oppure oltre al badge, è necessario certificare che la persona che entra sia quella che ci si aspetta tramite la lettura ottica delle impronte digitali. Un Gargiulo Marco 566/1465 Pagina 12 di 135 apposito sensore "scannerizza" il dito applicato e confronta i "segni" con la mappa memorizzata. In alcuni casi il sistema è in grado di riconoscere, oltre all'impronta, anche le caratteristiche della pelle, evitando così possibili frodi. Illustrazione 5 : Tecnica biomedica1 Un altro, ancora più sofisticato, tipo di controllo degli accessi di tipo biometrico, prevede il riconoscimento dell'iride. Si calcola che la possibilità di confondere un individuo con un altro utilizzando questo metodo è pari a uno su 1.2 milioni di casi. In questo caso una telecamera riprende l'iride di un occhio del soggetto, la digitalizza e la confronta con un riferimento precedentemente memorizzato. Gargiulo Marco 566/1465 Pagina 13 di 135 Illustrazione 6 : Tecnica biomedica2 I sistemi biometrici di rilevazione delle presenze sono generalmente osteggiati dal Garante per la privacy. Infatti, la raccolta e la registrazione di impronte digitali dei lavoratori e/o di altri dati biometrici utilizzati dalle aziende per la rilevazione in tempo reale delle presenze sul luogo di lavoro se da un lato elimina i tempi legati al controllo delle informazioni registrate nei cartellini o nei fogli di firma e rende più attendibile l'identificazione fisica del personale soprattutto quando i luoghi di lavoro presentano diverse vie d'accesso o una distribuzione territoriale articolata, dall'altro lato risulta particolarmente invasiva rispetto a dati personali sensibili dei dipendenti. 1.2 Rilevazione automatica delle presenze nei corsi di formazione La realizzazione di sistemi di rilevazione automatici delle presenze per gli studenti sono nati dall'esigenza delle Facoltà, di gestire con un sistema rapido ed efficiente, le presenze degli studenti, sia alle lezioni frontali che alle esercitazioni, dei corsi di studio a frequenza obbligatoria. Di seguito sono riportate le due fasi principali di un sistema di gestione delle presenze. Gargiulo Marco 566/1465 Pagina 14 di 135 1.2.1 L'acquisizione dei dati di presenza L’acquisizione delle timbrature di presenza dello studente viene effettuata attraverso i terminali orologio installati nelle aule didattiche e nei laboratori. L’acquisizione da terminale genera un file ASCII contenente le seguenti informazioni: Per la timbratura di apertura sessione effettuata dal docente: ● Identificativo del terminale di acquisizione (mediante indirizzo IP) ● Codice del badge docente ● Ora di apertura della sessione di timbrature ● Codice del corso ● Codice della classe ● Numero di ore previste ● Data della timbratura ● Ora della timbratura ● Verso di timbratura (ENTRA) Per la timbratura effettuata dallo studente: ● Identificativo del terminale di acquisizione (mediante indirizzo IP) ● Data della timbratura ● Ora della timbratura ● Verso di timbratura (ENTRA / ESCE - per lo studente il verso è irrilevante) ● Codice del badge studente Per la timbratura di chiusura sessione effettuata dal docente: ● Identificativo del terminale di acquisizione (mediante indirizzo IP) ● Codice del badge docente ● Data della timbratura ● Ora della timbratura ● Verso di timbratura (ESCE) Gargiulo Marco 566/1465 Pagina 15 di 135 Le timbrature vengono registrate in un DBMS e successivamente interpretate dal modulo di gestione per l'elaborazione delle ore di presenza da accreditare allo studente. 1.2.2 Elaborazione e gestione dei dati di presenza Un software per l'elaborazione e la gestione dei dati di presenza offre le seguenti funzionalità: ● Gestione delle anagrafiche studente / docente ● Visualizzazione dell’organigramma delle “attività didattiche” previste nell’offerta formativa dell’anno accademico corrente ● Monitoraggio delle presenze dello studente attraverso la griglia del Piano Frequenze, attraverso la quale è possibile visualizzare, modificare, inserire o cancellare le ore di presenza attribuite allo studente per ciascuna delle lezioni seguite ● Generazione della reportistica (report di presenza giornaliero, report di presenza riepilogativo del corso con l'indicazione delle percentuali di frequenza per ciascuno studente, “cartellino presenze studente” per corso selezionato, rendicontazione delle ore svolte per tipologia di attività didattica). 1.3 Architettura di un sistema di gestione delle presenze Un sistema per la gestione delle presenze degli studenti si articola in tre moduli principali: ● Modulo di acquisizione delle timbrature: è il software che gestisce la comunicazione tra i terminali ed il server di rilevazione presenze; ● Modulo di elaborazione e gestione dei dati di presenza: è il software dedicato all’elaborazione dei dati ai fini del calcolo degli indicatori di presenza. Tale modulo racchiude le funzionalità di gestione del sistema di rilevazione presenze e consente la generazione della reportistica; Gargiulo Marco 566/1465 Pagina 16 di 135 ● Modulo web: consente, a studenti e docenti, la consultazione delle timbrature registrate in aula e la stampa dei prospetti di riepilogo delle lezioni. 1.3.1 Schema funzionale La funzione del sistema di acquisizione è quella di rilevare, in modo affidabile, le timbrature di entrata e di uscita, di associarle alle causali relative al movimento degli studenti o docenti, di registrarle nei file preposti e infine di trasferirle al sistema di gestione. Tale funzione viene svolta con l'impiego di lettori di badge connessi a dei server mediante la rete. Tali server, svolgono la funzione di CLIENT di ACQUISIZIONE, ricevono la timbrature, ne controllano la validità e le registrano nell'archivio delle timbrature acquisite. L'archivio delle timbrature acquisite viene ospitato sul cosiddetto SERVER di ACQUISIZIONE che può essere replicato in ridondanza al fine di aumentare l'affidabilità del sistema. I lettori di badge sono collegati al Server di Acquisizione tramite linee seriali MULTIDROP con convertitori d'interfaccia RS232-RS485, che consentono il collegamento di 4 lettori su ciascuna linea dorsale. Ciascun lettore è caratterizzato da un identificativo unico nell'ambito del sistema, che fa parte integrante del messaggio che il lettore trasmette o riceve. E' tramite tale identificativo che il messaggio viene riconosciuto come appartenente ad un certo lettore piuttosto che ad un altri. I lettori di badge possono acquisire dati in 2 modalità: la modalità ONLINE, e quella OFFLINE. 1.3.2 Acquisizione online ONLINE significa che il collegamento lettore-Server di Acquisizione e' attivo, per cui ad ogni interrogazione il lettore risponde con il messaggio previsto. Le timbrature acquisite in modalità ONLINE, vengono immediatamente inviate al processo interrogante. In questo caso sul lettore appare, per ogni timbratura acquisita, un messaggio generato dal processo interrogante, che indica l'avvenuta accettazione, oppure il rifiuto della stessa. Gargiulo Marco 566/1465 Pagina 17 di 135 1.3.3 Acquisizione offline OFFLINE significa che il collegamento lettore-Server di Acquisizione non e' attivo, per cui le timbrature fatte vengono immagazzinate nella memoria locale del lettore. Le timbrature acquisite in modalità OFFLINE, non possono subire alcun controllo immediato, per cui sul display del lettore appare sempre il messaggio con il significato di “TIMBRATURA ACQUISITA”. Dopo che il collegamento con il processo interrogante è stato ripristinato, le timbrature vengono scaricate dalla memoria locale del lettore e inviate al Server di Acquisizione. Durante questa attività le eventuali timbrature fatte, vengono acquisite ancora in modalità OFFLINE e accodate a quelle già esistenti. 1.3.4 Transazione Successivamente all’apertura della sessione da parte del docente, gli studenti possono attestare la loro presenza effettuando una timbratura sul terminale master o su uno dei terminali slave. Il passaggio corretto del badge sarà seguito da un Beep (accettato) o da tre Beep (errata nella lettura del badge) per invitare a ripetere l’operazione. I codici di attività relativi alla transazione dei docenti sono riepilogati nelle tabelle sottostante. Gargiulo Marco 566/1465 Pagina 18 di 135 La prima indica il “Codice Topologia” seguito dal codice di “Attività”. CODIFICA TOPOLOGIA CODIFICA TIPOLOGIE ATTIVITA’ DIDATTICHE 00 Attività didattiche ordinarie ADO 01 Attività didattiche per Supplenze ADS 02 Attività didattiche per Incentivazione ADI 03 Attività didattiche per Master I liv. AM1 04 Attività didattiche per Master II liv. AM2 05 Attività didattiche per corsi di Dottorato ADD 06 Attività didattiche per scuole di specializzazione ASP 07 Attività didattiche Complementario Integrative ADC 08 Attività didattiche anno di preparazione ADP 99 Altro AAA Tabella 1 : Esempio di Possibile codifica (1) CODIFICA ATTIVITA’ DIDATTICHE 00 Lezione LEZ 01 Esercitazione ESE 02 Laboratorio LAB 03 Seminario SEM Tabella 2 : Esempio di Possibile codifica (2) Il codice attività da digitare sul terminale è dato dal “CODICE TIPOLOGIA” seguito dal “CODICE ATTIVITA” Gargiulo Marco 566/1465 Pagina 19 di 135 ESEMPIO: Codice da digitare sul terminale Decodifica 0000 ADO– Lezione 0001 ADO– Esercitazione 0002 ADO– Laboratorio 0300 AM1– Lezione 0301 AM1– Laboratorio Tabella 3 : Esempio di Possibile codifica (3) 1.3.5 Flusso dei dati I dati, o in altri termini, le timbrature, vengono acquisiti dai lettori; quest'ultimi, continuamente interrogati dai PROCESSI ACQUISITORI, inviano le timbrature acquisite al processo interrogante che, in condizioni normali è attivo sul Client di Acquisizione. La timbratura acquisita viene, in prima istanza, registrata sul file detto LOG DI TRANSITO e nell'istante successivo viene controllata dal processo acquisitore interrogante. Se tale controllo non è superato, la causale di rifiuto viene registrata nel summenzionato log di transito, inoltre tale evento viene segnalato sulla console del Server di Acquisizione. Nel caso in cui il controllo è superato, la timbratura viene: ● Registrata nell'archivio delle timbrature acquisite ubicato sul SERVER di BACKUP; Gargiulo Marco 566/1465 Pagina 20 di 135 ● Registrata sul giornale delle timbrature, ubicato sul Server di Backup. Se invece il controllo non e' superato, viene solamente registrato l'evento nel LOG DELLE TIMBRATURE RIFIUTATE. 1.3.6 Backup giornaliero automatizzato Il BACKUP GIORNALIERO è l'insieme delle attività che garantiscono la possibilità di ricostruire la situazione in cui era il sistema nel momento in cui si è verificato un guasto sul Server di Acquisizione. La procedura di backup viene lanciata giornalmente dal personale incaricato; essa rimane in attesa fino alle ore 1:00 del giorno successivo a quello dell'esecuzione, quindi inizia e registra la traccia di elaborazione nel file BACKUP.LOG : Le attività di Backup Giornaliero Automatizzato sono le seguenti: ● Esegue su supporti di memorizzazione il backup di archivi e programmi dell'ambiente di produzione del Sistema di Acquisizione. ● Esegue la copia dei soli archivi sul Server di Backup. 1.3.7 Backup a caldo S'intende per BACKUP CALDO la possibilità di utilizzare il Sistema di Backup al posto del Sistema di Acquisizione, usando la stessa configurazione hardware basata sui Client di Acquisizione. Tale possibilità deve essere applicata solo nei casi in cui il Server di Acquisizione non è disponibile per un periodo di tempo molto lungo. In questo caso la memoria locale dei lettori di badge potrebbe saturarsi, perciò il servizio di acquisizione potrebbe non essere garantito. Gargiulo Marco 566/1465 Pagina 21 di 135 Le azioni necessarie ad attivare Il BACKUP CALDO sono: ● Assicurarsi che il Sistema di Acquisizione sul server omonimo non sia attivo. ● Ridefinire, nell'apposita tabella, i parametri di indirizzamento del Server di Backup con quelli del Server di Acquisizione. ● Avviare il Sistema di Acquisizione. ● Lanciare il Processo Trasferitore. A questo punto, il personale preposto e' in grado di svolgere le normali attività sul Sistema di Gestione Presenze. 1.3.8 Badge di identificazione Un badge di identificazione o solo badge (dall'inglese: distintivo) è una tessera in PVC o altro materiale plastico (PET/ABS/Policarbonato) utilizzata per l'identificazione di docenti e/o studenti. Normalmente ha le dimensioni di una carta di credito conforme alla norma ISO 7810 nel formato ID-1 e può essere munito di banda magnetica o di altri dispositivi, quali ad esempio microcontrollori, RFID o memorie EEPROM, per l'utilizzo con apparecchiature informatiche e elettroniche. In telecomunicazioni ed elettronica RFID (Radio Frequency IDentification o Identificazione a radio frequenza) è una tecnologia per l'identificazione e/o memorizzazione dati automatica di oggetti, animali o persone, basata sulla capacità di memorizzazione di dati da parte di particolari dispositivi elettronici (detti tag o transponder) e sulla capacità di questi di rispondere all' "interrogazione" a distanza da parte di appositi apparati fissi o portatili chiamati per semplicità' "lettori" (in realtà' sono anche scrittori) a radiofrequenza comunicando (o aggiornando) le informazioni in essi contenute. In un certo senso possono essere quindi assimilabili a sistemi di "lettura e/o.scrittura".senza.fili.con.numerose.applicazioni. Nel 1973 Steven Depp, Alfred Koelle e Robert Freyman organizzarono una storica Gargiulo Marco 566/1465 Pagina 22 di 135 dimostrazione del funzionamento dei tag RFID a potenza riflessa (backscattering modulato), sia di tipo passivo che attivo, presso il Los Alamos Scientific Laboratory. Questo sistema portatile funzionava con una frequenza di 915 MHz e impiegava tag a12 bit. Questa tecnica è impiegata ancora oggi sulla maggior parte dei tag UHF (Ultra High Frequency) e RFID a microonde. La tecnologia RFID è considerata per la sua potenzialità di applicazione una tecnologia general purpose (come l'elettricità, la ruota, etc) e presenta un elevato livello di pervasività, ovvero una volta trovata una applicazione in un punto della filiera, l'applicazione ed i benefici si propagano velocemente a monte e a valle della stessa. Con gli RFID, grazie allo sviluppo delle tecnologie dell'informazione e di Internet è possibile creare una rete di oggetti e l'adozione a vasta scala in svariate applicazioni prevista nei prossimi decenni nonché la probabile interconnessione dei dati ottenuti in un'unica grande rete globale ha dato vita all'espressione “Internet delle cose”. Nello specifico un sistema RFID è costituito da tre elementi fondamentali: ● Un apparecchio di lettura e/o scrittura (lettore). ● Uno o più etichette RFID (o tag o Transponder). ● Sistema informativo di gestione dei dati per il trasferimento dei dati da e verso i lettori. L'etichetta RFID può essere attiva, passiva, semi-passiva o semi-attiva. Se è attiva, dispone di: ● Una batteria per alimentarla. ● Una o più antenne per inviare il segnale di lettura e ricevere le risposte anche su frequenze diverse. ● Uno o più transponder/tag RFID e possono contenere sensori Gargiulo Marco 566/1465 Pagina 23 di 135 In genere hanno distanze operative maggiori dei tag passivi ed in genere arrivano al massimo a 200m. Se è passiva: contiene: ● Un microchip (con identificativo univoco ed eventuale memoria), privo di alimentazione elettrica, ● Un'antenna ed un materiale che fa da supporto fisico chiamato "substrato" e che viene "eccitato, alimentato e/o scritto" al passaggio di un lettore che emette un segnale radio a frequenze basse o medie o di alcuni giga hertz (sotto le diverse bande usate). La radiofrequenza attiva il microchip e gli fornisce l'energia necessaria a rispondere al lettore, ritrasmettendogli un segnale contenente le informazioni memorizzate nel chip ma che, come abbiamo già detto, può anche scrivere dati sul.tag. Se è semi-passiva: è dotata di batteria usata solo per alimentare il microchip o apparati ausiliari (sensori) ma non per alimentare un trasmettitore in quanto in trasmissione si comportano come un'etichetta RFID passiva. Se è semi-attiva: è dotata di batteria che alimenta il chip ed il trasmettitore in cui per risparmiare energia l'etichetta RFID è disattivata e viene attivata tramite un ricevitore con tecnologia dei tag passivi e quindi in assenza di interrogazioni il tag può operare per tempi lunghi. L'elemento principale che caratterizza un sistema RFID è l'etichetta RFID o transponder o tag ed è costituito da: ● Un microchip che contiene dati in una memoria (tra cui un numero univoco universale scritto nel silicio) ● Una antenna ● Un supporto fisico che tiene insieme il chip e l'antenna chiamato "substrato" che può essere in Mylar, film plastico (PET, PVC, ecc), carta o altri materiali(in Gargiulo Marco 566/1465 Pagina 24 di 135 rari casi viene usata una batteria). L'antenna riceve un segnale, che tramite il principio della induzione trasforma in energia elettrica, che alimenta il microchip. Il chip così attivato trasmette i dati in esso contenuti tramite l'antenna (circuito di trasmissione del segnale) all'apparato che riceve i dati. In sintesi, un tag RFID è in grado di ricevere e di trasmettere via radiofrequenza le informazioni contenute nel chip ad un transceiver RFID. Il Lettore emette un campo elettromagnetico/elettrico che tramite il processo della induzione genera nell'antenna del tag una corrente che alimenta il chip. Il chip così alimentato comunica tutte le sue informazioni che vengono irradiate tramite l'antenna verso il Lettore ed il Lettore, come più volte detto, può anche scrivere i dati sul tag È possibile realizzare RFID in infiniti formati: inseriti in etichette del tutto simili a quelle normalmente utilizzate nei capi di abbigliamento, oppure sotto forma di adesivi da applicare sulle confezioni di cartone dei prodotti, o all'interno di tessere formato carta di credito. Per accedere alle informazioni contenute nell'etichetta è necessario un lettore fisso o portatile. Il vantaggio offerto da questo tipo di tecnologia rispetto ai sistemi di identificazione attualmente più utilizzati (codici a barre e lettori a banda magnetica), è che il lettore non ha bisogno di avere la visibilità ottica rispetto all'etichetta e funziona in tempi estremamente ridotti (circa 1 decimo di secondo). Il motivo di una scelta di questo carattere lo si può sintetizzare nei seguenti punti: Gargiulo Marco 566/1465 Pagina 25 di 135 I vantaggi della soluzione: ● Abbattimento dei tempi di computo dei cartellini ● Riduzione del rischio di errori di calcolo ● Controllo automatico degli orari e delle presenze dei dipendenti in tempo reale ● Stampa ed esportazione automatica dei dati elaborati ● Eliminazione dei fogli Inail vidimati e compilati a mano ● Interfaccia semplice e chiara per un utilizzo immediato Gargiulo Marco 566/1465 Pagina 26 di 135 2 Panoramica sugli strumenti software per i sistemi di gestione presenze La maggior parte dei prodotti esistenti sul mercato sono degli “Human Resources Management System” (HRMS), ovvero dei software multi-funzione per la gestione del personale (comprese timbrature e mansioni) delle commissioni e delle gestioni delle retribuzioni, di seguito analizzeremo solo i principali prodotti, sia al livello nazionale che a livello internazionale. Alcuni di essi comprendono anche i moduli per l'iterazione con i sistemi di acquisizione delle presenze, mentre per altri è necessaria un'integrazione con gli appositi moduli software prodotti dai produttori dell'hardware. 2.1 Soluzioni Proprietarie Ovvero quei software che sono sviluppati da aziende private e rilasciati a terzi con restrizioni specificate nella licenza, riguardanti l'utilizzo, la modifica e la distribuzione del prodotto. Solitamente il prezzo varia a seconda delle funzionalità presenti, infatti l'applicazione di base è espandibile con l'acquisti di moduli che offrono features aggiuntive. La ditta sviluppatrice inoltre garantisce assistenza in caso di problemi e spesso la disponibilità ad effettuare personalizzazioni o adattamenti. 2.1.1 SmartSuite Business Edition – Bioenable Technologies Web application sviluppata in PHP, installabile sia da internet aziendale sia in server web. Le timbrature vengono memorizzate in DBMS di tipo MySQL, con la possibilità di importarle ed esportarle, inoltre questa versione del software supporta diversi strumenti hardware di acquisizioni, offerti dall'azienda produttrice stessa. In caso di necessità è possibile acquistare degli interventi di personalizzazione del software a seconda delle esigenze e il supporto è garantito in diversi modi, come forum, email, chat e telefono. Gargiulo Marco 566/1465 Pagina 27 di 135 Si possono definire più profili utente e relativi privilegi, con la possibilità di controllare le presenze e l'orario di lavoro tramite grafici e schemi esportabili. La gestione degli stipendi viene semplificata notevolmente con calcoli automatici sulle informazioni salariali di ogni dipendente e sulle ore di lavoro, inoltre vengono pianificati i compiti dei lavoratori assegnati. E' possibile poi monitorare la situazione aziendale attraverso la generazione di più di 50 report configurabili e personalizzabili. 2.1.2 Orange HRM Live – OrangeHRM inc. Prodotto SaaS(Software as a Services) cioè l'applicazione viene rilasciata e resa disponibile dal produttore tramite internet direttamente sul browser web, senza il bisogno di mantenere in azienda un'infrastruttura server, sistemi di backup o tecnici addetti. Il software è stato sviluppato in PHP e necessita di un DBMS di tipo MYSQL. L'interfaccia è semplice e intuitiva, con la possibilità di generare dei totalizzatori esportabili in formati PDF o CSV, in oltre sono disponibili numerosi moduli da integrare nell'applicazione, per far fronte ad ogni esigenza aziendale. IU moduli interessati per quanto riguarda i requisiti sono: ● Admin module: vengono aggiunte funzioni utili per l'amministrazione, come la gestione degli utenti, le loro informazioni, le loro mansioni, orari e altro, con la possibilità di inviare notifiche. ● Personal information module: per inserire informazioni sulle capacità e conoscenza del personale, le lingue parlate, le specializzazioni, oltre alle informazioni sul salario. ● Time and attendance module: per automatizzare il tracciamento delle presenze del personale e organizzare meglio il flusso lavorativo, riducendo errori e perdite di tempo. Gargiulo Marco 566/1465 Pagina 28 di 135 Illustrazione 10 : Orange HRM Live 2.1.3 Tulip – Bloomtech s.n.c. Software prodotto da una ditta di Conegliano (TV) adottato da più di 250 aziende di ogni settore e dimensione, per far fronte alla gestione non solo di timbrature ma anche delle commesse, è disponibile sia come software installabile sia come applicativo web accessibile da browser (con l'acquisto del relativo modulo). Illustrazione 11 : Orange HRM Live Tulip è compatibile i database Oracle, Microsoft Access o Microsoft SQL Server, le timbrature possono essere rilevate con numerosi sistemi come quelli offerti dalla ditta DBL di Udine: codice a barre, banda magnetica, trasponder in radiofrequenza, impronta biometrica, foto istantanea da fotocamera e riconoscimento del volto. Tutte le Gargiulo Marco 566/1465 Pagina 29 di 135 funzioni di Tulip sono personalizzabili, come le informazioni del personale, gli orari di lavoro, le regole per la gestione delle pause e le varie tolleranze di orario, le ferie i permessi e molto altro. Si possono impostare dei totalizzatori, per il calcolo di orari o di buste paga, cartellini personalizzati, il tutto per velocizzare le mansioni e le trasferte del personale, con la possibilità di inserimento di giustificativi e ogni totalizzatore o cartellino può essere esportato in diversi formati. Non tutte le funzionalità sopracitate però sono integrate nativamente nell'applicativo, bensì sono acquistabili come moduli da integrare, come “Rilevazioni tempi commesse” per pianificare le commesse dalle timbrature, “Controllo accessi” utile per impostare le regole e gli orari d'accesso del personale, “Risorse umane” per controllare e gestire tutto il personale ed infine “Tulip Web” per far accedere ai dipendenti autorizzati alle azioni di timbratura e controllo direttamente tramite browser web da qualsiasi computer connesso alla rete aziendale. 2.1.4 OrangeHRM – OrangeHRM inc. Soluzione Open-Source leader internazionale per la gestione del personale per imprese di piccolo o medie dimensioni, il programma è scaricabile liberamente mentre il supporto, i corsi di formazione, le personalizzazioni e i moduli aggiuntivi (che sono gli stessi della versione live) sono a pagamento. Si tratta della soluzione liberamente scaricabile dell'omonimo software già analizzato in precedenza, la community garantisce un prodotto stabile e continuatamente aggiornato, però nativamente è privo di numerose funzioni utili rispetto alla versione a pagamento, come l'esportazione di resoconti in formati CSV o PDF. Gargiulo Marco 566/1465 Pagina 30 di 135 Illustrazione 12: Orange HRM Inc. 2.2 Soluzioni FOSS Acronimo di “Free and Open Source Software“, i prodotti con questo tipo di licenze integrano i concetti di software libero e di Open-Source, ovvero le applicazioni possono essere utilizzate gratuitamente e il loro codice sorgente è disponibile a chiunque per modifiche o personalizzazioni. Tuttavia per intervenire nel software è necessario all'interno dell'azienda con conoscenze e capacità adatte, altrimenti bisogna affidare il lavoro ad una ditta esterna, con i costi annessi. Molto spesso non è presente una documentazione adeguata, il prodotto evolve grazie ad una community di utilizzatori che eventualmente può fornire aiuto tramite forum, mentre l'assistenza ufficiale è a pagamento. Gargiulo Marco 566/1465 Pagina 31 di 135 2.2.1 SmartSuite Community Edition – Bioenable Technologies La versione FOSS di SmartSuite viene privata della compatibilità con gli strumenti di marcatura di tipo biometrico o con carte di prossimità e del supporto esteso, lasciando comunque la possibilità di ricevere aiuto dalla comunity tramite forum. Per quanto concerne il resto delle funzioni sono le medesime, in particolar modo è possibile eseguire la profilazione degli utenti e la gestione di totalizzatori esportabili. Gargiulo Marco 566/1465 Pagina 32 di 135 3 Analisi dei Requisiti nel caso di studio In questo capitolo sono descritti i requisiti generici funzionali e non funzionali di un sistema di gestione presenze per poi soffermarci su quelli implementati. 3.1 Analisi dei requisiti funzionali I requisiti funzionali rappresentano le caratteristiche delle operazioni eseguibili tramite l'applicazione web. Innanzitutto si è scelto di implementare il software di gestione delle presenze in ambiente web, in quanto quest'ultimo è raggiungibile da ogni posto che abbia il collegamento con la rete. Interfaccia di front-end: Da utilizzare in monitor touch-screen (terminali orologio (dove se ne prevede l’installazione) o, in assenza, tramite Personal Computer e/o dispositivo compatibile) come chiosco fisso per la timbratura, azione che deve essere rapida, per far fronte ad eventuali code causate da orari di lezioni. Graficamente deve essere minimale, con tastierino numerico per l'identificazione dell'utente e un orologio con orario corrente. Questa schermata dev'essere raggiungibile da ogni computer connesso alla LAN universitaria, in questo modo studenti e docenti, terminato l'orario di lezione, possono timbrare l'uscita direttamente dalla loro postazione. ● L’orario di rilevazione deve essere quello dei sistemi centrali di elaborazione ● Interoperabilità con il modulo “Gestione Presenze” e con il sistema di gestione documentale ● Bisogna prevedere, con cadenza definita e concordata, il caricamento delle registrazioni relative alle timbrature provenienti dai vari terminali orologio sia con le relative codifiche giustificative che con gli orari di ingresso e di uscita ● Deve essere possibile visualizzare tutte le ore effettive per ogni giorno lavorativo attraverso la consultazione di un cartellino elettronico capace di Gargiulo Marco 566/1465 Pagina 33 di 135 accettare imputazioni esterne sia a livello individuale che per gruppi omogenei di studenti per la correzione delle anomalie segnalate e per la verifica dei totali su base giornaliera, mensile, semestrale, annuale Area personale: Accessibile da ogni computer collegato alla rete interna dell’università tramite autenticazione con username e password, modificabili dal possessore in ogni momento attraverso l'area personale e in caso di dimenticanza l'utente si rivolgerà alla segreteria per la modica. In questa sezione possono essere invocate le funzioni alle quali l'utente connesso ha accesso, a seconda del suo ruolo. Utenti amministratori hanno la possibilità di accedere a tutti i dati presenti e di modificarli Utenti normali: d'altro canto hanno accesso solo alla visualizzazione dei propri dati, senza la possibilità di modificarli. Cartellino Funzionalità richiamabile dall'area personale, viene generato un riassunto delle timbrature di un utente in un determinato periodo temporale, con il formato della tabella: Badge Studente Data Ora IN Ora OUT Esportazione: Per ogni cartellino visualizzato dev'essere integrata la possibilità di salvarlo in locale in un file CSV, con le stesse impostazioni di formattazione della tabella soprastante. Gargiulo Marco 566/1465 Pagina 34 di 135 3.2 Analisi dei requisiti non funzionali I requisiti non funzionali rappresentano i vincoli e le caratteristiche di utilizzo che il prodotto deve soddisfare. Software È richiesta una web application accessibile tramite la rete interna dell’università per gestire le timbrature dei docenti e studenti per facilitare le rilevazione delle presenze. Per il mantenimento dei dati deve essere progettato un database apposito. Usabilità L'applicazione deve avere interfaccia intuitiva e di facile comprensione anche per i meno avvezzi alla tecnologia, l'utilizzo deve essere veloce e le funzioni invocabili con pochi e semplici comandi. Scalabilità Il software deve essere sviluppato con strumenti e metodologie che garantiscano una futura aggiunta di funzionalità o operazioni sui dati, a tale scopo viene raccomandato l'utilizzo di software Open-Source. Efficienza ed efficacia Le funzioni implementate devono avere tempi di risposta brevi, soddisfacendo le richieste dell'utilizzatore con i risultati adeguati. Sicurezza I dati confidenziali, come le password, devono essere protetti, inoltre ogni utente può accedere solo ai dati e alle funzioni abilitate per il suo profilo. Utenti Hanno un ruolo interno all’università che ne identifica i privilegi. Inizialmente sono richiesti i profili Utente e Amministratore, ma nulla vieta aggiunte future, a seconda delle esigenze interne. Timbrature Ognuna appartiene ad un singolo utente e deve contenere informazioni su data e ora di creazione. Si distinguono 2 tipi principali: Ingresso e Uscita, ma non bisogna precludere la possibilità di aggiungerne altri a discrezione dell’università. Gargiulo Marco 566/1465 Pagina 35 di 135 3.3 Analisi dei requisiti nel caso di studio di un corso di formazione a frequenza obbligatoria. I requisiti funzionali cioè le funzionalità e i servizi offerti dal sistema sviluppato. 3.3.1 Attori del Sistema e Casi d'uso Come illustrato nella figura 2.1, il sistema innanzitutto deve garantire un'interfaccia atta alla raccolta delle timbrature senza restrizioni di utenza, in secondo luogo deve essere raggiungibile un'area ristretta, tramite login, nella quale si distinguono le diverse funzionalità disponibili per gli studenti, docenti,amministratori. Illustrazione 7 : Use Case1 Interfaccia di Front-end Ovvero una pagina web adatta ad essere visualizzata in monitor touch-screen fissi con l'unica funzione di raccogliere le timbrature degli utenti in entrata e in uscita. Sarà composta da un tastierino numerico di dimensioni ragionevoli, un display dove visualizzare il codice che si sta inserendo, un tasto per eliminare l'ultimo carattere e i Gargiulo Marco 566/1465 Pagina 36 di 135 tasti per confermare le timbrature, inoltre sarà presente un orologio digitale come riscontro dell'ora attuale. Al momento della timbratura il software dovrà controllare nel database degli utenti registrati la presenza del codice inserito, in caso affermativo verrà stampato a schermo un messaggio di avvenuta marcatura per l'utente, in caso contrario una notifica di errore. Dal momento che questa pagina web dovrà rimanere fissa in un chiosco, non dovranno esserci possibilità di re-indirizzamento o di apertura di nuove finestre, al contrario bisogna garantire un'alta velocità di timbratura. Login Dopo una prima fase iniziale “registrazione utente”,l'accesso per le aree ristrette avverrà tramite badge di identificazione e password, scelta in base alle preferenze dell'utente, Una volta effettuato e confermato l'accesso seguirà la prolazione dell'utente, ovvero l'assegnazione dei privilegi garantiti per la categoria di appartenenza del soggetto. Area personale Sarà accessibile dagli utenti che hanno effettuato il login, in questa pagina potranno richiamare la funzione per la generazione del cartellino personale. In questo modo verrà aperta la possibilità di controllare le proprie presenze in un periodo temporale a scelta e con un pulsante apposito sarà possibile esportare i dati in un file CSV, ovvero in foglio di calcolo elettronico, utilizzabile con programmi come Microsoft Office Excel o OpenOffice Calc. Infine l'utente potrà modificare le proprie credenziali di accesso, cioè username e password, e terminata la sessione si potrà disconnettere tramite il pulsante di “logout“. Gargiulo Marco 566/1465 Pagina 37 di 135 3.3.2 I casi d’uso per lo studente Il sistema di gestione delle presenze sviluppato, offre diverse funzionalità ad uno studente. Egli dopo aver effettuato il “login” potrà effettuare le seguenti operazioni: Attore Caso D’uso Studente Visualizza Corsi Iscritti Visualizza Corsi Non Iscritti Eliminare iscrizione ad un corso Iscriversi ad un corso Visualizza dettagli su di un corso al quale è iscritto Visualizza Propria Anagrafe Modifica Propria Anagrafe Visualizza Sessioni Aperte Effettua Timbratura in Entrata Effettua Timbratura Uscita 3.3.3 I casi d’uso per il docente Un docente dopo aver effettuato il “login” potrà effettuare le seguenti operazioni: Attore Caso D’uso Docente Visualizza Propri Corsi Inserisce Nuovo Corso Elimina un proprio Corso Visualizza Iscritti ad un corso Visualizza Propria Anagrafe Modifica Propria Anagrafe Aprire una Sessione Chiudere Una sessione Visualizza Dati Sessioni Gargiulo Marco 566/1465 Pagina 38 di 135 Illustrazione 8 : Use Case Studente 3.3.4 Spiegazione casi d’uso per lo studente Visualizza Corsi ai quali si può inscrivere: L’utente visualizza un elenco con tutti i corsi, di esami che ancora non ha superato. Visualizza Corsi ai quali è inscritto: L’utente visualizza un elenco con tutti i corsi ai quali è iscritto. Iscrizione ad un corso: L’utente visualizza un form di riepilogo del corso precedentemente selezionato, e ha la possibilità di inscriversi. Visualizza Dettagli Corso: L’utente visualizza le informazioni relative al corso selezionato dall’elenco “Corsi ai quali è inscritto” compreso un riepilogo delle sue presenze/assenze di quel corso. Elimina Iscrizione ad un corso: L’utente visualizza un form con le informazioni di corso precedentemente selezionato, e ha la possibilità di eliminare la sua inscrizione. Visualizza Propria Anagrafe : L’utente visualizza un form di riepilogo dei suoi dati Gargiulo Marco 566/1465 Pagina 39 di 135 anagrafici personali. Visualizza Sessione Aperta : L’utente visualizza un form di riepilogo della sessione di lezione aperta dal docente comprensiva del nome della materia, orario di inizio, orario di fine. Effettua timbratura: L’utente visualizza un form di conferma della timbratura(entrata/uscita) Illustrazione 9: Use Case Docente 3.3.5 Spiegazione casi d’uso per il docente Visualizza Propri Corsi: L’utente con qualifica di docente visualizza un elenco con tutti i corsi, di cui è titolare di cattedra. Elimina un Corso: : L’utente con qualifica di docente elimina un corso dall’elenco precedentemente visualizzato. Inserisce nuovo Corso: : L’utente con qualifica di docente inserisce un nuovo corso di Gargiulo Marco 566/1465 Pagina 40 di 135 cui è titolare di cattedra. Visualizza Propria Anagrafe: : L’utente con qualifica di docente un form di riepilogo dei suoi dati anagrafici personali. Modifica Anagrafe: L’utente con qualifica di docente un form nel quale è possibile modificare i suoi dati anagrafici personali. Apre nuova sessione: L’utente con qualifica di docente apre una nuova sessione di lezione. Chiude una sessione: L’utente con qualifica di docente chiude una nuova sessione di lezione. Visualizza Iscritti ad un corso: L’utente con qualifica di docente visualizza un form di riepilogo con i dati degli studenti iscritti ad un corso di cui è titolare di corso. Visualizza Dati Sessione Aperta: L’utente con qualifica di docente visualizza un form di riepilogo con i dati degli studenti che hanno effettuata la timbratura ad un corso di cui è titolare di corso. 3.4 Definizioni delle tabelle di Cockburn Vediamo nel dettaglio il funzionamento del sistema di autenticazione. Riporto nella tabella di Cockburn relativo al caso d'uso descritto. Gargiulo Marco 566/1465 Pagina 41 di 135 Use Case 1 Goal in Context Preconditions Success End Condition Failed End Condition Primary Actor Secondary Actor Trigger Description 1 2 N° Step 1 2 3 3 4 4 Extension A Username mancante o incorretta 4.A Extension B Password mancante o incorretta Gargiulo Marco 566/1465 5.A 4.B Login L'utente seleziona la funzionalità di login Connessione al server, L'utente deve già essersi registrato al servizio L'utente riesce ad effettuare il login L'utente non riesce ad effettuare il login Utente Sistema Pressione, con il dispositivo puntatore, sul tasto “Accesso nel Servizio numero2 ” dal menu fisso. Utente Sistema Trigger Visualizza Form Autenticazione Compila il Form di Autenticazione e preme il tasto “Invia Dati” Visualizza Form “Benvenuto nel Sistema” Visualizza popup errore “Username mancante o incorretta” Clicca il tasto “ok” Visualizza popup errore “Password mancante o incorretta” Pagina 42 di 135 Use Case 2 Goal in Context Preconditions Success End Condition Failed End Condition Primary Actor Secondary Actor Trigger Description Extension A Username mancante Extension B Password mancante Extension C Nome Utente mancante Crea nuovo Account L'utente vuole creare un nuovo account Connessione al server L'utente riesce ad creare un nuovo account L'utente non riesce ad creare un nuovo account Utente Sistema Pressione, con il dispositivo puntatore, sul link “Non sei ancora registrato?” dal menu fisso. N° Step Utente Sistema 1 Trigger 2 Visualizza Form Registrazione 3 Compila il Form di Registrazione e preme il tasto “Invia Dati” 4 Visualizza Form “Login effettuato con successo” 4.A Visualizza pop-up errore “Username mancante” 5.A 6.A 4.B Clicca il tasto “ok” 5.B 6.B 4.C Clicca il tasto “ok” Torna allo step numero 2 Visualizza pop-up errore “Password mancante” Torna allo step numero 2 Visualizza pop-up errore “Nome utente mancante” Clicca il tasto “ok” Extension D Data di Nascita Errata Torna allo step numero 2 Visualizza pop-up errore “Data di nascita errata” 4.D 5.D 6.D Gargiulo Marco 566/1465 Clicca il tasto “ok” Torna allo step numero 2 Pagina 43 di 135 Extension E Selezione congiunta comuneprovincia non valida 4.E 5.E Visualizza pop-up errore “Comune di Nascita errato” Clicca il tasto “ok” 6.E Torna allo step numero 2 4.F Visualizza pop-up errore “Conferma Password mancante” Extension F Conferma Password mancante Extension G Conferma Password non corrisponde nte Extension H Nome utente già esistente 5.F 6.F 4.G Clicca il tasto “ok” 5.G 6.G 4.H Clicca il tasto “ok” 5.H 6.H Clicca il tasto “ok” Gargiulo Marco 566/1465 Torna allo step numero 2 Visualizza pop-up errore “Conferma Password non corrisponde alla password inserita” Torna allo step numero 2 Visualizza pop-up errore “Nome Utente già in uso” Torna allo step numero 2 Pagina 44 di 135 Use Case 3 Goal in Context Preconditions Success End Condition Failed End Condition Primary Actor Secondary Actor Trigger Description L'utente non riesce a cambiare la propria password Studente Sistema Lo studente seleziona dal menù laterale l'opzione “cambia password” N° Step 1 2 Utente Trigger 3 L'utente compila il form e clicca il tasto “Invia Dati” 4 Extension A Dati Mancanti Extension B Password non corrisponden ti Cambio password Lo studente vuole cambiare il cambio di password Utente loggato al sistema L'utente riesce a cambiare la propria password 4.A 4.B Gargiulo Marco 566/1465 Sistema Mostra form “cambiamento di password” Mostra messaggio “password cambiata con successo” Visualizza pop-up errore “Campi non inseriti correttamente” Visualizza pop-up errore “Password non corrispondenti” Pagina 45 di 135 use Case 4 Goal in Context Preconditions Success End Condition Failed End Condition Primary Actor Secondary Actor Trigger Description Extension A Lo studente non si è ancora iscritto a nessun corso N° Step 1 2 2.B Gargiulo Marco 566/1465 Visualizza registrazione Lo studente vuole visualizzare i corsi ai quali si è registrato Utente loggato al sistema in qualità di studente L'utente riesce a visualizzate ile proprie registrazioni L'utente non riesce a visualizzate ile proprie registrazioni Studente Sistema Lo studente seleziona dal menù laterale l'opzione “visualizza registrazioni” Utente Trigger Sistema Mostra form con i dati relativi ai corsi ai quali lo studente si è inscritto. Visualizza pop-up errore “Non ti sei inscritto a nessun corso” Pagina 46 di 135 Use Case 5 Goal in Context Preconditions Success End Condition Failed End Condition Primary Actor Secondary Actor Trigger Description Extension A Lo studente non ha ancora registrato presenza N° Step 1 2 2.B Gargiulo Marco 566/1465 Consultazione presenze Lo studente vuole visualizzare le presenze riportate in una materia Utente loggato al sistema in qualità di studente L'utente riesce a visualizzate le proprie presenze L'utente non riesce a visualizzate ile proprie presenze Studente Sistema Lo studente seleziona dal menù laterale l'opzione “consulta le tue presenze” Utente Trigger Sistema Mostra form con i dati relativi ai giorni e orari ai quali lo studente è stato presente a lezione Visualizza pop-up errore “Non hai ottenuto nessuna ora di lezione per l'insegnamento prescelto” Pagina 47 di 135 Use Case 6 Goal in Context Preconditions Success End Condition Failed End Condition Primary Actor Secondary Actor Trigger Description Extension A L'orario di sistema è maggiore di quello di inizio della lezione Timbratura in ingresso Lo studente vuole effettuare la presenza in ingresso ad una lezione. Utente loggato al sistema in qualità di studente e non ha altre sessioni aperte L'utente riesce a effettuare la presenza in ingresso L'utente non riesce a effettuare la presenza in ingresso Studente Sistema Lo studente seleziona l'opzione “prendi presenza in ingresso” N° Step Utente 1 Trigger 2 3 Inserisce parola segreta e preme il tasto invio 4 4.B Gargiulo Marco 566/1465 Sistema Mostra form con parola segreta Mostra messaggio avvenuta registrazione di presenza Visualizza pop-up errore”Sei arrivato troppo tardi” Pagina 48 di 135 Use Case 7 Goal in Context Preconditions Success End Condition Failed End Condition Primary Actor Secondary Actor Trigger Description Extension A Lo studente non si è ancora iscritto a nessun corso N° Step 1 2 2.B Gargiulo Marco 566/1465 Visualizza corsi attivi Lo studente vuole visualizzare i corsi ai quali si può registrare Utente loggato al sistema in qualità di studente L'utente riesce a visualizzate ile proprie registrazioni L'utente non riesce a visualizzate ile proprie registrazioni Studente Sistema Lo studente seleziona dal menù laterale l'opzione “visualizza registrazioni” Utente Trigger Sistema Mostra form con i dati relativi ai corsi ai quali lo studente si è inscritto. Visualizza pop-up errore “Non ti sei inscritto a nessun corso” Pagina 49 di 135 4. Gli strumenti utilizzati 4.1 Il progetto Liferay Un portale d'informazione aziendale noto è l'Enterprise Information Portal. E' una struttura che consente di integrare informazioni, persone e processi attraverso spazi organizzativi. Esso offre un punto di accesso unificato e sicuro, spesso nella forma di un'interfaccia utente basata sul web, disegnato per aggregare e personalizzare informazioni attraverso le “portlet”. Nel 2001 è nato Liferay, un Enterprise Portal candidato ad aiutare le organizzazioni a collaborare in un modo più efficiente mettendo a disposizione una serie consolidata di applicazioni pronte all'uso. Utilizzato da piccole, medie e grandi aziende in tutto il mondo presenta inoltre un elenco di funzionalità tali da metterlo a confronto con altri portali commerciali con il vantaggio di non avere oneri di licenza. Svolge la funzione di Web Container, permettendo di considerare una pagina come un'aggregazione di moduli web, destinati a contenere applicazioni. Nel contesto applicativo possiamo dire che Liferay implementa le portlet, che costituiscono una interfaccia facile da modificare, ma anche fornendo applicazioni pronte all'uso. Infatti esso è un portale web open source basato sulla tecnologia JAVA J2EE, consente di impiegarlo insieme a differenti application server, database e sistemi operativi. Tra le proprietà basilari ci sono: ● Java Server Face con l'utilizzo di JSR 252 ● Java Management Extension (JMX) 1.2 ● Full J2EE 1.4 associato con JBoss AS ● Portlet Specification and API 1.0 (JSR-168) ● Web Services for Remote Portlets (WSRP) 1.0 Base Level A questi si aggiungono alcune caratteristiche specifiche che lo contraddistinguono: Gargiulo Marco 566/1465 Pagina 50 di 135 ● Elevata dinamicità, permettendo di creare, rimuovere e modificare portlet, temi/layout finestre impostazioni di sicurezza a runtime ● IPC (Interportlet communication) notevolmente irrobustita attraverso un'organizzazione gerarchica delle portlet ● Temi e Layout pluggabili Liferay si basa su un'architettura orientata ai servizi denominata (SOA). Con SOA (Service Oriented Architecture) si va ad indicare un'architettura software usata per supportare l'utilizzo di Web Service e per assicurare l'interoperabilità tra diversi sistemi, in modo tale da consentire l'uso delle singole applicazioni come parte dell'intero processo gestionale. Le applicazioni, in questo modo, sono frutto dell'unione di più servizi, che tra di loro risultano essere indipendenti garantendo il massimo della riusabilità. La scelta ricade su Liferay in quanto offre una grande quantità di servizi integrati di qualità ed un'ottima flessibilità. Tutto questo si va ad includere con una grande capacità di organizzare e il supporto alla collaborazione. Liferay Portal Server è di fatto un Portlet Engine che viene distribuito come "Enterprise Archive" (EAR) all'interno di JBOSS Application Server: questo gli consente di potersi avvalere in maniera trasparente di tutti i vantaggi apportati dalla suite JEMS: ● Disponibilità di un potente ORM quale Hibernate ● Autenticazione JAAS ● Caching ● Architettura in cluster ● Hot deployment delle portlet ● Soluzioni di SSO/LDAP ● Business Process Management & Business Rules ● Gestione di transazioni distribuite ● Enterprise messaging (JMS) Gargiulo Marco 566/1465 Pagina 51 di 135 Dalla figura sottostante si denota che il portale presenta un'interfaccia utente molto semplice e chiara organizzata in modo tale da aiutare lo sviluppatore alla finalizzazione del compito da effettuare. Illustrazione 13 : Home Page Liferay Per poter iniziare ad inserire le pagine create bisogna accedere in qualità di amministratori inserendo lo username e la corrispondente password. Dopo la fase di autenticazione con l'immissione delle proprie credenziali il sistema passa ad uno stato che consente la creazione delle pagine, in cui eventualmente possono essere inseriti i codici del servizi web. L'inserimento di un nuovo contenuto web (pagina web, libreria multimediale o anche servizio web) è un'operazione molto semplice: basta selezionare l’opzione Add dal pannello di controllo. Nel caso di inserimento di un servizio web è possibile utilizzare l'oggetto iFrame e inserire al suo interno il codice del servizio sviluppato. Gargiulo Marco 566/1465 Pagina 52 di 135 Illustrazione 20 : Selezione New Frame Una volta caricato il progetto viene visualizzato a video l'homepage della nostra applicazione con la doppia opzione se si è già registrati al sistema o meno. Gargiulo Marco 566/1465 Pagina 53 di 135 4.2 I Portali “I Portali Web” si propone come un testo divulgativo, scritto con linguaggio accessibile ai non specialisti ma al tempo stesso approfondito e aggiornato, e che si rivolge a chiunque voglia sapere qualcosa di più su di uno strumento. Il portale è un servizio che opera da mediatore di informazioni a favore degli utenti della rete, consentendo agli utilizzatori di raggiungere una grande quantità di informazioni attraverso un prestabilito punto d'ingresso nella rete. Non è facile determinare un'unica definizione per questo termine, che pur essendo recente, è uno dei più diffusi ed utilizzati. Il portale è un punto di accesso unico ad un insieme di servizi, dati e applicazioni. Facilita il lavoro di ricerca essendo un aggregatore di informazioni e mettendo a disposizione un servizio di navigazione sulla rete. Principalmente ha il compito di favorire la collaborazione, la gestione dei contenuti e l'aggregazione di applicazioni. Il “Portale”, molto importante per la navigazione tra le risorse di Internet ma sul quale ben poche pubblicazioni, a parte quelle specialistiche, approfondiscono storia, caratteristiche e prospettive. La capacità di integrazione fa del portale uno strumento con enormi potenziale. Dal punto di vista dell'interfaccia utente, indipendentemente dalla soluzione d'integrazione scelta, un portale può svolgere il ruolo importante dell'integrazione delle applicazioni o dei servizi costituenti un sistema informativo. In questo modo l'utente potrà accedere alla medesima interfaccia in modo facile e personalizzato a diverse sorgenti d'informazione. Inoltre un portale è un ottimo gestore di contenuti. L'informazione, disponibile sotto varie forme multimediali, testo, foto o video, viene organizzata ed integrata per permettere all'utente di accedere in modo efficace ed omogeneo ad un argomento di suo interesse. Per gestire l'eterogeneità dei contenuti da pubblicare viene utilizzato un Gargiulo Marco 566/1465 Pagina 54 di 135 CSM(Content Management System), capace di garantire un simile risultato grazie alle sue funzionalità gestionali. Grazie al CSM ogni utente è capace di gestire interattivamente i propri spazi e i propri contenuti. Dal punto di vista della collaborazione è importante sottolineare che un portale è in grado di fornire i tipici strumenti utilizzati da un team di lavoro. Instant messaging, mail, message board, shared calendar e wiki sono strumenti utilizzabili all'interno di un portare per favorire la collaborazione di un team di lavoro in una rete aziendale. Come vedremo in seguito una piattaforma per la realizzazione di portali di alto livello abilita con un unico strumento la aggregazione di applicazioni, la possibilità di pubblicate contenuti e le funzionalità per la collaborazione tra gli utenti. È evidente che tutte queste possibilità insieme aprono scenari infiniti al progettista web, molto più vasti di quelli tipici di una applicazione web verticale e quindi anche più complessi da affrontare e da indirizzare correttamente per ottenere risultati efficaci e di reale utilità per gli utenti. Le persone si connettono sul Web per le più svariate attività, dal lavoro allo svago e i Portali in questo scenario rappresentano non soltanto dei veri e propri organizzatori di risorse ma anche dei “Centri Servizi”. Le prospettive di sviluppo e di utilizzo della “Rete” sono in velocissima crescita e gli strumenti offerti dai Portali saranno sempre più indispensabili ai “naviganti” . Una definizione di "portale" può essere : "una porta web-based che consente agli utenti di: ● Localizzare risorse, ● Usufruire di servizi, ● Usare applicazioni produttive necessarie di internet o di intranet . Molti portali sono costruiti e manutenuti con componenti software dinamici chiamati portlet. I portali di qualità ed efficienza sono di generalità diverse : Gargiulo Marco 566/1465 Pagina 55 di 135 ● Alcuni forniscono una ampia gamma di prestazioni, servizi, contenuti e collaborazioni commerciali o culturali, ● Alcuni sono concentrati su servizi ed argomenti specialistici o su una fascia particolare di utenti e presentano strumenti quali motori di ricerca, liste di discussione, ● In tutti i casi consentono anche ai loro utenti di personalizzare, alcune loro contenuti. Alcuni esempi di portali : Liferay portal, Pluto, uPortal, Sun portal. 4.2.1 La struttura dei portali Il portale si prefigura come lo strumento principale per la gestione e l'integrazione informativa all'interno di una qualsiasi impresa. L'obiettivo principale è rendere l'informazione accessibile e pertinente aiutando l'azienda ad incrementare i guadagni tramite un più rapido ed efficiente accesso ai dati. Le varie proposte commerciali comprendono ambienti molto complessi, per adesso ci soffermiamo a spiegare quali sono gli elementi standard che costituiscono un portale. Principalmente un buon Enterprise Information Portale (EIP) deve fornire due tipologie di servizi: 1. L'integrazione tra dati, applicazioni, e sorgenti diversi e non necessariamente localizzati uniformemente. 2. La personalizzazione dello strato di presentazione dei contenuti e delle interfacce dell'ambiente lavorativo. In “rete” possiamo trovare molti esempi di portali: quello forse più conosciuto è Gargiulo Marco 566/1465 Pagina 56 di 135 Yahoo.com partito come motore di ricerca questo sito fornisce ora servizi diversi quali email, newsgroup, forum e altri servizi d'informazione. L'utente si potrà trovare ogni volta che si autentifica un ambiente familiare e configurabile secondo le sue esigente, avendo un rapido accesso alle informazioni che più gli interessano. In un qualsiasi portale all'utente si darà la possibilità di operare modifiche su due aspetti: ● Personalizzazione ● Configurazione A prima vista il livello di configurazione e di personalizzazione possono apparire analoghi, ma operano su due contesti differenti. Procediamo ora a descrivere le caratteristiche. Personalizzazione Il concetto base è quello di differenziare i contenuti e l'aspetto presentativo a seconda del ruolo che il visitatore ricopre all'interno dell'ambiente di lavoro. All'inizio si propone una richiesta di autenticazione tramite la quale l'utente accede al portale inserendo uno username ed una password all'interno di un'area preposta al Login. Dopo l'autenticazione all'utente verranno presentati contenuti mirati e limitati dal suo status all'interno della gerarchia del portale. Ad esempio, all'interno di un'azienda all'amministratore verrà presentato uno spettro informativo maggiore di quello che verrà presentato all'impiegato medio. Questo serve a fornire solo le informazioni veramente utili all'utente, scartando quello che non gli è necessario. Gargiulo Marco 566/1465 Pagina 57 di 135 Configurazione Ad ogni utente verrà permesso di manipolare la propria area e adattarla alle proprie esigenze determinando la struttura del profilo sul portale. E' importante notare che il termine inglese utilizzato non è configuration ma bensì customization che rende maggiormente l'idea di una riconfigurazione personale dell'aspetto presentativo dei contenuti. Viene infatti fornita la possibilità di: ● Gestire i layout/template del proprio profilo, quindi i colori, i caratteri e tutti gli aspetti prettamente estetici del portale. ● Aggiungere e rimuovere i servizi e le fonti d'informazione messi a disposizione dal portale a seconda del ruolo riconosciuto all'utente dopo il Login. Da questo punto di vista si parla sempre di personalizzazione, decisa dall'utente e non dall'amministratore del portale. Questi aspetti che abbiamo elencato sono relativi al rapporto tra il visitatore del portale e l'utilizzo che esso può farne. E' utile tenere conto che la vera capacità del portale è quella di proporsi come strumento conoscitivo, quindi come un oggetto utile per la ricerca e organizzazione dei contenuti. Un portale concorrenziale deve essere in grado di recuperare informazioni tramite l'accesso a diverse sorgenti di dati. La capacità di radunare i dati e portarli in maniera adeguata viene identificata sotto il nome di aggregazione di contenuti. Le sorgenti di dati possono essere suddivise in: ● Basi di dati e sistemi transazionali ● Documenti e contenuti non strutturali ● Servizi e fonti sul Web E' necessario quindi un sistema applicativo che riesca ad occuparsi del recupero Gargiulo Marco 566/1465 Pagina 58 di 135 intelligente di questi dati. Con “recupero intelligente” intendiamo la capacità di riuscire a fornire contenuti essenziali e mirati da un enorme mole di dati. 4.3 Java Portlet e Portlet Container Iniziamo ad entrare nel mondo Java ed a esaminare ciò che la piattaforma offre per la realizzazione di portali. In questo ambito vi è stata una grande evoluzione negli ultimi anni e da una situazione di immaturità e incompletezza di specifiche e strumenti si è arrivati oggi a una situazione in cui si può realmente dire di avere a disposizione standard e tecnologie che consentono di realizzare portali web in modo efficiente e completo. Il tutto ha le sue fondamenta nelle Java Portlet che è l’argomento che ci accingiamo a discutere. La Java Portlet Specification 1.0 definita nell’ambito della JSR 168 fu rilasciata nell’ottobre 2003. Questa è stata la prima specifica che definiva molti aspetti sulle portlet ed ebbe una notevole importanza perché diede una prima standardizzazione a un ambito che fino ad allora era andato sviluppandosi senza seguire una linea comune. La specifica, sebbene costituisse un primo passo verso la standardizzazione, non copriva molti importanti aspetti. A febbraio 2006 fu costituito il JSR 286 Expert Group al fine di arrivare alla Java Portlet Specification 2.0 rilasciata nel giugno 2008 che costituisce lo standard attuale per le portlet, le cosiddette Portlet 2.0. Vediamo meglio come possiamo definire una Portlet. Esistono definizioni diverse più o meno rigorose da un punto di vista tecnico ma quella forse più semplice e di immediata comprensione è la seguente: una portlet è una applicazione web che viene eseguita in una porzione di una pagina web. Il paradigma di funzionamento di una portlet è analogo a quello di una servlet visto che parliamo sempre di un modello richiesta/risposta. Chi ha familiarità con le servlet, e con le JSP, sa però che questi componenti sono Gargiulo Marco 566/1465 Pagina 59 di 135 responsabili del rendering di una intera pagina web. Con le portlet il discorso cambia poiché una singola portlet con le sue funzionalità è responsabile solo di una porzione dell’intera pagina web. Possiamo quindi pensare alle portlet come a tanti mattoncini che messi insieme vanno a costituire la nostra pagina web. Ecco le principali differenze tra portlet e servlet: ● Sono componenti più semplici e quindi più leggeri, ciò consente una maggior facilità di gestione. ● Non possono essere raggiunte da un url specifico, in quanto è il portale interno ad avere associato l'indirizzo. ● Non posseggono la comunicazione con il browser, quindi non permettono di inviare redirect o errori Non possono rappresentare pagine web complete, ma solo singoli componenti. Illustrazione 59: Esempio di Portlet di una pagina web Affinché le portlet possano essere eseguite, è necessario un ambiente dedicato, un container, il portlet container, che è il corrispondente di ciò che è il servlet container Gargiulo Marco 566/1465 Pagina 60 di 135 per le servlet. È il portlet container che assolve ai compiti infrastrutturali necessari al corretto funzionamento di questi elementi di interfaccia detti portlet. Da un punto di vista del deployment, una portlet non è altro che una web application, un .WAR per intenderci, molto simile a una normale web application ma ovviamente con alcune specificità. Con le portlet è possibile comporre in un’unica pagina funzionalità distinte che operano su sorgenti dati diverse. Ciò consente di aggregare, in una interfaccia omogenea, dati e applicazioni eterogenee senza costringere l’utente a viaggiare tra applicativi diversi per eseguire le funzionalità di cui ha bisogno. Il Portlet Container fornisce alle portlet il necessario ambiente di esecuzione, inoltre fornisce loro il contesto, gestendo il loro ciclo di vita e infine il comportamento. E' il container ad istanziare le portlet prima che vengano richieste e lanciare eccezioni se qualcosa va male. Il portal server esegue il lavoro finale di aggregazione delle portlet application e delle singole portlet. In particolare il portal server esegue la spedizione delle request e tute le portlet contenute in una singola pagina svolgendo quindi il lavoro di orchestrazione e coordinamento. La generazione di una pagina di un portale avviene attraverso questi fondamentali passi: ● Il contenuto per gli utenti, statico o dinamico, dipendente dalla logica dell'applicazione della portlet, viene generato da ogni portlet. ● Il portlet container riceve i dati generati dal server portlet. ● Il container manipola le informazioni per il server portal. ● Il server portal ha il compito della creazione della pagina del portale, costituita essenzialmente da codice HTML generato automaticamente utilizzato dal Gargiulo Marco 566/1465 Pagina 61 di 135 browser. In base alle scelte di layout che ciascun portlet si porta dietro, il server portal le applica per una corretta visualizzazione. ● La pagina creata viene inviata dal server al browser. ● L'utente può visualizzare il contenuto nel browser. La pagina è pronta per effettuare interazioni con l'utente. 4.3.1 Gli standard per sviluppare una portlet Come abbiamo già detto, per sviluppare una portlet occorre rispettare due standard : La Java Portlet Specification (JSR168) che definisce un set (insieme) di interfacce appplicative (API) per l'interoperabilità fra un portlet container e i portlet; una implementazione molto diffusa della specifica JSR168 Apache Pluto, ma anche altri portali open source come Liferay, uPortal, Stringbeans portal , ed altri sviluppi da IBM, Oracle,.. Lo standard WSPR (Web Services for Remote Portlets) definisce un protocollo standard per il dialogo fra il portale e i portlet. 4.4 Java Server Pages (JSP) Apache Tomcat è un Servlet/JSP engine che non fa altro che contenere ed eseguire le applicazioni Java Servlet e Java Server Page (JSP). Non è l'unico Application Server per Servlet/JSP, ma di sicuro è libero ed è il contenitore di servlet utilizzato nell'implementazione ufficiale di riferimento per il Java Servlet e le tecnologie Java Server Page sviluppate dalla Sun Microsystems. Le Java Server Pages di solito indicato con l'acronimo JSP (letto anche talvolta come Java Scripting Preprocessor) è una tecnologia Java per lo sviluppo di applicazioni Web che forniscono contenuti dinamici in formato HTML o XML. Si basa su un insieme di speciali tag con cui possono essere invocate funzioni predefinite o codice Java (JSTL). In aggiunta, permette di creare librerie di nuovi tag che estendono l'insieme dei tag standard (JSP Custom Tag Library). Le librerie di tag JSP si possono considerare estensioni indipendenti dalla piattaforma Gargiulo Marco 566/1465 Pagina 62 di 135 delle funzionalità di un Web server. Nel contesto della piattaforma Java, la tecnologia JSP è correlata con quella delle servlet. All'atto della prima invocazione, le pagine JSP vengono infatti tradotte automaticamente da un compilatore JSP in servlet. Una pagina JSP può quindi essere vista come una rappresentazione ad alto livello di un servlet. Per via di questa dipendenza concettuale, anche l'uso della tecnologia JSP richiede la presenza, sul Web server, di un servlet container, oltre che di un server specifico JSP detto motore JSP (che include il compilatore JSP); in genere, servlet container e motore JSP sono integrati in un unico prodotto (per esempio, Tomcat svolge entrambe le funzioni). 4.4.1 Come funzionano le JSP Ogni volta che arriva una request, server compone dinamicamente il contenuto della pagina. Ogni volta che incontra un tag <%...%> valuta l’espressione Java contenuta al suo interno inserisce al suo posto il risultato dell’espressione Questo meccanismo permette di generare pagine dinamicamente . 5 Dettagli implementativi realizzata della soluzione software In questo capitolo sono descritti i servizi che costituiscono il sistema di gestione delle presenze, organizzati logicamente in servizi generali, servizi per lo studente e servizi per il docente. 5.1 Servizi generali 5.1.1 Servizio di autenticazione Illustrazione 23 : homepage Gargiulo Marco 566/1465 Pagina 63 di 135 Se si è un utente già registrato al sistema verrà visualizzato a video il form di autenticazione con la richiesta del numero di badge e la password. Illustrazione 24: Form di login L'illustrazione sottostante apparirà nel caso l'utente sbagli a digitare il suo username nel form di login. Illustrazione 32: Credenziali non valide 1 L'llustrazione sottostante apparirà nel caso l'utente sbagli a digitare la sua password nel form di login. Gargiulo Marco 566/1465 Pagina 64 di 135 Illustrazione 33: Credenziali non valide 2 Viceversa se l’esito del controllo è positivo verrà visualizzata la seguente schermata nel caso l'utente si sia loggato in qualità di studente: Illustrazione 34: Login eseguito con successo 5.1.2 Iterazione tra il frontend ed il backend del sistema Nel nostro caso abbiamo un form in “html” che richiama una “jsp” <form name="form1" action="verifica7.jsp" method="post" > <p> Username : <input type="text" name="username" size="20"> <p> Password : <input type="password" name="password" maxlength="20" Gargiulo Marco 566/1465 Pagina 65 di 135 size="18" /> </p> <input type="submit" value="Invia Dati"> <input type="reset" value="Annulla"> </form> Il form dell’esempio contiene tre campi di immissione testo (Username, Codice Fiscale, Password) e due bottoni: uno per confermare i dati (Invia Dati), l’altro per resettare il form e quindi cancellare i valori immessi (Annulla). Tutti questi elementi sono definiti utilizzando il tag <INPUT> con valori differenti per “type”: “text” nel caso dei campi testo, “submit” per il bottone di conferma e “reset” per il bottone di cancellazione dati. <form.name="form1".action="verifica7.jsp".method="post" > dove: ● il campo “name” indica il nome del form ● il campo “action” indica l'azione da eseguire ● il campo “method” può essere settato a GET o POST sono due metodi definiti in HTTP . Normalmente GET è usato per ottenere un file o altra risorsa, possibilmente con parametri che specificano più esattamente ciò di cui si ha bisogno. Mentre POST si usa per mandare dati che devono essere processati. Quindi una volta premuto il tasto “submit” viene richiamato “verifica7.jsp” che processerà i dati inseriti nel form. <%@ page language="java" import="java.sql.*" %> <% String user = request.getParameter("username"); String password= request.getParameter("password"); %> Oggetto request rappresenta la richiesta alla pagina JSP. ● È il parametro request passato al metodo service() della servlet ● Consente l’accesso a tutte le informazioni relative alla richiesta HTTP: ● Indirizzo di provenienza, URL, headers, cookie, parametri, ecc. Quindi request.getParameter("username") si richiama il parametro “username” della Gargiulo Marco 566/1465 Pagina 66 di 135 pagina html. Nelle pagine “JSP” è possibile direttamente inserire istruzioni SQL direttamente nel codice. Per accedere al database innanzitutto dobbiamo caricare il gestore di driver: Class.forName("com.mysql.jdbc.Driver").newInstance(); Ed effettuare la connessione al database. Il metodo (statico) per ottenere una connessione al DB è: static Connection getConnection(String,String,String) che prende 3 argomenti: URL, username, password String url="jdbc:mysql://localhost:3306/mgargiulo"; String dbName="root"; String password2="******"; String userName="mgargiulo"; connessione = DriverManager.getConnection (url, dbName, password2); Per poter eseguire le query, dobbiamo poi creare uno statement ,con la connessione appena creata. Statement statement = connessione.createStatement(); Ora abbiamo tutto l'occorrente per effettuare le nostre query richiamando il metodo executeQuery() della variabile statement. String query="SELECT * FROM utenti”; rs = statement.executeQuery(query); Una volta terminato non ci rimane altro che chiudere la connessione e le risorse aperte: rs.close(); Gargiulo Marco 566/1465 Pagina 67 di 135 connessione.close(); 5.1.3 Servizio di registrazione Se invece non si è ancora registrati nel sistema viene visualizzato a video il link per potersi registrare. Illustrazione 25 Link di registrazione Gargiulo Marco 566/1465 Pagina 68 di 135 Una volta acceduti al link di registrazione viene visualizzato il form di registrazione. Illustrazione 26: Form di registrazione Gargiulo Marco 566/1465 Pagina 69 di 135 Dopo la compilazione del form e la conferma della correttezza dei dati inseriti, avviene la fase di controllo di questi ultimi . Nel caso ci siano degli errori, quale “username già in uso ” ci apparirà la seguente schermata. Illustrazione 27: Errore di registrazione 1 Se invece i dati inseriti sono corretti viene visualizzata a video una scheda riassuntiva dei dati inseriti dall’utente. Come si può notare viene calcolato il codice fiscale dell'utente senza l'appoggio di servizi esterni per effettuare una verifica dei dati inseriti dall'utente . Gargiulo Marco 566/1465 Pagina 70 di 135 Ad ogni nuovo utente viene assegnato un numero di badge per identificarlo univocamente. Illustrazione 28: Iscrizione avvenuta con successo Alla fine di tale scheda c’è un link che reindirizza l’utente al form di login. Le informazioni riguardanti gli utenti del servizio vengono memorizzate in un database realizzato in SQL chiamata per appunto utenti. Viene riassunta la struttura della tabella utenti: Gargiulo Marco 566/1465 Pagina 71 di 135 Illustrazione 29: Tabella “utenti” mysql Come si può notare la chiave primaria che caratterizza la tabella è l'attributo badge in quanto due utenti non avranno mai lo stesso numero di badge. Ovviamente inizialmente il database appena creato sarà vuoto in quanto nessun utente ancora ha effettuato la registrazione al sistema e si popolerà man man che ci saranno nuovi utenti al sistema. Illustrazione 30: Select mysql “utenti” 1 Una volta che L'iscrizione è avvenuta con successo come si può notare le informazioni riguardanti il nuovo utente sono state memorizzate ne database utenti. Gargiulo Marco 566/1465 Pagina 72 di 135 Illustrazione 31: Select mysql “utenti” 2 Successivamente all'inserimento da parte dell'utente dei dati, nel form di autenticazione, e la successiva conferma , il sistema controlla se nel database “utenti” esistano tali credenziali. Se l’esito del controllo è negativo verranno stampate a video le possibili schermate. 5.1.4 Servizio di cambio password L'utente loggato in qualità di studente potrà usufruire delle seguenti funzionalità: Potrà cambiare la sua password: Illustrazione 35: Cambio di password Questi sono i rispettivi scenari del cambiamento di password: Gargiulo Marco 566/1465 Pagina 73 di 135 Illustrazione 36: Cambio di password con successo Illustrazione 37: Cambio di password fallita Gargiulo Marco 566/1465 Pagina 74 di 135 5.2 Servizi per lo studente Lo studente potrà visualizzare i corsi ai quali si è registrato: Illustrazione 38: Visualizzazione corsi già registrati Visualizzare i corsi ai quali si può registrare: Illustrazione 39: Iscrizione nuovo corso Gargiulo Marco 566/1465 Pagina 75 di 135 Vedere le lezioni degli insegnamenti ai quali si è inscritto, come si può notare verranno stampate a video le sessioni di lezione che si svolgono nel giorno attuale e nell'orario di sistema rilevato. Una timbratura in ingresso si può registrare in un range di dieci minuti precedenti all'inizio della lezione e a dieci minuti successivi l'inizio della lezione. Illustrazione 40: Timbratura in ingresso Una volta che l'utente ha cliccato sul bottone “Prendi Presenza” apparirà la schermata, richiesta della parola segreta comunicata all'inizio della lezione dal docente. Illustrazione 41: Identificativo lezione Gargiulo Marco 566/1465 Pagina 76 di 135 Lo studente potrà effettuare la registrazione alla lezione (“presenza”) in un range temporale che va da 5 minuti precedenti all'inizio della lezione fino ad un massimo di cinque minuti dopo. Nel caso in cui lo studente si voglia registrare alla lezione dopo di tale soglia, gli apparirà il seguente messaggio: Illustrazione 42: Timbratura fallita Quindi se l'orario attuale del sistema è compreso nell'intervallo inizio della lezione, e l'identificativo della lezione immesso dell'utente è uguale a quello registrato dal docente , lo studente potrà effettuare la timbratura in ingresso: Illustrazione 43: Timbratura effettuata con successo Gargiulo Marco 566/1465 Pagina 77 di 135 Successivamente potrà effettuare la timbratura in uscita: Illustrazione 44: Timbratura in uscita Lo studente una volta effettuata la timbratura in ingresso potrà visualizzare una “reportistica” sulle sue presenze per l'insegnamento prescelto. Illustrazione 45: Riepilogo Presenze Studente Gargiulo Marco 566/1465 Pagina 78 di 135 E potrà effettuare il calcolo totale delle ore di presenza cliccando l'apposito pulsante. Illustrazione 46: Totale Presenze Studente 5.3 Servizi per il docente Se l'utente si è loggato in qualità di docente verrà visualizzata la seguente schermata. Illustrazione 47: Homepage docente Gargiulo Marco 566/1465 Pagina 79 di 135 Potrà inserire un nuovo corso, indicando il nome, i CFU e il numero di ore. Illustrazione 48: Inserimento nuovo corso Potrà vedere i propri corsi già attivati. Illustrazione 49:Visualizzazione Corsi Attivi E per ogni corso attivato potrà visualizzare le lezioni, inserire una nuova lezione, visualizzare l'elenco degli iscritti. Gargiulo Marco 566/1465 Pagina 80 di 135 Illustrazione 50:Funzionalità docente Può vedere il registro delle lezioni di una materia di cui è titolare di cattedra. Illustrazione 51:Calendario Lezioni Gargiulo Marco 566/1465 Pagina 81 di 135 Può inserire una nuova lezione. Illustrazione 52:Inserimento nuova lezione Può visualizzare un elenco con tutti i gli studenti iscritti al proprio corso. Illustrazione 53:Riepilogo iscrizioni studenti Gargiulo Marco 566/1465 Pagina 82 di 135 Può visualizzare una reportistica sul numero di ore di presenza registrate per ogni studente. Illustrazione 54:Registro presenze Gargiulo Marco 566/1465 Pagina 83 di 135 Può calcolarne il totale. Può eliminare un corso. Illustrazione 56:Eliminazione Corso Gargiulo Marco 566/1465 Pagina 84 di 135 Illustrazione 57:Eliminazione Corso con successo Come ho fatto già notare il “servizio” implementato calcola il codice fiscale degli utenti che si iscrivono, senza il supporto di applicazioni esterne. Per poi essere usato nel “form di login”. Per poter calcolarlo si è creata una tabella in SQL denominata “comuni” per ricavare il codice catastale del comune di nascita inserito dall'utente. Illustrazione 58: Tabella comuni Gargiulo Marco 566/1465 Pagina 85 di 135 Conclusioni L'obiettivo di questo lavoro di tesi mi ha permesso di realizzare una “web application” per la gestione delle presenze. L'applicativo creato soddisfa tutti i requisiti, il suo sviluppo ad-hoc ha fatto si che in poco tempo sia stata creata una web application su misura e con tutti i presupposti di modularità e scalabilità per implementazioni future, grazie anche all'utilizzo di soli strumenti Open Source. L'interfaccia finale è chiara e pulita, con pochi pulsanti per le funzionalità, le quali possono essere richiamate in breve tempo e con pochi click. I semplici utenti potranno sempre controllare i loro dati dal proprio computer e generare dei resoconti, nella piena completa trasparenza. L'implementazione del nuovo sistema di timbratura velocizza e ottimizza tutte le azioni ad esso collegate, dalla semplice marcatura di ingresso e uscita ai calcoli per adempiere alle mansioni della segreteria, infatti grazie all'eliminazione del supporto cartaceo vengono ridotti gli errori, velocizzati tutti i processi e salvaguardate tutte le informazioni in modo migliore e sicuro, grazie al database apposito. Gli sviluppi futuri potrebbero riguardare la generazione automatica di altri moduli altrimenti cartacei, la gestione delle ferie di ogni utente, le ore di straordinari, di permessi, di malattia o di maternità. Inoltre potrebbe essere interessante la possibilità di timbrare con dispositivi di prossimità, tramite un sistema di lettura di impronte digitali diminuendo ulteriormente i tempi di timbratura. Gargiulo Marco 566/1465 Pagina 86 di 135 Appendice A Configurazione dell'ambiente di lavoro A.1 Installazione Application Server Apache Tomcat 6 Per installare la versione 6 di Apache Tomcat, disponibile tra i pacchetti di Synaptic, potete seguire questo semplice procedimento. Per cominciare scarichiamo Tomcat 6.0.18 con il seguente comando : $wgethttp://mirror.nohup.it/apache/tomcat/tomcat-6/v6.0.18/bin/apachetomcat6.0.18.tar.gz Scompattiamo: $tarxzvfapache-tomcat-6.0.18.tar.gz Ora decidiamo in quale directory vogliamo che venga salvato Tomcat. Per esempio /usr/local/tomcat, ma qualsiasi cartella va bene. Per spostare nella cartella da noi scelta: $sudomvapache-tomcat-6.0.18/usr/local/tomcat Per usare Tomcat è necessario settare la variabile $JAVA_HOME, per farlo editiamo il nostro file bashrc. Apriamolo digitando : $kate~/.bashrc e aggiungiamo la seguente riga exportJAVA_HOME=/usr/lib/jvm/java-6-sun Ora possiamo avviare Tomcat digitando $/usr/local/tomcat/bin/startup.sh Gargiulo Marco 566/1465 Pagina 87 di 135 e interromperlo $/usr/local/tomcat/bin/shutdown.sh Se volete invece invocare Tomcat senza dover scrivere il path completo potete creare un link simbolico in /usr/local/bin $ln-s/usr/local/tomcat/bin/startup.sh/usr/local/bin/tomcaton $ln-s/usr/local/tomcat/bin/shutdown.sh/usr/local/bin/tomcatoff In tal modo basterà digitare tomcaton per avviare e tomcatoff per interrompere il servizio. Per installare Apache Tomcat 6.0.26, seguire il procedimento appena descritto, con l’unico accorgimento di digitare, dove necessario, 6.0.26 invece di 6.0.18 A.2 Installazione di Liferay in ambiente linux utilizzando apache tomcat 6 e MySQL 5.1 Paths: Per cominciare, impostare i seguenti paths CATALINA_BASE=/usr/share/tomcat6 CATALINA_HOME=/var/lib/tomcat6 Attivazione dei package non-free Prima di procedere all’installazione, è necessario aprire con un editor il file sources.list vi/etc/apt/sources.list e aggiungere il parametro non-free alla fine di ogni riga relativa ai repository principali, dopodiché procedere all’update dei package eseguendo il comando : $aptitude update Impostare Java Runtime Environment (JRE) Per impostare la JRE, lanciare il comando : $update – alternatives – set java/usr/lib/jvm/java-6-sun/jre/bin/java Gargiulo Marco 566/1465 Pagina 88 di 135 A.3 Installazione dei package di Liferay Download di Liferay Eseguire il download dei file ●liferay-portal-6.0.5.war ●liferay-portal-dependencies-6.0.5.zip Spostamento delle dipendencies di Liferay all’interno delle librerie di Apache Tomcat Per spostare le dependencies di Liferay all'interno delle librerie di tomcat, eseguire il comando: $unzip liferay-portal-dependencies-6.0.5.zip $mv liferay-portal-dependencies-6.0.5/*.jar CATALINA_BASE/lib/ext/ Aggiungere la directory ext al path delle librerie di Apache Tomcat Per effettuare l’operazione è necessario aprire il file: CATALINA_HOME/conf/catalina.properties e trovare la riga che comincia con ”common.loader=...” e aggiungere alla fine di tale riga il path seguente: ,${catalina.home}/lib/ext/*.jar Effettuare l’undeploy della webapp di default Eseguire il comando: $rm -rf CATALINA_HOME/webapps/ROOT/* Decomprimere l’achivio WAR di Liferay Per effettuare la decompressione dell’archivio WAR di Liferay è necessario lanciare i comandi $cd CATALINA_HOME/webapps/ROOT $ jar -xf /path/to/liferay-6.0.5.war Gargiulo Marco 566/1465 Pagina 89 di 135 Setup del database MySQL Eseguire lo shutdown di Apache Tomcat con il comando : $servicetomcat6stop Creare database e utente Per creare il database su cui si appoggerà Liferay e la relative utenza, è necessario eseguire I comandi $mysql -p $<InserirelapasswordMySQLdiroot> mysql> CREATE DATABASE lportal DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; mysql>CREATEUSER 'utenteDB'@'localhost' IDENTIFIEDBY 'utenteDBpassword' ; mysql>GRANT ALL PRIVILEGESONl portal.*TO'utenteDB'@'localhost; Impostazioni di base della struttura del database Effettuare,il,download,degli,script,SQL,da http://www.liferay.com/de/downloads/liferay-portal/additional-files e decomprimere l’archivio, quindi cambiare la sottocartella in create-minimal e importare lo script create-minimal-mysql.sql nel database utilizzando il comando $mysql-uutenteDB-plportal<create-minimal-mysql.sql <InserireutenteDBpassword> Configurare Tomcat Per configurare Apache Tomcat si deve modificare (o creare, se non esiste) il file CATALINA_HOME/webapps/ROOT/WEB-INF/classes/portalext.properties Nel modo seguente: jdbc.default.driverClassName=com.mysql.jdbc.Driver jdbc.default.url=jdbc:mysql://localhost/lportal? useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false jdbc.default.username=utenteDB Gargiulo Marco 566/1465 Pagina 90 di 135 jdbc.default.password=utenteDBpassword Copiare il driver JDBC di MySQL Per copiare il driver necessario, lanciare il comando $cp/usr/share/java/mysql-connector-java-5.1.10.jarCATALINA_BASE/lib/ext/ Impostare le E-Mail : Per essere in grado di inviare e-mail utilizzando Liferay, è necessario configurare la connessione SMTP che dovrà essere usata. Per farlo è necessario aggiungere un nuovo child node Resource all’interno del blocco Context del file: “CATALINA_HOME/conf/Catalina/localhost/ROOT.xml “: <Resource name="mail/MailSession" auth="Container" type="javax.mail.Session" mail.transport.protocol="smtp" mail.smtp.host="localhost" mail.store.protocol="imap" mail.imap.host="localhost" /> Configurare JAAS Registrare il Realm di JAAS Per registrare il Realm, è necessario aggiungere un nuovo child node Realm all’interno del blocco Context del file: CATALINA_HOME/conf/Catalina/localhost/ROOT.xml: <Realm className="org.apache.catalina.realm.JAASRealm" appName="PortalRealm" userClassNames="com.liferay.portal.kernel.security.jaas.PortalPrincip al" roleClassNames="com.liferay.portal.kernel.security.jaas.PortalRole" debug="99" useContextClassLoader="false" /> Gargiulo Marco 566/1465 Pagina 91 di 135 Configurare il Realm Per configurare il Realm, si deve creare il file CATALINA_HOME/conf/jaas.config PortalRealm{ com.liferay.portal.kernel.security.jaas.PortalLoginModulerequired; }; Ed editare il file CATALINA_BASE/bin/catalina.sh e, per fare in modo che Tomcat possa riferirlo al login del modulo, aggiungere un nuovo parametro alle JAVA_OPTS: #-----ExecuteTheRequestedCommand----JAVA_OPTS=”$JAVA_OPTS\ -Xms128m\ -Xmx512m\ -Dfile.encoding=UTF8\ -Duser.timezone=GMT\ -Djava.security.auth.login.config=%CATALINA_HOME %/conf/jaas.config” Lanciare Liferay Per lanciare Liferay, eseguire i comandi $tail-fCATALINA_HOME/logs/catalina.out& $servicetomcat6start Lanciare Tomcat Per lanciare Tomcat, eseguire i comandi : Posizionarsi nella directory bin $cdliferay-portal-6.1.0-ce-ga1/tomcat-7.0.23/bin/ $./startup.sh Gargiulo Marco 566/1465 Pagina 92 di 135 Appendice B - Il codice del sistema presenze File “homepage.html” <html> <body> <Center><h3>Dammi le credenziali</h3></Center> <form name="f1" action="verifica7.jsp" method="post" > <p>Numero di badge:<input type="text" name="badge" size="8"></p> <p>Password:<input type="password"</p> <p>name="password"maxlength="20"size="18</p> <input type="submit" value="Invia Dati"> <input type="reset" value="Annulla"> <br><br><br></br></br></br> <a href="registrazione5.jsp"> NON SEI ANCORA REGISTRATO?</a> </form> </body> </html> File “registrazione.jsp” <html> <head> <title>Accesso al Servizio numero2 </title> </head> <body> <div align="center"> <u> Accesso nel Servizio numero2 </u> <u><br />Registrazione </u> <h5> Inserisci le tue credenziali </h5><br /> <form name="f1" action="verifica3.jsp" method="POST" > <div align="center"> <p>Usermane:<input type="text" name="Username" size="20"></p> <p>Nome utente:<input type="text" name="Nome" size="20"></p> <p>Cognome utente:<input type="text" name="Cognome" size="20"></p> <p> Data di nascita : <p> Giorno: <select name='giorno'> <option value = '1' >1 <option value = '2' >2 <option value = '3' >3 <option value = '4' >4 <option value = '5' >5 <option value = '6' >6 <option value = '7' >7 Gargiulo Marco 566/1465 Pagina 93 di 135 <option value = '8' >8 <option value = '9' >9 <option value = '10' >10 <option value = '11' >11 <option value = '12' >12 <option value ='13' >13 <option value = '14' >14 <option value = '15' >15 <option value = '16' >16 <option value = '17' >17 <option value = '18' >18 <option value = '19' >19 <option value = '20' >20 <option value = '21' >21 <option value = '22' >22 <option value = '23' >23 <option value = '24' >24 <option value = '25' >25 <option value = '26' >26 <option value = '27' >27 <option value = '28' >28 <option value = '29' >29 <option value = '30' >30 <option value = '31' >31 </select> Mese: <select name='mese'> <option value = '1' >Gennaio <option value = '2' >Febbraio <option value = '3' >Marzo <option value = '4' >Aprile <option value = '5' >Maggio <option value = '6' >Giugno <option value = '7' >Luglio <option value = '8' >Agosto <option value = '9' >Settembre <option value = '10' >Ottobre <option value = '11' >Novembre <option value = '12' >Dicembre </select> Anno:<select name='anno'> <option value = '1900' >1900 <option value = '1901' >1901 <option value = '1902' >1902 <option value = '1903' >1903 <option value = '1904' >1904 <option value = '1905' >1905 <option value = '1906' >1096 <option value = '1907' >1907 <option value = '1908' >1908 <option value = '1909' >1909 <option value = '1910' >1910 <option value = '1911' >1911 <option value = '1912' >1912 <option value = '1913' >1913 <option value = '1914' >1914 <option value = '1915' >1915 Gargiulo Marco 566/1465 Pagina 94 di 135 <option value = '1916' >1916 <option value = '1917' >1917 <option value = '1918' >1918 <option value = '1919' >1919 <option value = '1920' >1920 <option value = '1921' >1921 <option value = '1922' >1922 <option value = '1923' >1923 <option value = '1924' >1924 <option value = '1925' >1925 <option value = '1926' >1926 <option value = '1927' >1927 <option value = '1927' >1927 <option value = '1927' >1927 <option value = '1929' >1929 <option value = '1930' >1930 <option value = '1931' >1931 <option value = '1932' >1932 <option value = '1933' >1933 <option value = '1934' >1934 <option value = '1935' >1935 <option value = '1936' >1936 <option value = '1937' >1937 <option value = '1938' >1938 <option value = '1939' >1939 <option value = '1940' >1940 <option value = '1941' >1941 <option value = '1942' >1942 <option value = '1943' >1943 <option value = '1944' >1944 <option value = '1945' >1945 <option value = '1946' >1946 <option value = '1947' >1947 <option value = '1948' >1948 <option value = '1949' >1949 <option value = '1950' >1950 <option value = '1951' >1951 <option value = '1952' >1952 <option value = '1953' >1953 <option value = '1954' >1954 <option value = '1955' >1955 <option value = '1956' >1956 <option value = '1957' >1957 <option value = '1958' >1958 <option value = '1959' >1959 <option value = '1960' >1960 <option value = '1961' >1961 <option value = '1962' >1962 <option value = '1963' >1963 <option value = '1964' >1964 <option value = '1965' >1965 <option value = '1966' >1966 <option value = '1967' >1967 <option value = '1968' >1968 <option value = '1969' >1969 <option value = '1970' >1970 <option value = '1971' >1971 <option value = '1972' >1972 <option value = '1973' >1973 <option value = '1974' >1974 <option value = '1975' >1975 <option value = '1981' >1981 <option value = '1976' >1976 <option value = '1982' >1982 <option value = '1977' >1977 <option value = '1983' >1983 <option value = '1978' >1978 <option value = '1984' >1984 <option value = '1979' >1979 <option value = '1985' >1985 <option value = '1980' >1980 <option value = '1986' >1986 <option value = '1987' >1987 <option value = '1991' >1991 <option value = '1988' >1988 <option value = '1992' >1992 <option value = '1989' >1989 <option value = '1993' >1993 <option value = '1990' >1990 <option value = '1994' >1994 <option value = '1995' >1995 <option value = '2001' >2001 <option value = '1996' >1996 <option value = '2002' >2002 <option value = '1997' >1997 <option value = '2003' >2003 <option value = '1998' >1998 <option value = '2004' >2004 <option value = '1999' >1999 <option value = '2005' >2005 <option value = '2000' >2000 <option value = '2006' >2006 <option value = '2007' >2007 <option value = '2008' >2008 <option value = '2009' >2009 <option value = '2010' >2010 </select> </p> Gargiulo Marco 566/1465 Pagina 95 di 135 </p> <p> Sesso: <select name='sesso'> <option value = 'M' >M <option value = 'F' >F </select> </p> <p> Qualifica:<select name='Qualifica'> <option value = 'docente' >Docente <option value = 'studente' >Studente </select> </p> <p> Matricola: <input type="text" name="Matricola" size="20"> </p> <p> Universita': <select name='Universita'> <option value = 'Napoli' >Napoli <option value = 'Bari' >Bari </select> </p> <%@ page language="java" import="java.sql.*" %> <% Connection connessione=null; Statement statement=null; ResultSet rs=null; Class.forName("com.mysql.jdbc.Driver").newInstance(); try{ String url="jdbc:mysql://localhost:3306/mgargiulo"; String dbName="root"; String password2="nagios-2012"; connessione = DriverManager.getConnection (url, dbName, password2); }//try catch(Exception e){out.println("errore database"); statement = connessione.createStatement(); rs = statement.executeQuery("SELECT COMUNE FROM comuni "); %> <p> Comune di Nascita : <select name='comune'> <% while (rs.next()) { String comune2 = rs.getString("COMUNE"); String comune = comune2.toUpperCase(); %> <option value = '<%out.println(comune);%>' > <%out.println(comune); <% } %> </select> <% rs = statement.executeQuery("SELECT DISTINCT(PROVINCIA) FROM comuni ORDER BY PROVINCIA ASC"); Gargiulo Marco 566/1465 Pagina 96 di 135 %> Provincia :<select name='provincia'> <% while (rs.next()) { String provincia2 = rs.getString("PROVINCIA"); String provincia = provincia2.toUpperCase(); %> <option value = '<%out.println(provincia);%>' > <%out.println(provincia);%> <% } %> </select> </p> <p>Password :<input type="password" name="Password" size="20"></p> <p> Ripeti Password :<input type="password" name="Ripetipassword" size="20"> </p> <input type="submit" value="Invia Dati"> <input type="reset" value="Annulla"> </p> </div> </form> <li><a href="prova2.html">back</a></li> </body> </html> File “verifica7.jsp” <%! String messaggio; public java.util.Calendar getData() { return new java.util.GregorianCalendar(); } %> <HTML> <BODY> <%@ page language="java" import="java.sql.*" %> <% String badge = request.getParameter("badge"); String password= request.getParameter("password"); String errore="|"; if(badge==null){ badge = (String) session.getAttribute( "badge" ) ; } if(password==null){ password = (String) session.getAttribute( "password" ) ; } if((badge.length()==0)||(password.length()==0)){ errore="Credenziali nulle"; } Connection connessione=null; Statement statement=null; ResultSet rs=null; int rowCount=0; Class.forName("com.mysql.jdbc.Driver").newInstance(); Gargiulo Marco 566/1465 Pagina 97 di 135 try{ String url ="jdbc:mysql://localhost:3306/mgargiulo"; String dbName="root"; String password2="nagios-2012"; String userName="mgargiulo"; connessione = DriverManager.getConnection (url, dbName, password2); } catch(Exception e){ out.println(e.getMessage()); } statement = connessione.createStatement(); try { String query="SELECT COUNT(*) FROM utenti WHERE badge ='"+badge+"' "; rs = statement.executeQuery(query); rs.next(); rowCount = rs.getInt(1); } catch(Exception e){ out.println(e.getMessage()); } if(rowCount>0) { try { String query="SELECT * FROM utenti WHERE badge='"+badge+"' "; rs = statement.executeQuery(query); } catch(Exception e){ out.println(e.getMessage()); } int risp=-1; int a=0; while ((rs.next())&&(risp==-1)) { a=a+1; String username= rs.getString("username"); String nome = rs.getString("name"); String passw = rs.getString("password"); String qualifica= rs.getString("qualifica"); String CF1 = rs.getString("cf"); String badge1= rs.getString("badge"); if (passw.compareTo(password)!=0) {errore="Login fallito password errata";} else { badge=badge.toUpperCase(); badge1=badge1.toUpperCase(); if(badge1.compareTo(badge)!=0) { errore="Login fallito badge errato"; } else { Gargiulo Marco 566/1465 Pagina 98 di 135 out.println("<BR><H1><CENTER> BENVENUTO NEL NOSTRO SERVIZIO </CENTER></H1><BR>"); out.println("<BR><H3><CENTER> Utente: " +nome+ " Qualifica: " +qualifica+ "</H3></CENTER><BR>"); if(qualifica.compareTo("studente")==0) { %> <center><img src="http://www.mondoimmagine.net/mihome/wpcontent/uploads/2012/05/studente.jpg" width="100" height="69"/></center> <table border="0" width="100%"> <tr> <td colspan="2"></td> </tr> <tr> <td width="500"> <table width="500"> <tr> <td></td> </tr> <tr> <td>Opzioni </td> </tr> <tr> <td></td> </tr> <tr> <td> <% session.setAttribute("badge",badge); session.setAttribute("password", password ); %> <li><a href="cambia_password0.jsp"> Cambia Password </a></li> </td> </tr> <tr> </td> </tr> <tr> <td> <% session.setAttribute("badge",badge); session.setAttribute("password", password ); %> <li><a href="visualizza_registrazioni4.jsp ">Visualizza Registrazioni</a></li> </td> </tr> <tr> <td> </td> Gargiulo Marco 566/1465 Pagina 99 di 135 </tr> <tr> <td> <% session.setAttribute("badge", badge ); session.setAttribute("password", password ); %> <li> <a href="visualizza_corsi_attivi.jsp">Visualizza Corsi Attivi</a></li> </td> </tr> <tr> <td> <% session.setAttribute("badge", badge ); session.setAttribute("password", password ); %> <li> <a href="visualizza_presenze.jsp">Consulta le tue presenze</a></li> </td> </tr> <tr> <td> <li><a href="prova118.html">Logout </a></li> </td> </tr> </td> </tr> <% messaggio=" "; } else { if(qualifica.compareTo("docente")==0) { %> <center><img src="http://www.ondadelsud.it/wp content/uploads/2011/03/professore.jpg" width="100" height="69"/> </center> <% Date d = new Date (System.currentTimeMillis()); out.println(d); java.util.Calendar data = getData(); int ora = data.get(java.util.Calendar.HOUR) + 2; int minuti = data.get(java.util.Calendar.MINUTE); int secondi = data.get(java.util.Calendar.SECOND); String orario = "!! sono le ore "+ora+":"+minuti+":"+secondi; if (data.get(java.util.Calendar.AM_PM) == 0) messaggio = "<b>Buongiorno</b>"+orario+" del mattino"; else messaggio = "<b>Buonasera</b>"+orario+" del pomeriggio"; out.println(messaggio); Gargiulo Marco 566/1465 Pagina 100 di 135 %> <table border="0" width="100%"> <tr> <td colspan="2"></td> </tr> <tr> <td width="500"> <table width="500"> <tr> <td> Opzioni </td> </tr> <tr> <td> <% session.setAttribute("badge", badge ); session.setAttribute("password", password ); %> <li><a href="cambia_password0.jsp"> Cambia Password </a></li> </td> </tr> <tr> <td> <% session.setAttribute("badge", badge ); session.setAttribute("password", password ); %> <li><a href="nuovo_corso2.jsp">Inserisci Nuovo Corso</a></li> </td> </tr> <tr> <td> <% session.setAttribute("badge", badge ); session.setAttribute("password", password ); %> <li><a href="elimina_corso.jsp">Elimina corso </a></li> </td> </tr> <tr> <td> <% session.setAttribute("badge", badge ); session.setAttribute("password", password ); %> <li><a href="visualizza_corsi.jsp">visualizza corsi </a></li> </td> </tr> </tr> <td> Gargiulo Marco 566/1465 Pagina 101 di 135 <li><a href="prova118.html">Logout </a></li> </td> </tr> </td> </tr> <% } } } } else{errore="badge errato";} if(errore.compareTo("|")!=0) { out.println("<BR><H1><CENTER> ACCESSO NEGATO </CENTER></H1><BR>"); out.println("<CENTER>"+errore); out.println("<BR><BR>"); session.setAttribute("badge", badge ); session.setAttribute("password", password ); %> <li><a href="homepage.html">Back </a></li> <% } %> </BODY> </HTML> Gargiulo Marco 566/1465 Pagina 102 di 135 File “cambia_password.jsp” <HTML> <BODY> <%@ page language="java" import="java.sql.*" %> <% String badge = (String) session.getAttribute( "badge" ); String password = (String) session.getAttribute( "password" ); String password3 = request.getParameter("password3"); String password2 = request.getParameter("password2"); String password1 = request.getParameter("password1"); String errore="|"; int p=0; if(password1.length()==0){errore="Errore(1):Password utente uguale NULL";p=1;} if(password2.length()==0){errore="Errore(1):Nuova Password utente uguale NULL";p=1;} if(password2.compareTo(password3)!=0) {errore="Errore(1):Nuova Password Non Corrispondenti"; p=1; } if(password1.compareTo(password)!=0) {errore="Errore(1):Password Non Corrispondenti"; p=1; } if(p==0) { Connection connessione=null; Statement statement=null; ResultSet rs=null; int rowCount=0; Class.forName("com.mysql.jdbc.Driver").newInstance(); try{ String url="jdbc:mysql://localhost:3306/mgargiulo"; String dbName="root"; String password4="nagios-2012"; String userName="mgargiulo"; connessione=DriverManager.getConnection (url, dbName, password4); } catch(Exception e){out.println(e.getMessage());} statement = connessione.createStatement(); Gargiulo Marco 566/1465 Pagina 103 di 135 try{ String query="SELECT COUNT(*) FROM utenti WHERE badge='"+badge+"' "; rs = statement.executeQuery(query); rs.next(); rowCount = rs.getInt(1); } catch(Exception e){out.println(e.getMessage());} if(rowCount>0) { try { String query="SELECT * FROM utenti WHERE badge='"+badge+"' "; rs = statement.executeQuery(query); } catch(Exception e){out.println(e.getMessage());} int risp=-1; int a=0; while ((rs.next())&&(risp==-1)) { String passw = rs.getString("password"); String badge1= rs.getString("badge"); if(passw.compareTo(password)!=0){errore="Password*Errata";} else { badge=badge.toUpperCase(); badge1=badge1.toUpperCase(); if(badge1.compareTo(badge)!=0){errore="Badge errato";} else{ Statement statement2 =connessione.createStatement(); ***String*query2="UPDATE*utenti*SET password='"+password2+"'WHERE badge='"+badge+"' "; out.println("Password cambiata con Successo"); Gargiulo Marco 566/1465 Pagina 104 di 135 %><a href="prova118.html"> Torna al form di autenticazione </a></li><% try{statement2.executeUpdate(query2);} catch(Exception e){out.println(e.getMessage());} } } } if(errore.compareTo("|")!=0) { out.println("<BR><H1><CENTER>ACCESSO.NEGATO</CENTER></H1><BR>"); out.println("<CENTER>"+errore); out.println("<BR><BR>"); session.setAttribute("badge", badge ); session.setAttribute("password", password); %><li><a href="verifica7.jsp">back</a></li><% } else { out.println("<BR><H1><CENTER> ACCESSO NEGATO </CENTER></H1><BR>"); out.println("<CENTER>"+errore); out.println("<BR><BR>"); session.setAttribute("badge", badge ); session.setAttribute("password", password); %><li><a href="verifica7.jsp">back</a></li><% } %> </BODY> </HTML> Gargiulo Marco 566/1465 Pagina 105 di 135 File “cambia_password0.jsp” <html> <body> <%@ page language="java" import="java.sql.*" %> <% String badge = (String) session.getAttribute( "badge" ) ; String password= (String) session.getAttribute( "password" ) ; %> <title>Cambiamento di password </title> <div align="center"> <u>Cambio di password </u> <h5>Inserisci e tue credenziali </h5><br /> <form name="f1" action="cambia_password.jsp" method="post" > <p>Vecchia Password: <input type="text" name="password1" maxlength="20" size="18" /> </p> <p>Nuova Password:<input type="text" name="password2" maxlength="20" size="18" /> </p> <p>Ripeti Password: <input type="text" name="password3" maxlength="20" size="18" /> </p> <% session.setAttribute("badge", badge ); session.setAttribute("password", password); %> <input type="submit" value="Invia Dati"> <input type="reset" value="Annulla"> <br> <br> <br> <li><a href="verifica7.jsp">back</a></li> </form> <div> </body> </html> Gargiulo Marco 566/1465 Pagina 106 di 135 File “cambia_password.jsp” <html> <head> <script type="text/javascript"> function st(valore) { var x=valore; document.location = 'visualizza_presenze99.jsp?valore='+x; } </script> </head> <body> <%@ page language="java" import="java.sql.*" %> <% String badge = (String) session.getAttribute( "badge" ); String password = (String) session.getAttribute( "password" ) ; Connection connessione=null; Statement statement=null; ResultSet rs=null; ResultSet rs1=null; int rowCount=0; Class.forName("com.mysql.jdbc.Driver").newInstance(); try{ { String url="jdbc:mysql://localhost:3306/mgargiulo"; String dbName="root"; String password2="nagios-2012"; String userName="mgargiulo"; connessione = DriverManager.getConnection (url, dbName, password2); } catch(Exception e){ out.println(e.getMessage()); } statement = connessione.createStatement(); try { String query="SELECT COUNT(*) FROM registrazioni as r where r.badge_studente='"+badge+"' "; rs = statement.executeQuery(query); rs.next(); rowCount = rs.getInt(1); } catch(Exception e){ out.println(e.getMessage()); } if(rowCount>0) { try { String query="SELECT * FROM registrazioni as r where r.badge_studente='"+badge+"'"; rs = statement.executeQuery(query); } Gargiulo Marco 566/1465 Pagina 107 di 135 catch(Exception e){ out.println(e.getMessage()); } int appi=0; String app[]=new String[1000]; String app2[]=new String[1000]; while (rs.next()) { String nome_corso = rs.getString("nome_corso"); String id_corso = rs.getString("id_corso"); app[appi]=nome_corso; app2[appi]=nome_corso+"|"+id_corso+"|"+badge+"|"+password+"|"; appi++; } %> <CENTER><H3> RIEPILOGO PRESENZE </H3></CENTER> <TABLE.BORDER="1"CELLPADDING="0" CELLSPACING="0" BGCOLOR="#0000FF"> <TR> <TD> <TABLE BORDER="1" CELLPADDING="5" CELLSPACING="5"> <TR> <TD BGCOLOR="#FFFFFE">Nome Corso</TD> <TD BGCOLOR="#FFFFFE">Opzioni</TD> </TR> <% for(int i=0;i<appi;i++) { %> <TR> <TD BGCOLOR="#FFFFFE"> <%out.println(app[i]); %> </TD> <TD BGCOLOR="#FFFFFE"><button id="<%out.println(app2[i]);%>" value="Vedi" onClick="st(this.id)" > Visualizza Presenze </button> </TD> </TR> <% } %> </TABLE> </TD> </TR> </TABLE> <% }else{out.println("Non sei inscritto a nessun corso");} %> <BR></BR> <% session.setAttribute("badge", badge ); session.setAttribute("password", password); %> <li><a href="verifica7.jsp">Back</a></li> </body> Gargiulo Marco 566/1465 Pagina 108 di 135 </html> File “visualizza_registrazioni4.jsp” <html> <head> <Script tipo = "text / javascript" > funzione dammi_id (id){ return(id); } </ script> </head> <body> <%@ page language="java" import="java.sql.*" %> <% String badge = (String) session.getAttribute( "badge" ) ; String username = (String) session.getAttribute( "username" ) ; String CF = (String) session.getAttribute( "CF" ) ; String password = (String) session.getAttribute( "password" ) ; Connection connessione=null; Statement statement=null; ResultSet rs=null; int rowCount=0; Class.forName("com.mysql.jdbc.Driver").newInstance(); try{ String url="jdbc:mysql://localhost:3306/mgargiulo"; String dbName="root"; String password2="nagios-2012"; String userName="mgargiulo"; connessione.=.DriverManager.getConnection(url, dbName, password2); } catch(Exception e){ out.println(e.getMessage());} statement = connessione.createStatement(); try { String query="SELECT COUNT(*) FROM registrazioni WHERE badge_studente='"+badge+"' "; rs = statement.executeQuery(query); rs.next(); } rowCount =rs.getInt(1); catch(Exception e){out.println(e.getMessage());} if(rowCount==0)out.println("Nessuna registrazione effettuata"); session.setAttribute("user", username ); session.setAttribute("CF", CF ); session.setAttribute("badge", badge ); session.setAttribute("password", password ); %> <li><a href="verifica7.jsp">Back </a></li> <% } Gargiulo Marco 566/1465 Pagina 109 di 135 else{ try{ String query2="select * from registrazioni where badge_studente = '"+badge+"' "; rs = statement.executeQuery(query2); } catch(Exception e){ out.println(e.getMessage());} int appi=0; String app[]=new String[1000]; String app2[]=new String[1000]; while (rs.next()) { String nome_corso = rs.getString("nome_corso"); String nome_docente = rs.getString("nome_docente"); String cognome_docente = rs.getString("cognome_docente"); String id_corso = rs.getString("id_corso"); String valori2=badge+"|"+nome_corso+"|"+nome_docente+"|"+cognome_docente+"|"+id_corso+"|"; String valori=nome_corso+" "+nome_docente+" "+cognome_docente+" "; app[appi]=valori2; app2[appi]=valori; appi++; } int i=0; for(i=0;i<appi;i++) { %> <BR> <%out.println(app2[i]);%> <input type="button" value="Vedi"id="%out.println(app2[i]);%>"> </BR> <% } } %> </body> </html> Gargiulo Marco 566/1465 Pagina 110 di 135 File “iscrizione_corso.jsp” <html> <body> <%@ page language="java" import="java.sql.*" %> <% String dati = request.getParameter("corso"); int i=0,j,cont=0,cont2=0,k=0; String app,badgeS=null,badgeD=null,nome_corso=null,nome_docente=null; String cognome_docente=null,id_corso=null; while((i<dati.length())&&(k==0)) { j=i; cont=0; app=null; while((cont==0)&& ( j<dati.length() ) ) { char a=dati.charAt(j); if(a!='|') { if(app==null) app= Character.toString(a); else app=app+a; } else cont++; j++; } i=j; cont2=cont2+cont; if (cont2==1) badgeS=app; else { if(cont2==2){badgeD = app.substring(1,app.length());} else{ if(cont2==3) nome_corso=app; else{ if(cont2==4) nome_docente=app; else{ if(cont2==5)cognome_docente=app; else{id_corso=app; k=1;} } } } } } Connection connessione=null; Statement statement=null; Gargiulo Marco 566/1465 Pagina 111 di 135 ResultSet rs=null; ResultSet rs1=null; int rowCount=0; Class.forName("com.mysql.jdbc.Driver").newInstance(); try { String url="jdbc:mysql://localhost:3306/mgargiulo"; String dbName="root"; String password2="nagios-2012"; String userName="mgargiulo"; connessione = DriverManager.getConnection (url, dbName, password2); } catch(Exception e){ out.println(e.getMessage()); } statement = connessione.createStatement(); try { String query2="select count(*) from registrazioni as r where r.id_corso = '"+id_corso+"' && r.badge_studente = '"+badgeS+"' "; rs = statement.executeQuery(query2); rs.next(); rowCount = rs.getInt(1); } catch(Exception e){ out.println(e.getMessage()); } if(rowCount > 0){out.println("Gia hai effettuato la registrazione a questo corso"); } else { String query2="INSERT INTO registrazioni (badge_studente, nome_corso, badge_docente, id_corso, nome_docente,cognome_docente ) VALUES ('"+badgeS+"', '"+nome_corso+"', '"+badgeD+"','"+id_corso+"','"+nome_docente+"', '"+cognome_docente+"')"; try { statement.executeUpdate(query2); } catch(Exception e){ out.println(e.getMessage()); } try { String query30 ="DELETE FROM prova WHERE id_corso > 0 " ; statement.executeUpdate(query30); } catch(Exception e){ out.println(e.getMessage()); } %> <CENTER><H1>ISCRIZIONE AVVENUTA CON SUCCESSO</H1></CENTER> <CENTER><H3> RIEPILOGO DATI INSERITI </H3></CENTER> <%}%> <CENTER><li><a href="prova118.html">EFFETTUA LOGIN </a></li></CENTER> </body> <html> Gargiulo Marco 566/1465 Pagina 112 di 135 File “visualizza_corsi_attivi.jsp” <html> <body> <%@ page language="java" import="java.sql.*" %> <% String badge = (String) session.getAttribute( "badge" ); String password = (String) session.getAttribute( "password" ) ; Connection connessione=null; Statement statement=null; ResultSet rs=null; ResultSet rs1=null; int rowCount=0; String.badge2=null,nomeDoc=null,cognomeDoc=null; String.nome_corso=null,cfu=null,String ore=null, badgeD=null; Class.forName("com.mysql.jdbc.Driver").newInstance(); try { String url="jdbc:mysql://localhost:3306/mgargiulo"; String dbName="root"; String password2="nagios-2012"; String userName="mgargiulo"; connessione.=DriverManager.getConnection(url, dbName, password2); } catch(Exception e){out.println(e.getMessage()); } statement = connessione.createStatement(); try{ String query30 ="DELETE FROM prova WHERE id_corso > 0 " ; statement.executeUpdate(query30); } catch(Exception e){ out.println(e.getMessage()); } try { String query="SELECT COUNT(*) FROM corsi_attivi"; rs = statement.executeQuery(query); rs.next(); rowCount = rs.getInt(1); } catch(Exception e){ out.println(e.getMessage()); } if(rowCount == 0){ out.println("Nessun Corso E' attivo"); } else { try { String query2="select count(*) from corsi_attivi as c where c.id_corso not in (select r.id_corso from registrazioni as r where r.badge_studente='"+badge+"')"; rs = statement.executeQuery(query2); rs.next(); rowCount =rs.getInt(1); } Gargiulo Marco 566/1465 Pagina 113 di 135 catch(Exception e){ out.println(e.getMessage()); } if(rowCount == 0) { out.println("Ti sei registrato a tutti i corsi attivi "); } else { try { String query3="select * from corsi_attivi as c where c.id_corso not in (select r.id_corso from registrazioni.asr where r.badge_studente='"+badge+ "')"; rs = statement.executeQuery(query3); } catch(Exception e){ out.println(e.getMessage()); } String[][] v = null; v=new String[100][6]; int i=0; while(rs.next()) { String id_corso = rs.getString("id_corso"); nome_corso = rs.getString("come_corso"); cfu = rs.getString("cfu"); badge2 = rs.getString("badge"); //badge docente ore = rs.getString("ore"); v[i]= new String[5]; v[i][0]=badge2; v[i][1]=cfu; v[i][2]=nome_corso; v[i][3]=ore; v[i][4]=id_corso; i++; } try{ String query6="select Count(*) from prova " ; rs = statement.executeQuery(query6); rs.next(); rowCount = rs.getInt(1); } catch(Exception e){ out.println(e.getMessage()); } if(rowCount > 0) { try { String query7 ="DELETE FROM prova WHERE id_corsoi > 0 " ; rs = statement.executeQuery(query7); rs.next(); } catch(Exception e){out.println(e.getMessage()); } Gargiulo Marco 566/1465 Pagina 114 di 135 } else { Statement statement3 =connessione.createStatement(); for(int j=0;j<i;j++) { String.query8="INSERT.INTO.prova (badgeS,badgeD,nome_corso,id_corso,cfu,ore) VALUES ('"+badge+"','"+v[j][0]+"','"+v[j][2]+"','"+v[j}[4]+"' ,'"+v[j] [1]+"','"+v[j][3]+"')"; try{statement3.executeUpdate(query8);} catch(Exception e){out.println(e.getMessage());} } } try { String.query9=".select.u.name,u.cognome,p.badgeS,p.badgeD, p.nome_corso,p.cfu,p.ore, p.id_corso from utenti as u inner join prova as p where u.badge=p.badgeD;"; rs = statement.executeQuery(query9); } catch(Exception e){ out.println(e.getMessage());} %> <CENTER><H3>RIEPILOGO.CORSI.ATTIVATI.A.CUI.SI.PUO'.INSCRIVERE</H3> </CENTER> <FORM ACTION="iscrizione_corso.jsp" METHOD="post"> Selezionare il corso al quale si vuole inscrivere:<BR><BR><BR> Gargiulo Marco 566/1465 Pagina 115 di 135 <select name='corso'> <%while(rs.next()) { String badgeS1 = rs.getString("badgeS"); String badgeD1 = rs.getString("badgeD"); String nome_corso1 = rs.getString("nome_corso"); String nomeD = rs.getString("name"); String cognomeD = rs.getString("cognome"); String cfu1 = rs.getString("cfu"); String ore1 = rs.getString("ore"); String id_corso1 = rs.getString("id_corso"); String.valori.=.badgeS1+"|"+badgeD1+"|"+nome_corso1+"|"+nomeD +"|”+cognomeD+"| " +id_corso1+"|"; String valori2=nome_corso1+" "+nomeD+" "+cognomeD+" "; %> <option value = '<%out.println(valori);%>' > <%out.println(valori2) <% } %> <select> <input type="submit" value="Invia Dati" onClick="return(confirm('Premi il tasto OK se vuoi registrarti al corso\nAltrimenti premi Annulla'))"> </form><% } } session.setAttribute("badge", badge ); session.setAttribute("password", password); %> <li><a href="verifica7.jsp">Back</a></li> </body> </html> Gargiulo Marco 566/1465 Pagina 116 di 135 File “nuova_lezione.jsp” <html> <body> <%@ page language="java" import="java.sql.*" %> <% String badge = (String) session.getAttribute( "badge" ) ; String id_corso = (String) session.getAttribute( "id_corso" ) ; String titolo = request.getParameter("titolo"); String descrizione = request.getParameter("descrizione"); String ore = request.getParameter("ore"); String giorno= request.getParameter("giorno"); String mese= request.getParameter("mese"); String anno= request.getParameter("anno"); String password = (String) session.getAttribute( "password" ) ; String identificativo = request.getParameter("identificativo"); String ora = request.getParameter("ora"); String minuti = request.getParameter("minuti"); String secondi = request.getParameter("secondi"); String data = giorno+"/"+mese+"/"+anno; String orario =ora+":"+minuti+":"+secondi; String errore="|"; Connection connessione=null; Statement statement=null; ResultSet rs=null; int rowCount=0,a=0; String nome,errore2=""; if(titolo.length()==0){errore2="titolo lezione errato";} else{if(descrizione.length()==0){errore2="descrizione lezione errata";} else{ if(identificativo.length()==0){ errore2="identificativo errato";} String app=""; if(errore2.compareTo(app)==0) { Class.forName("com.mysql.jdbc.Driver").newInstance(); try { String url="jdbc:mysql://localhost:3306/mgargiulo"; String dbName="root"; String password2="nagios-2012"; String userName="mgargiulo"; connessione = DriverManager.getConnection (url, dbName, password2); } catch(Exception e){out.println(e.getMessage()); } statement = connessione.createStatement(); Gargiulo Marco 566/1465 Pagina 117 di 135 try { String query="SELECT COUNT(*) FROM lezioni WHERE titolo='"+titolo+"' and descrizione='"+descrizione+"' "; rs = statement.executeQuery(query); rs.next(); rowCount = rs.getInt(1); } catch(Exception e){ out.println(e.getMessage()); } if(rowCount==0) { try { String query="SELECT COUNT(*) FROM corsi_attivi"; rs = statement.executeQuery(query); rs.next(); rowCount = rs.getInt(1); } catch(Exception e){ out.println(e.getMessage());} if(rowCount>0) { try { String query="SELECT come_corso FROM corsi_attivi where id_corso="+id_corso+" "; rs = statement.executeQuery(query); rs.next(); } catch(Exception e){ out.println(e.getMessage()); } nome = rs.getString("come_corso"); String query3=“INSERT INTO lezioni (id_corso, nome_corso, badge, titolo, descrizione, data, inizio, ore, ide) VALUES ('"+id_corso+"', '"+nome+"', '"+badge+"', '"+titolo+"', '"+descrizione+"', '"+data+"','"+orario+"','"+ore+"', '"+identificativo+")"; try{ statement.executeUpdate(query3);} catch(Exception e){ out.println(e.getMessage()); a=1;} if(a==0){ out.println("Inserimento Avvenuto con successo"); } else out.println("Nuova lezione fallita non è possibile avere due lezioni con stesso titolo e stessa descrizione"); } else out.println(errore2); String valore=badge+"|"+id_corso+"|"+password+"|"; session.setAttribute("valore", valore); %> <li><a href="dettagli_corso0.jsp">Back </a></li> </body> </html> Gargiulo Marco 566/1465 Pagina 118 di 135 File“visualizza_presenze.jsp”(Lato studenti) <html> <head> <script type="text/javascript"> function st(valore) { var x=valore; document.location = 'visualizza_presenze99.jsp?valore='+x; } </script> </head> <body> <%@ page language="java" import="java.sql.*" %> <% String badge = (String) session.getAttribute( "badge" ) ; String password = (String) session.getAttribute( "password" ) ; Connection connessione=null; Statement statement=null; ResultSet rs=null; ResultSet rs1=null; int rowCount=0; Class.forName("com.mysql.jdbc.Driver").newInstance(); try { String url="jdbc:mysql://localhost:3306/mgargiulo"; String dbName="root"; String password2="nagios-2012"; String userName="mgargiulo"; connessione = DriverManager.getConnection (url, dbName, password2); } catch(Exception e){ out.println(e.getMessage()); } statement = connessione.createStatement(); try { String query="SELECT COUNT(*) FROM registrazioni as r where r.badge_studente='"+badge+"' "; rs = statement.executeQuery(query); rs.next(); rowCount = rs.getInt(1); } catch(Exception e){ out.println(e.getMessage()); } if(rowCount>0){ try { String query="SELECT * FROM registrazioni as r where r.badge_studente='"+badge+"'"; rs = statement.executeQuery(query); } catch(Exception e){ out.println(e.getMessage()); } int appi=0; String app[]=new String[1000]; String app2[]=new String[1000]; while (rs.next()) Gargiulo Marco 566/1465 Pagina 119 di 135 { String nome_corso = rs.getString("nome_corso"); String id_corso = rs.getString("id_corso"); app[appi]=nome_corso; app2[appi]=nome_corso+"|"+id_corso+"|"+badge+"|"+password+"|"; appi++; } %> <CENTER><H3> RIEPILOGO PRESENZE </H3></CENTER> <TABLE BORDER="1" CELLPADDING="0" CELLSPACING="0" BGCOLOR="#0000FF"> <TABLE BORDER="1" CELLPADDING="5" CELLSPACING="5"> <TR> <TD BGCOLOR="#FFFFFE">Nome Corso</TD> <TD BGCOLOR="#FFFFFE">Opzioni</TD> </TR> <% for(int i=0;i<appi;i++) { %> <TR> <TD BGCOLOR="#FFFFFE"> <%out.println(app[i]); %> </TD> <TD BGCOLOR="#FFFFFE"><button id="<%out.println(app2[i]); %>" value="Vedi"onClick="st(this.id)" > Visualizza Presenze</button> </TD> </TR> <%}%> </TABLE> </TD> </TR> </TABLE> <%}else{out.println("Non sei inscritto a nessun corso");}%> <BR></BR> <% session.setAttribute("badge", badge ); session.setAttribute("password", password); %><li><a href="verifica7.jsp">Back</a></li> </body> </html> File “visualizza_presenze2.jsp”(Lato studenti) <html> <head> <script type="text/javascript"> function st(valore) { var x=valore; var q=valore.length; var vi=0; Gargiulo Marco 566/1465 Pagina 120 di 135 var ore=””,min=””,cent=””,c,cont=0; while(vi<q) { c=x.charAt(vi); if(c!='|') { if(cont==0) {ore=ore+c;} else { if(cont==1) {min=min+c;} else{cent=cent+c} } } else{cont++;} vi++; } alert(" Ore Presenza "+ore+":"+min+" guadagno euro: "+cent); } </script> </head> <body> <%@ page language="java" import="java.sql.*" %> <% String var = request.getParameter("valore"); int i=0,cont=0; String app="",badge="",password="",nome_corso="",id_corso="",errore=""; int ore_totali=0,s_ore=0,ore_totali_parziali=0; int minuti_totali=0,s_min=0,minuti_totali_parziali=0; char c; while(i<var.length()) { c=var.charAt(i); if(c!='|') { if (app.compareTo("")==0) app=Character.toString(c); else app=app+c; } else{ if(cont==0){ nome_corso=app; app=""; cont++; } else{ if (cont==1){ id_corso=app; app=""; cont++;} else{ if (cont==2) { badge=app; app="";cont++;} else{ password=app; app=""; cont++;} } } } i++; } id_corso=id_corso.replace(" ",""); Gargiulo Marco 566/1465 Pagina 121 di 135 Connection connessione=null; Statement statement=null; ResultSet rs=null; Class.forName("com.mysql.jdbc.Driver").newInstance(); String nul="NULLO"; try { String url="jdbc:mysql://localhost:3306/mgargiulo"; String dbName="root"; String password5="nagios-2012"; connessione = DriverManager.getConnection (url, dbName, password5); } catch(Exception e){out.println("Errore(1): Database non trovato");} statement =connessione.createStatement(); int err=0,rowCount=0; try{ String query="SELECT COUNT(*) FROM timbratura WHERE (id_corso = '"+id_corso+"'&& badge_studente='"+badge+"' && ora_out<>'"+nul+"') "; rs = statement.executeQuery(query); rs.next(); rowCount = rs.getInt(1); } catch(Exception e){ out.println(e.getMessage()); } if(rowCount == 0 ){ out.println("Nessuna Presenza Ottenuta");} else{ try{ String query2="select * FROM timbratua WHERE ((id_corso ='"+id_corso+"') &&(badge_studente='"+badge+"') && (ora_out<>'"+nul+"')) "; rs = statement.executeQuery(query2); } catch(Exception e){out.println(e.getMessage());} %> <CENTER><H3> REPORT PRESENZE PER LO STUDENTE BADGE:<%out.println(badge);%>MATERIA: <% out.println(nome_corso);%> </H3> </CENTER> <TABLE.BORDER="1"CELLPADDING="0"CELLSPACING="0" BGCOLOR="#0000FF"> <TR> <TD> <TABLE BORDER="1" CELLPADDING="5" CELLSPACING="5"> <TR> <TD BGCOLOR="#FFFFFE">Data</TD> <TD BGCOLOR="#FFFFFE">Timbratura Ingresso</TD> <TD BGCOLOR="#FFFFFE"> Timbratura Uscita</TD> <TD BGCOLOR="#FFFFFE"> Totale Presenza Lezione </TD> </TR> <% while (rs.next()) { String ora_in = rs.getString("ora_in"); String ora_out = rs.getString("ora_out"); Gargiulo Marco 566/1465 Pagina 122 di 135 String data = rs.getString("data"); i=0;app="";cont=0; ore_totali=0; minuti_totali=0; String.ora_in1="";String.min_in1=""; String ora_out1=""; String min_out1=""; while(i<ora_in.length()) { c=ora_in.charAt(i); if(c!=':') { if(app.compareTo("")==0) app=Character.toString(c); else app=app+c; } else{ if(cont==0){ora_in1=app; app=""; cont++;} else{ if (cont==1){ min_in1=app; app=""; cont++; } } } i++; } i=0; app=""; cont=0; while(i<ora_out.length()) { c=ora_out.charAt(i); if(c!=':') { if (app.compareTo("")==0) app=Character.toString(c); else app=app+c; } else{ if(cont==0){ ora_out1=app; app="";cont++;} else{ if (cont==1){ min_out1=app; app="";cont++;} } } i++; } if(ora_in1.length()<2)ora_in1='0'+ora_in1; if(min_in1.length()<2)min_in1='0'+min_in1; int min_in2 = Integer.parseInt (min_in1); int ora_in2 = Integer.parseInt (ora_in1); if(ora_in1.length()<2)ora_in1='0'+ora_in1; if(min_in1.length()<2)min_in1='0'+min_in1; min_in2 = Integer.parseInt (min_in1); ora_in2 = Integer.parseInt (ora_in1); if(ora_out1.length()<2)ora_out1='0'+ora_out1; if(min_out1.length()<2)min_out1='0'+min_out1; int min_out2 = Integer.parseInt (min_out1); Gargiulo Marco 566/1465 Pagina 123 di 135 int ora_out2 = Integer.parseInt (ora_out1); int appore=ora_in2; int appmin=min_in2; while ((ora_in2!=ora_out2)||(min_in2!=min_out2)) { minuti_totali++; if(minuti_totali==60){ore_totali++;minuti_totali=0;} min_in2++; if(min_in2==60){ora_in2++;min_in2=0;} } while(minuti_totali>59) { if((minuti_totali%60)>59) { ore_totali=ore_totali+(minuti_totali/60); minuti_totali=minuti_totali%60; } } s_ore=s_ore+ore_totali; s_min=s_min+minuti_totali;%> <TR> <TD BGCOLOR="#FFFFFE"> <%out.println(data);%></TD> <TD BGCOLOR="#FFFFFE"> <%out.println(appore+":"+appmin);%> </TD> <TD BGCOLOR="#FFFFFE"> <%out.println(ora_out2+":"+min_out2);%> </TD> <TD BGCOLOR="#FFFFFE"><%out.println(ore_totali+":"+minuti_totali); %></TD> </TR> <%} } while(s_min>59) { if((s_min%60)>59){ s_ore=s_ore+(s_min/60);s_min=s_min%60; } else{if((s_min%60)>0){s_ore=s_ore+1;s_min=s_min%60;} } } %> </TABLE> </TD> </TR> </TABLE> <% if(rowCount != 0 ) { int g=((s_ore*60)+s_min)*4; double euro=g * 0.01; euro= (double)((int)(euro*10))/10; String parametri=s_ore+"|"+s_min+"|"+euro+"|"; %> <TD.BGCOLOR="#FFFFFE"><button.id="<%out.println(parametri);%>" value="Vedi"onClick="st(this.id)" >Calcola</button></TD> <BR><BR><%} Gargiulo Marco 566/1465 Pagina 124 di 135 session.setAttribute("badge",badge); session.setAttribute("password", password); %><BR><BR></BR></BR> <li><a href="visualizza_presenze.jsp">Back </a></li> </body> </html> File “elimina_corso.jsp” <html> <body> <%@ page language="java" import="java.sql.*" %> <% String badge = (String) session.getAttribute( "badge" ) ; String password = (String) session.getAttribute( "password" ) ; Connection connessione=null; Statement statement=null; ResultSet rs=null; int rowCount=0; Class.forName("com.mysql.jdbc.Driver").newInstance(); try{ String url="jdbc:mysql://localhost:3306/mgargiulo"; String dbName="root"; String password2="nagios-2012"; String userName="mgargiulo"; connessione = DriverManager.getConnection (url, dbName, password2); } catch(Exception e){ out.println(e.getMessage());} statement = connessione.createStatement(); try { String query="SELECT COUNT(*) FROM corsi_attivi WHERE badge='"+badge+"' "; rs = statement.executeQuery(query); rs.next(); rowCount = rs.getInt(1); } catch(Exception e){ out.println(e.getMessage());} if(rowCount==0){out.println("Nessun corso Attivo");} else{ try { String query2="SELECT * FROM corsi_attivi WHERE badge='"+badge+"' "; rs = statement.executeQuery(query2); } catch(Exception e){ out.println(e.getMessage());} %> <CENTER><H3> CORSI AI QUALI SI E' TITOLARE DI CATTEDRA</H3></CENTER> <TABLE BORDER="1" CELLPADDING="0" CELLSPACING="0" BGCOLOR="#0000FF"> <TR> <TD> <TABLE BORDER="1" CELLPADDING="5" CELLSPACING="5"> <TR> <TD BGCOLOR="#FFFFFE">Nome Corso</TD> <TD BGCOLOR="#FFFFFE"> CFU </TD> Gargiulo Marco 566/1465 Pagina 125 di 135 <TD BGCOLOR="#FFFFFE"> ore </TD> <TD BGCOLOR="#FFFFFE"> ELIMINA </TD> <% while(rs.next()) { String nome_corso = rs.getString("come_corso"); String CFU = rs.getString("cfu"); String ore =rs.getString("ore"); String id =rs.getString("id_corso"); session.setAttribute("id",id); %> <TR> <TD BGCOLOR="#FFFFFE">%out.println(rs.getString("come_corso")); %></TD> <TD BGCOLOR="#FFFFFE"> <%out.println(rs.getString("cfu")); %> </TD> <TD BGCOLOR="#FFFFFE"><%out.println(rs.getString("ore")); %> </TD> <TD BGCOLOR="#FFFFFE"> <form method="POST" action="elimina_corso2.jsp"> <button type="submit">ok</button> </form></TD> </TR> <% } %> </TABLE> </TD> </TR> </TABLE> </CENTER><% } session.setAttribute("badge", badge ); session.setAttribute("password", password); %> <BR> <BR> <li><a href="verifica7.jsp">back</a></li> </BR> </BR> </body> </html> Gargiulo Marco 566/1465 Pagina 126 di 135 File “visualizza_corsi.jsp”(Lato docente) <html> <script type="text/javascript"> function cattura(clicked_id) { var x=clicked_id; document.location = 'dettagli_corso0.jsp?valore='+x; } </script> <body> <%@ page language="java" import="java.sql.*" %> <% String badge = (String) session.getAttribute( "badge" ) ; String password = (String) session.getAttribute( "password" ) ; Connection connessione=null; Statement statement=null; ResultSet rs=null; int rowCount=0; Class.forName("com.mysql.jdbc.Driver").newInstance(); try { String url="jdbc:mysql://localhost:3306/mgargiulo"; String dbName="root"; String password2="nagios-2012"; String userName="mgargiulo"; connessione = DriverManager.getConnection (url, dbName, password2); } catch(Exception e){out.println(e.getMessage()); } statement = connessione.createStatement(); try { String query="SELECT COUNT(*) FROM corsi_attivi WHERE badge='"+badge+"' "; rs = statement.executeQuery(query); rs.next(); rowCount = rs.getInt(1); } catch(Exception e){ out.println(e.getMessage()); } if(rowCount==0) { out.println("Nessun Corso Attivo"); } if(rowCount>0) Gargiulo Marco 566/1465 Pagina 127 di 135 { try { String query2="SELECT * FROM corsi_attivi WHERE badge='"+badge +"' "; rs = statement.executeQuery(query2); } catch(Exception e){ out.println(e.getMessage()); } int i=0; int appi=0; String app[] = new String[1000]; String app2[] = new String[1000]; while(rs.next()) { String nome_corso = rs.getString("come_corso"); String CFU = rs.getString("cfu"); String ore =rs.getString("ore"); String id =rs.getString("id_corso"); String valore= nome_corso+"|"+CFU+"|"+ore+"|"; String valori2= badge+"|"+id+"|"+password+"|"; app2[appi]=valori2; app[appi]=valore; appi++; } %> <CENTER><H3> CORSI TITOLARE DI CATTEDRA </H3></CENTER> <TABLE BORDER="1" CELLPADDING="0" CELLSPACING="0" BGCOLOR="#0000FF"> <TR> <TD> <TABLE BORDER="1" CELLPADDING="5" CELLSPACING="5"> <TR> <TD BGCOLOR="#FFFFFE">NOME CORSO</TD> <TD BGCOLOR="#FFFFFE">CFU</TD> <TD BGCOLOR="#FFFFFE">ORE</TD> <TD BGCOLOR="#FFFFFE">OPZIONI</TD> <% int j=0,cont=0; char c; String nome_corso="",cfu="",ore=""; String sw=""; for(i=0;i<appi;i++) { j=0;nome_corso="";cfu="";ore=""; Gargiulo Marco 566/1465 Pagina 128 di 135 sw="";cont=0; while(j<app[i].length()) { c=app[i].charAt(j); if(c!='|') sw=sw+c; else{ if(cont==0){ nome_corso=sw;sw=""; } else{ if (cont==1){ cfu=sw;sw="";} else{ if (cont==2) { ore=sw; sw="";} } } cont++; } j++; } %> <TR> <TD BGCOLOR="#FFFFFE"><%out.println(nome_corso);%> </TD> <TD BGCOLOR="#FFFFFE"><%out.println(cfu);%></TD> <TD BGCOLOR="#FFFFFE"><%out.println(ore);%></TD> <TD BGCOLOR="#FFFFFE"><button id="<%out.println(app2[i]);%>" onClick="cattura(this.id)">VEDI </button> </TD> <% } } %> </TR> </TABLE> </TD> </TR> </TABLE> <BR></BR> <% session.setAttribute("badge", badge ); session.setAttribute("password", password ); %> <li><a href="verifica7.jsp">back</a></li> </body> </html> Gargiulo Marco 566/1465 Pagina 129 di 135 File “dettaglio_corso.jsp” <html> <head> <script type="text/javascript"> function st(valore) { var x=valore; document.location = 'visualizza_lezioni.jsp?valore='+x; } </script> </head> <body> <%@ page language="java" import="java.sql.*" %> <% String badge = (String)session.getAttribute("badge") ; String id_corso = (String)session.getAttribute("id_corso"); String password= (String)session.getAttribute("password"); Connection connessione=null; Statement statement=null; ResultSet rs=null; int rowCount=0; Class.forName("com.mysql.jdbc.Driver").newInstance(); try { String url="jdbc:mysql://localhost:3306/mgargiulo"; String dbName="root"; String password2="nagios-2012"; String userName="mgargiulo"; connessione = DriverManager.getConnection (url, dbName, password2); } catch(Exception e){out.println(e.getMessage());} statement = connessione.createStatement(); try {rs = statement.executeQuery("SELECT COUNT(*) FROM lezioni WHERE badge='"+badge+"' && id_corso='"+id_corso+"' "); rs.next(); rowCount = rs.getInt(1); } catch(Exception e){out.println(e.getMessage());} if (rowCount==0){out.println("nessun lezione svolta");} else { try { String query2="SELECT * FROM lezioni WHERE badge='"+badge+"' && id_corso='"+id_corso+"' "; rs = statement.executeQuery(query2); } catch(Exception e){out.println(e.getMessage());} Gargiulo Marco 566/1465 Pagina 130 di 135 %> <CENTER><H3> CORSI TITOLARE DI CATTEDRA </H3></CENTER> <BR></BR> <TABLE BORDER="1" CELLPADDING="0" CELLSPACING="0" BGCOLOR="#0000FF"> <TR> <TD> <TABLE BORDER="1" CELLPADDING="5" CELLSPACING="5"> <TR> <TD BGCOLOR="#FFFFFE">NOME CORSO</TD> <TD BGCOLOR="#FFFFFE">DATA</TD> <TD BGCOLOR="#FFFFFE">OPZIONI</TD> <% int appi=0; String app[]=new String[1000]; String app2[]=new String[1000]; while(rs.next()) { String nome_corso =rs.getString("nome_corso"); String titolo =rs.getString("titolo"); String descrizione = rs.getString("descrizione"); String data =rs.getString("data"); String valore= nome_corso+"|"+data+"|"; String valori2= badge+"|"+id_corso+"|"+data+"|"+password+"|"; app2[appi]=valori2; app[appi]=valore; appi++; } int i; char c; for(i=0;i<appi;i++) { String nc="";String data="";int cont2=0;String sw="";int j=0; while(j<app[i].length()) { c=app[i].charAt(j); if(c!='|'){ sw=sw+c;} else{if(cont2==0){ nc=sw;sw="";} else{if (cont2==1){data=sw;sw="";} } cont2++; } j++; } %> <TR> <TD BGCOLOR="#FFFFFE"><%out.println(nc);%> </TD> <TD BGCOLOR="#FFFFFE"><%out.println(data);%></TD> <TD BGCOLOR="#FFFFFE"><button id="<%out.println(app2[i]);%>" onClick="st(this.id) ">VEDI </button> </TD> Gargiulo Marco 566/1465 Pagina 131 di 135 </TR> <%}%> </TR> </TABLE> </TD> </TR> </TABLE> <% } String valore=badge+"|"+id_corso+"|"+password+"|"; session.setAttribute("valore", valore); %> <BR><BR></BR></BR><li><a href="dettagli_corso0.jsp">back </a></li> </body> </html> File “visualizza_lezioni.jsp”(Lato docente) <html> <body> <%@ page language="java" import="java.sql.*" %> <% String var = request.getParameter("valore") ; int i=0,cont=0; String app="",badge="",id_corso="",data="",password="",nullo="NULL"; while(i<var.length()) { char c; c=var.charAt(i); if(c!='|') { if (app.compareTo("")==0) app=Character.toString(c); else app=app+c; i++; } else{ if(cont==0){ badge=app; app="";} else{ if (cont==1){ id_corso=app;app="";} else{ if (cont==2) { data=app; app="";} else{ if (cont==3){password=app;app="";} } } cont++; i=i+1; } } Connection connessione=null; Statement statement=null; ResultSet rs=null; int rowCount=0; Class.forName("com.mysql.jdbc.Driver").newInstance(); Gargiulo Marco 566/1465 Pagina 132 di 135 try { String url="jdbc:mysql://localhost:3306/mgargiulo"; String dbName="root"; String password2="nagios-2012"; String userName="mgargiulo"; connessione = DriverManager.getConnection (url, dbName, password2); } catch(Exception e){ out.println(e.getMessage()); } statement = connessione.createStatement(); try { String query="SELECT COUNT(*) FROM timbratura WHERE((id_corso ='"+id_corso+"') && (data='"+data+"') && (ora_out!='NULLO'))"; rs = statement.executeQuery(query); rs.next(); rowCount = rs.getInt(1); } catch(Exception e){ out.println(e.getMessage()); } if(rowCount>0){ try{ String query="SELECT * FROM timbratura WHERE(id_corso='"+id_corso+"'&& data='"+data+"'&& ora_out!='NULLO)"; rs = statement.executeQuery(query); } catch(Exception e){ out.println(e.getMessage()); } %> <CENTER><H3> RIEPILOGO PRESENZE DELLA LEZIONE </H3></CENTER> <TABLE BORDER="1" CELLPADDING="0" CELLSPACING="0" BGCOLOR="#0000FF"> <TR> <TD> <TABLE BORDER="1" CELLPADDING="5" CELLSPACING="5"> <TR> <TD BGCOLOR="#FFFFFE">Badge Studente</TD> <TD BGCOLOR="#FFFFFE">Ora_in</TD> <TD BGCOLOR="#FFFFFE"> Ora_out</TD> </TR> <% while ((rs.next())) { String badge_studente= rs.getString("badge_studente"); String ora_in=rs.getString("ora_in"); String ora_out=rs.getString("ora_out"); %> <TR> <TD BGCOLOR="#FFFFFE"> <%out.println(badge); %></TD> <TD BGCOLOR="#FFFFFE"> <%out.println(ora_in);%> </TD> <TD BGCOLOR="#FFFFFE"> <%out.println(ora_out);%> </TD> </TR> <% Gargiulo Marco 566/1465 Pagina 133 di 135 } %> </TABLE> </TD> </TR> </TABLE> <% } else { out.println("Nessuno Studente Presente per la lezione selezionata"); } session.setAttribute("badge",badge); session.setAttribute("password", password ); %> <li><a href="visualizza_corsi.jsp">back</a></li> </body> </html> Gargiulo Marco 566/1465 Pagina 134 di 135 BIBLIOGRAFIA E SITOGRAFIA 1. Eric Freeman & Elisabeth Robson (2011) , Head First HTML 5 Programming, O'REILLY (USA) 2. Joe Walnes - Ara Abrahamian (2004), Java Open Source Programming, WILEY(USA) 3. Jim Melton – Andrew Eisenberg (2010), Understanding SQL and Java Together, O'REILLY (USA) 4. The Apache Software Fountation(2012), Apache Tomcat 7 Essentials, Packet Publishing 5. Richard Sezov(2008), Liferay Administrator's Guide, 2nd Edition, BROSSURA 6. Jonas X. Yuan(2010), Liferay Portal 6 Enterprise Intranets, Packet Publishing 7. Alain Trottier, Java 2 Enterprise Edition (J2EE) Web Component Developer Exam, Training Guide 8. Ian Sommerville, Ingegneria del Software, Addison – Wesley 9. UML Jim Arlow, iLa Neustadt, UML e Unified Process, McGraw-Hill, 2003 10. J. T. Roff, Fondamenti di UML McGraw-Hill, 2003 Gargiulo Marco 566/1465 Pagina 135 di 135
Documenti analoghi
documento programmatico sulla sicurezza dei dati personali
• gli hard disk non sono condivisi in rete se non temporaneamente per operazioni di copia;
• tutte le operazioni di manutenzione che sono effettuate on-site avvengono con la
supervisione dell'incar...