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