SlideShare une entreprise Scribd logo
1  sur  110
Télécharger pour lire hors ligne
Università Degli Studi di Trieste
                 Facoltà di Ingegneria
  Corso di Laurea Specialistica in Ingegneria Informatica
             Tesi di laurea in reti di calcolatori




Progetto e realizzazione di una infrastruttura
 modulare per acquisizione ed archiviazione
            remota di documenti



LAUREANDO                                            RELATORE
Giancarlo Todone                             Prof. Alberto Bartoli

                                                CORRELATORE
                                             Ing. Giorgio Davanzo




                Anno Accademico 2008/2009
Talk is cheap. Show me the code!
                (Linus Torvalds)
Indice



1 Introduzione                                                                      1

2 Il caso di studio                                                                  3
  2.1 Situazione iniziale e requisiti . . . . . . . . . . . .   .   .   .   .   .    3
  2.2 Architettura generale e definizioni . . . . . . . . .      .   .   .   .   .    5
       2.2.1 Flusso di un tipico caso di utilizzo . . . .       .   .   .   .   .    9
  2.3 Cenni di implementazione e tecnologie utilizzate .        .   .   .   .   .   11

3 SyncUtils                                                                         13
  3.1 Requisiti e scopi di SyncUtils . . . . . . . .     . . . . . . .          .   13
  3.2 Architettura . . . . . . . . . . . . . . . . . .   . . . . . . .          .   14
  3.3 Dettagli implementativi e tecnologie . . . .       . . . . . . .          .   20
      3.3.1 Perché il file system? . . . . . . . . .      . . . . . . .          .   20
      3.3.2 Meccanismo di sincronizzazione . . .         . . . . . . .          .   21
      3.3.3 Identificativi di richieste e risposte .      . . . . . . .          .   23
      3.3.4 Protocollo . . . . . . . . . . . . . . .     . . . . . . .          .   24
      3.3.5 Problematiche delle notifiche . . . .         . . . . . . .          .   27
      3.3.6 Formati dei file di comunicazione . .         . . . . . . .          .   28
      3.3.7 Serializzazione XML . . . . . . . . .        . . . . . . .          .   32
      3.3.8 COM . . . . . . . . . . . . . . . . .        . . . . . . .          .   35
  3.4 Installazione e preparazione dell’ambiente di      esecuzione .           .   40

                                       i
ii                                                                          INDICE

     4 GEC_Scan                                                                     43
       4.1 Requisiti e progetto dell’interfaccia utente . . . . . . . .         .   43
           4.1.1 Interfaccia grafica e usabilità . . . . . . . . . . .           .   44
       4.2 Composizione di GEC_Scan . . . . . . . . . . . . . . . .             .   49
           4.2.1 TWAIN . . . . . . . . . . . . . . . . . . . . . . .            .   50
           4.2.2 VisualSlideShow e design delle classi coinvolte . .            .   55
       4.3 Tecnologie e tecniche implementative . . . . . . . . . . .           .   58
           4.3.1 dotNetTwain . . . . . . . . . . . . . . . . . . . .            .   59
           4.3.2 Grafica . . . . . . . . . . . . . . . . . . . . . . .           .   68
       4.4 Installazione e preparazione dell’ambiente di esecuzione .           .   70

     5 Sottosistema di archiviazione e plug in                                      73
       5.1 Caratteristiche del sottosistema di archiviazione . .    .   .   .   .   73
           5.1.1 Funzionalità di manipolazione file . . . . . .      .   .   .   .   75
       5.2 Design del sottosistema di archiviazione . . . . . .     .   .   .   .   76
       5.3 Specifiche e tecnologie . . . . . . . . . . . . . . . .   .   .   .   .   80
           5.3.1 Archiviazione locale e debug . . . . . . . . .     .   .   .   .   84
           5.3.2 Funzionalità estese ed archiviazione Remota        .   .   .   .   85
                  5.3.2.1 Sharepoint . . . . . . . . . . . . .      .   .   .   .   86
                  5.3.2.2 Google Documents . . . . . . . . .        .   .   .   .   92
       5.4 Setup dei sistemi di archiviazione . . . . . . . . . .   .   .   .   .   97

     6 Conclusioni                                                                  99

     Bibliografia                                                                    103
Capitolo      1
Introduzione

La gestione di un documento cartaceo per via informatica inizia con le
operazioni di acquisizione ed archiviazione. Per “acquisizione” si intende
l’operazione di traduzione e codifica di un documento cartaceo in una
forma comprensibile e fruibile da un elaboratore. Per “archiviazione” si
può distinguere tra la mera operazione di immagazzinamento dati e la
“conservazione sostitutiva”—con la quale si intende tutto il complesso
di azioni che permettono di conservare elettronicamente dati di valore
legale o tributario senza per questo conservare anche i documenti cartacei
originali.

    A seguito e come proseguimento del tirocinio svolto presso la soft-
ware house MIDA4, lo scrivente ha realizzato un pacchetto software per
consentire di aggiungere le funzionalità di archiviazione al software di
contabilità preesistente GEC. Tale pacchetto fornisce una infrastruttura
per interfacciare GEC con altri sistemi di archiviazione (già esistenti o
futuri) grazie ad un sistema estendibile con plug in, e si inserisce in un
più ampio contesto di gestione documentale in sviluppo nel “Laborato-
rio Reti” del DEEI, Università Degli Studi di Trieste. Un tema trattato
con particolare riguardo è quello dell’archiviazione remota, cioè l’inte-
grazione con servizi di terze parti—come Google Documents o Microsoft
Sharepoint—per la memorizzazione dei dati su un server connesso ad
Internet.

                                      1
2                                                                1. Introduzione

        Dall’osservazione della situazione di partenza, dopo lo studio del pro-
    blema nella sua accezione più generale, sono stati definiti dei requisiti
    che hanno portato alla suddivisione del lavoro nei tre moduli software
    responsabili di comunicazione, acquisizione e archiviazione; per ognuno
    dei tre moduli sono stati definiti ulteriori requisiti in base ai quali sono
    state poi concepite l’architettura e le specifiche tecnologiche di ogni sin-
    gola parte. Ogni classe o componente sviluppato è stato verificato con
    metodologie di unit-test ed in alcuni casi anche con test automatici di
    carico. L’intero progetto ha subito anche diversi test funzionali condotti
    da operatori umani.
        I requisiti tecnologici del committente hanno portato alla scelta del
    linguaggio C# e del framework dotNet all’interno dell’ambiente di svi-
    luppo integrato Visual Studio 2008, su un sistema operativo Windows
    XP/Vista. L’interfacciamento con le periferiche di acquisizione è gestito
    con lo standard TWAIN mentre l’interfacciamento con il software GEC
    è gestito con le tecnologie COM e XML.
        Nel capitolo 2 si affrontano tematiche di carattere generale inerenti
    l’insieme del software sviluppato. Nei tre capitoli successivi ( 3 nella pa-
    gina 13, 4 nella pagina 43, 5 nella pagina 73) si affrontano separatamente
    i tre moduli software, esponendo di ognuno:

       • situazione pregressa e/o requisiti;

       • architettura e definizioni;

       • tecniche implementative e tecnologie utilizzate;

    aggiungendo—ove pertinente—un breve riassunto delle operazioni
    necessarie all’installazione e alla manutenzione del modulo.
Capitolo      2
Il caso di studio

2.1     Situazione iniziale e requisiti
La software house MIDA4 ha prodotto e mantiene il software di con-
tabilità chiamato GEC. La necessità dei clienti di MIDA4 di archiviare
documenti per via informatica contestualizzandoli con le loro situazioni
amministrative e altri dati, ha spinto la software house a ricercare un
modo per ampliare in tal senso le capacità del suo prodotto.
    La richiesta era quella di aggiungere le funzionalità desiderate in un
modo che permettesse di iniziare a servirsi di tecnologie più recenti e
promettenti senza per questo dover riscrivere da capo un programma già
rodato e funzionante come GEC.
    GEC viene attualmente fornito in due versioni: installabile e ASP
(2.2):

   • la versione installabile è un normale programma che risiede ed ope-
     ra sul personal computer dell’utente finale, ed eventualmente co-
     munica con un server centralizzato per recuperare informazioni di
     licenza ed aggiornamenti;

   • la versione ASP consiste nella versione installabile montata però su
     un server accessibile da molti fruitori contemporaneamente tramite
     Internet ed un software di remote desktop.

                                      3
4                                                             2. Il caso di studio

    Il software necessario ad aggiungere le funzionalità di archiviazione de-
    siderate, deve necessariamente interagire con GEC—qualsiasi sia la sua
    ubicazione—ma deve anche interagire con l’hardware dell’utente fina-
    le (es: scanner e fotocamere) e deve essere in grado di comunicare
    autonomamente con eventuali servizi di archiviazione di terze parti.
        Il modo in cui il nuovo software si integra con GEC deve

      1. richiedere il minimo sforzo in termini di modifiche al codice
         sorgente di GEC;

      2. essere facilmente utilizzabile dagli sviluppatori di GEC;

      3. permettere l’integrazione futura con nuovi servizi di terze parti
         senza riscrivere il codice sorgente;

    per poter permettere rispettivamente:

      1. di rendere il più possibile indipendenti lo sviluppo e il manteni-
         mento di GEC da quelli del nuovo software di archiviazione;

      2. di consentire una rapida integrazione al momento del rilascio;

      3. di poter essere rapidamente espandibile con nuove funzionalità.

    Dal punto di vista dell’utente, il software sviluppato dev’essere:

       • facilmente integrabile con il proprio sistema di produzione;

       • di utilizzo semplice ed immediato.

        In quest’ottica, un sistema di astrazione delle periferiche di acquisi-
    zione immagini dell’utente è stato posto come requisito; fondamentale è
    anche la trasparenza di tale meccanismo, necessaria al fine di ottenere
    un’interfaccia grafica consistente per tutti gli utenti, a prescindere da
    marca e modello dei loro hardware.
        Infine, la scelta dell’ambiente di sviluppo ha dovuto tenere conto di
    varie richieste:

       • GEC opera in ambiente Microsoft Windows, e quindi anche il nuovo
         software di archiviazione deve funzionare almeno in tale sistema;
Architettura generale e definizioni                                             5

   • esso deve consentire di proporre all’utente finale un’interfaccia
     piacevole, immediata e consistente;
   • metodologie, linguaggi, librerie, framework utilizzati (a parte quelli
     finora citati che hanno diverse motivazioni) devono essere allo stato
     dell’arte, o quantomeno ancora vivamente supportati da produttori
     e da una nutrita schiera di sviluppatori; essi devono però permet-
     tere allo sviluppatore di interfacciarsi anche con moduli software
     utilizzanti tecnologie meno recenti, come TWAIN o Visual Basic 6
     (di cui—come vedremo—fanno uso alcune parti del sistema).
Da ciò si evince come la capacità di interoperabilità tra diverse tecnolo-
gie sia essa stessa un requisito; viste queste necessità, in fase di analisi
preliminare è stato posto l’utilizzo del dotNet framework di Microsoft
come requisito.


2.2      Architettura generale e definizioni
Per motivi di natura tecnica e per questioni di manutenibilità del codice
che vedremo in seguito, il modulo che dovrà svolgere le operazioni di
acquisizione e archiviazione dev’essere indipendente, cioè non fare parte
di GEC, ma essere compilato in un eseguibile autonomo: questo significa
che GEC e il nuovo software di acquisizione sono due entità distinte che
necessitano di comunicare.
    Si considerino quindi i seguenti attori:
GEC è il programma di contabilità già esistente, che dovrà subire delle
   modifiche per poter utilizzare SyncUtils e comunicare con il soft-
   ware di nuova creazione dedicato all’acquisizione e archiviazione;
   in seguito, se non esplicitamente specificato, col nome di GEC ci
   si riferirà indistintamente al programma in versione tradizionale o
   ASP;
GEC_Scan è il software di acquisizione e archiviazione: esso è un soft-
   ware a se stante, ma può dialogare con GEC—tramite un mec-
   canismo descritto in 3.3 nella pagina 20—e con servizi di terze
   parti—mediante dei moduli aggiuntivi chiamati plug in ( 5.3 nella
   pagina 80).
6                                                                                                                                     2. Il caso di studio




                                                                   



                                                                                                        ASP Remote desktop
                           Internet                                                                                                                          (A)
                                                                                                                             User 1
                                                                                                                                           GEC_Scan

                                                                                                        ASP Remote desktop



                                                                                                                                             GEC-2           (B)
                                                                                                                             User 2
                   ASP




     GEC-1
                                                                                                                                           GEC_Scan



                                                                                                                                             GEC-3           (C)
                                                                                                                             User 3

                                                                                                                                           GEC_Scan




    Figura 2.1: Tre casi di utilizzo del sistema di archiviazione: nel caso (A)
    l’utente 1 utilizza solo l’istanza 1 di GEC tramite ASP e il suo sistema di
    remote desktop; nel caso (C) l’utente 3 utilizza solo GEC-3 in esecuzione sul
    suo computer locale; nel caso (B), l’utente 2 utilizza sia la locale istanza 2 di
    GEC, sia GEC-1 tramite sistema ASP.



        Queste due entità devono poter comunicare tra loro in vario modo.
    Nel caso più semplice GEC e GEC_Scan vengono eseguiti sullo stesso
    calcolatore e comunicano senza interferenze esterne; in figura 2.1 si os-
    servano anche i casi in cui GEC sia remoto e quello più complesso in cui
Architettura generale e definizioni                                                7

un solo utente utilizzi più istanze di GEC, eventualmente miste tra locali
e remote.




                                                             plug in




                       SyncUtils
          GEC                          GEC_Scan              plug in

                                                             plug in




                                      
                                      
                                      
                                      
                                      
                                      
                                      
                                      
                                                
                                                
                                                
                                                
                                                
                                                
                                                
                                                         
                                                         
                                                         
                                                         
                                                         
                                                                  
                                                                  
                                                                  
                                                                  
                                          acquisizione     archiviazione
                      
                      
                      
                      
                      
                                   
                                   
                                   
                                   

                                      
                                      
                                      
                                      
                                      
                                      
                                      
                                      
                                      
                                      
                                      
                                      
                                      
                                      
                                      
                                      
                                      
                                      
                                                         
                                                         
                                                         
                                                         
                                                         
                                                         
                                                         
                                                         
                                                         
                                                         
                                                         
                                                         
                                                         
                                                         
                                                         
                                                         
                                                         
                      comunicazioni              funzionalità
     
     
     
     
     
              
              
              
              
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                      
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
         software                         software
       preesistente                        nuovo


Figura 2.2: Descrizione dei software coinvolti; GEC è preesistente e viene
modificato solo per poter usare SyncUtils; il resto del software è sviluppato
ex novo; di questo è visibile la suddivisione in comunicazioni, acquisizione ed
archiviazione: solo le ultime due implementano funzionalità richieste, mentre
la prima serve a rendere interoperabili nuovo e vecchio software.

    Come illustrato in figura 2.2, tutte le funzionalità aggiunte risiedono
in GEC_Scan e nei suoi plug in, mentre la libreria SyncUtils consente a
GEC di comunicare con GEC_Scan e di utilizzare tali funzionalità.
    Si consideri inoltre la seguente nomenclatura:
Utente è l’utente finale di GEC e di GEC_Scan, colui che opera i pro-
    grammi per archiviare documenti; si faccia attenzione alla differen-
    za tra “utente finale” e l’utente di una libreria (sviluppatore) o di
    un servizio (potrebbe essere un modulo software);
8                                                              2. Il caso di studio

    Documento un insieme di più immagini corredate da meta dati;



    ASP acronimo di Application Service Provider, è il sistema che permet-
       te tramite un remote desktop di utilizzare dal PC dell’utente finale
       un’istanza di GEC in esecuzione su un server remoto; da non con-
       fondersi con Active Server Pages di Microsoft (di cui non si parla
       mai in questo testo);



    Plug in è un modulo software che consente di aggiungere funzionalità
         a GEC_Scan senza la necessità di modificare o ricompilare il suo
         codice sorgente;



    Servizio esterno un qualsiasi servizio di archiviazione di documenti
         estraneo sia a GEC che a GEC_Scan, probabilmente pubblicato
         tramite un servizio web.



    Sessione di acquisizione l’insieme di operazioni iniziate dall’utente
         che portano all’acquisizione, riorganizzazione in documenti e archi-
         viazione di un insieme di immagini con i loro meta dati associati
         (punti da 2 a 9 in 2.2.1 nella pagina 10 e figura 2.3; si noti che tra il
         punto 3 e il punto 4 il sistema rimane indefinitamente in attesa di
         istruzioni dall’utente; quindi può essere un operazione che richiede
         molto tempo).



    In aggiunta—se non per esigenze particolari—si eviterà di seguito l’uti-
    lizzo di termini come “server” e “client” per riferirsi a GEC o GEC_Scan,
    poiché potrebbero essere causa di fraintendimenti; infatti nella sua ver-
    sione ASP, il software GEC viene eseguito su una macchina che interpreta
    il ruolo di server, ma per correttezza dovrebbe essere considerato client
    del software di acquisizione che gli offre per l’appunto un servizio.
Architettura generale e definizioni                                                                                                9

 2.2.1              Flusso di un tipico caso di utilizzo



                               1.richiede inizio
                               sessione di acquisizione




                                                                            Utente
                     2.Request                           3.mostra form
                                                         principale
                                             Acquisizione
                                                                                   (tempo



                                             
                                                                                                   indefinito)
                                                           4.accetta o
                                                           annulla


                                         (C): GEC_SCAN
                        (B): SyncUtils
         (A): GEC
tempo




                                                         5.esegue il
                                                         plug in adeguato
                                                                                           6.sottomette




                                                                                                           (E): Servizio esterno
                                                                                           documenti




                                                                            (D): Plug in
                                                                                           7.fine del job
                                                          8.fine del job
                    9.Response




 Figura 2.3: Flusso di esecuzione di una richiesta e relativa risposta; vede-
 re 2.2.1 nella pagina successiva per una descrizione puntuale dei passi nume-
 rati; la progettazione e creazione delle entità marcate come (B), (C) e (D)
 costituiscono il caso di studio; le linee ondulate indicano il punto in cui l’utente
 può causare un’attesa a tempo indeterminato del sistema; (B) risolve i proble-
 mi di comunicazione tra (A) e (C) siano essi sulla stessa macchina oppure su
 macchine diverse comunicanti tramite Internet.
10                                                                      2. Il caso di studio

     Un tipico caso di utilizzo del sistema—nel quale una singola istanza di
     GEC comunica con una singola istanza di GEC_Scan—si svolge co-
     me di seguito (i punti numerati si riferiscono a figura 2.3 nella pagina
     precedente):
            • il sistema dell’utente si avvia; parte automaticamente anche il soft-
              ware di acquisizione e carica dalla cartella plugins le estensioni
              di cui è stato dotato;
            • l’utente carica e opera GEC (versione installabile o ASP), mentre
              il programma di acquisizione (eseguito allo start up sul sistema
              dell’utente) resta in attesa nascosto;
        1. l’utente esegue un’operazione su GEC per la quale è prevista
           l’acquisizione di un certo numero di documenti;
        2. GEC—tramite una chiamata all’apposita libreria di comunicazione
           SyncUtils—effettua una richiesta a GEC_Scan; ad esso (sia que-
           sto in esecuzione sulla medesima macchina o su di una diversa)
           viene segnalato di mostrare la sua finestra principale, inviandogli
           nel contempo i meta dati da associare ai documenti che si andrà
           ad acquisire ed una lista di azioni desiderate da intraprendere su
           di essi; se la finestra era già aperta a seguito di una precedente
           richiesta non ancora soddisfatta, il lavoro viene messo in coda;
        3. GEC_Scan accetta la richiesta e la accoda ad una lista o la scarta
           rispondendo con una lista di errori (ad esempio quando non è in
           grado di gestire la richiesta);
        4. l’utente usa le funzionalità del programma di acquisizione per scan-
           sionare1 ed ordinare un certo numero di pagine inerenti la richiesta
           accettata; l’utente può inserire dei separatori tra gruppi di immagi-
           ni per organizzare il materiale acquisito in documenti: ad ogni do-
           cumento vengono associati tutti i meta dati ricevuti; alla fine della
           riorganizzazione e separazione dei documenti, l’utente sottomette
           i dati o annulla la sessione con appositi comandi;
        1
          Sulla scelta tra gli equivalenti italiani dell’inglese “to scan” l’Accademia della
     Crusca si è espressa nelle “Risposte ai quesiti” concludendo che sono accettabili tutte
     le soluzioni (scandire, scannare, scannerare, scannerizzare, scansionare) [3].
Cenni di implementazione e tecnologie utilizzate                               11

   5. GEC_Scan cerca tra i plug in caricati quelli in grado di soddisfare
      le richieste effettuate da GEC tramite la libreria di comunicazione
      ed esegue ogni operazione ritenuta pertinente su ogni documento;

   6. questo può comportare il dialogo con un ulteriore software di ar-
      chiviazione, anche residente su una macchina diversa da quella su
      cui è in esecuzione GEC e da quella su cui esegue il programma
      di acquisizione (esempio: inviare tutti i documenti ad un servizio
      web);

   7. il software di acquisizione completa ogni elaborazione e compila un
      rapporto con il dettaglio delle operazioni effettuate e un’eventuale
      lista di errori;

   8. il software di acquisizione invia la risposta così costruita a GEC
      sempre tramite libreria di comunicazione;

   9. GEC riceve la notifica che i suoi lavori richiesti sono stati
      completati (o annullati);

   • nel caso la coda di lavori del software di acquisizione non sia vuo-
     ta, l’utente viene invitato a continuare il suo lavoro con un’altra
     sessione di sottomissione documenti.


2.3     Cenni di            implementazione            e    tecnologie
        utilizzate
Il programma preesistente GEC è stato sviluppato in Visual Basic 6,
kit di sviluppo capace di generare file di codice eseguibile nativo; esso
permette anche una buona interazione con componenti COM.
    Nei seguenti tre capitoli, viene trattato il software sviluppato ex novo
per aggiungere a GEC le funzionalità di acquisizione e archiviazione:

libreria di comunicazione (progetto di nome “SyncUtils”) che per-
      mette ad un’istanza di GEC di effettuare richieste ad un’istanza di
      GEC_Scan e riceverne risposta, in 3 nella pagina 13;
12                                                                  2. Il caso di studio

     software GEC_Scan che tramite interfaccia grafica permette l’acqui-
          sizione di documenti, in 4 nella pagina 43;

     plug in che permettono a GEC_Scan di accedere a servizi di
          archiviazione di terze parti, in 5 nella pagina 73.

     Tutti questi moduli software sono stati sviluppati nel linguaggio C# e
     utilizzano quindi il dotNet framework (versione 2.0 o successive).
         Con riguardo alla libreria di comunicazione, in 3.3.8 nella pagina 35
     si parla della necessaria metodologia di interazione tra codice mana-
     ged e codice nativo: l’utilizzo di oggetti dotNet come componenti COM
     tramite software wrapper.
         Quest’ultimo sistema è stato adottato per permettere a GEC di chia-
     mare delle funzioni sviluppate con tecnologia dotNet; in questo modo la
     libreria SyncUtils è richiamabile sia da codice nativo (come avviene per
     GEC) sia da codice dotNet.
         Le funzioni di comunicazione utilizzano un meccanismo di sincronia e
     comunicazione basato sulla condivisione di un file system ( 3.2 nella pa-
     gina 14) per scambiarsi messaggi XML (formato descritto in 3.3.6 nella
     pagina 28) secondo il protocollo descritto in 3.3.4 nella pagina 24. La ge-
     nerazione del codice XML avviene tramite meccanismo semi automatico
     per serializzazione di oggetti ( 3.3.7 nella pagina 32).
         Per l’interfacciamento di GEC_Scan con le periferiche di acquisizio-
     ne immagini è stato usato TWAIN ( 4.2.1 nella pagina 50)—secondo
     le specifiche versione 1.9 [5]—tramite l’apposito sviluppo della libreria
     dotNetTwain. TWAIN si presenta come una DLL contenente codice
     nativo a 32 bit; per l’utilizzo da parte di dotNet, è quindi necessa-
     rio adottare ulteriori tecniche di interoperabilità con l’aiuto del package
     System.Runtime.InteropServices ( 4.3.1 nella pagina 59).
         Ogni plug in è stato sviluppato come una classe dotNet residente
     in un assembly dotNet2 . Per permettere il rapido sviluppo di plug in
     sono state sfruttate alcune caratteristiche del framework dotNet come
     reflection e caricamento dinamico di classi.

       2
         Un assembly dotNet è una DLL contenente bytecode dotNet nella forma di una
     o più classi appartenenti anche a diversi namespace, con i rispettivi meta dati di
     contorno.
Capitolo       3
SyncUtils

3.1     Requisiti e scopi di SyncUtils
La parte del progetto che deve interagire più intimamente con GEC è la
libreria di comunicazione chiamata SyncUtils. Mentre le funzionalità di
archiviazione aggiuntive risiedono principalmente in GEC_Scan e nel-
l’insieme dei suoi plug in, esse non potrebbero essere utilizzate da GEC
senza l’ausilio di questa libreria: il suo scopo è quello di astrarre il meto-
do di comunicazione dalle modalità tecniche con le quali le comunicazioni
effettivamente avvengono.
    L’ambiente nel quale il sistema progettato deve operare prevede:

   • molti software di scansione (GEC_Scan) che hanno a disposizione
     varie sorgenti di dati e vengono manovrati da operatori umani;

   • uno o più software di controllo (GEC) che possano richiedere
     ad uno dei software di scansione di cominciare una sessione di
     acquisizione.

GEC_Scan deve essere in grado di accettare una richiesta di inizio proce-
dura di acquisizione, gestirla autonomamente e inviare alla fine la notifica
dell’avvenuto lavoro senza tenere GEC in sospeso, permettendogli così
di gestire nel frattempo eventuali altre comunicazioni.

                                       13
14                                                                  3. SyncUtils

        Siamo perciò interessati ad un tipo di comunicazione nella quale—nel
     caso peggiore (facendo riferimento alle figure 2.1 nella pagina 6 e 3.1):

        • come attori, sono coinvolte m istanze di GEC in versione installa-
          bile (al massimo una per macchina), n istanze remote di GEC in
          versione ASP, i istanze di GEC_Scan (al massimo una per macchi-
          na), con i, m ed n numeri imprecisati non necessariamente uguali,
          maggiori di 1;

        • ogni attore può prendere l’iniziativa di parola;

        • ogni GEC in versione installata può parlare col GEC_Scan
          presente sulla sua stessa macchina (se presente);

        • ogni GEC in versione ASP può parlare con qualsiasi GEC_Scan;

        • ogni GEC_Scan può parlare con GEC installato sulla sua stessa
          macchina e con qualsiasi altro GEC in versione ASP.

         Cioè: ogni utente col suo calcolatore deve poter usare la sua unica
     copia di GEC_Scan facendola interagire con un GEC installato sulla sua
     stessa macchina e/o con un certo numero di altri GEC remoti.


     3.2     Architettura
     Si assuma che ogni copia di GEC_Scan abbia accesso in lettura e scrit-
     tura ad una porzione privata del file system dell’elaboratore sul quale
     è installato; chiunque voglia dialogare con esso (ad es. GEC installato
     o GEC versione ASP) dovrà poter avere accesso in lettura e scrittura
     alla stessa porzione del file system (per brevità di seguito “file system” o
     “FS”).
         La comunicazione è dunque a mezzo condiviso, nel senso che gli attori
     che dialogano tra loro di volta in volta devono condividere un file system
     cui hanno accesso; per analizzare il caso più generale continueremo a
     dire che ogni GEC condivide con l’i-esimo GEC_Scan il file system i (o
     FS-i).
         Le richieste vengono effettuate da un GEC scrivendo nel FS-i dei
     file con estensione .IN contenenti i dettagli delle richieste in formato
Architettura                                                              15

XML ( 3.3.6 nella pagina 28); le risposte al termine di una sessione di
acquisizione vengono fornite da GEC_Scan scrivendo nel FS-i dei file
con estensione .OUT e nome file uguale alla corrispondente richiesta.



                                 GEC



                                 ASP




                       ASP
               GEC                                  GEC
                                 FS-i




                             GEC_Scan-i



Figura 3.1: Schema dell’utilizzo concorrente da più istanze di GEC del
file system i, associato alla i-esima istanza di GEC_Scan.

    Naturalmente, più processi potrebbero accedere contemporaneamen-
te ad uno stesso file system; è tuttavia stato approntato un meccanismo
di mutua esclusione (descritto in 3.3.2 nella pagina 21):
   • per fare in modo che ogni richiesta abbia un nome univoco sul
     file system i;
   • per garantire che più GEC concorrenti nell’effettuare una richiesta
     allo stesso GEC_Scan non si intralcino a vicenda;
   • per fare in modo che le richieste siano ordinabili—per istante di
     arrivo—in una coda.
16                                                                  3. SyncUtils

     Un attore che voglia prendere possesso del mezzo comunicativo costitui-
     to dal FS-i, per prima cosa utilizzerà detto meccanismo impedendo a
     qualunque altro attore di impadronirsi a sua volta del file system.
         Ovviamente non sempre un attore riesce a prenotare l’uso esclusivo
     del file system, ad esempio quando questo è già in uso da un altro attore;
     in seguito ( 3.3.2 nella pagina 21) si darà spiegazione dei dettagli del
     meccanismo: si dica “tentativo di acquisizione del lock ” il tentativo di
     impadronirsi del mezzo di comunicazione, e “acquisizione del lock ” il
     provare reiteratamente ad acquisire il lock finché non si abbia successo.
         La generazione di un nome file univoco nel FS-i, necessaria per la
     scrittura dei file .IN dipende da una stringa originata a partire dalla da-
     ta/ora della sua creazione: questa stringa e l’entità che essa rappresenta
     assumono il nome di JobId. Definiamo quindi un JobId come l’iden-
     tificativo univoco all’interno di un file system, utilizzato per identificare
     esattamente richieste e relative risposte.
         Ogni file di nome {JobId}.IN contiene delle informazioni organiz-
     zate in un’entità chiamata Request; ogni file di nome {JobId}.OUT
     contiene dati relativi ad un’entità di tipo Response.
         Come si può osservare in figura 3.2 nella pagina successiva, ogni
     Request contiene:

        • una o più ActionRequest;

        • uno e un solo AdditionalData;

        • un Timestamp.

     In ottica di programmazione ad oggetti, ActionRequest e
     AdditionalData sono solo delle classi base astratte, atte a definire
     l’archetipo dei campi contenuti in ogni richiesta: una Request ben for-
     mata non conterrà mai direttamente una ActionRequest, bensì una
     classe derivata da essa (similmente per AdditionalData ed altre clas-
     si simili); d’ora in avanti per “una ActionRequest” ad esempio, si
     intenderà una qualsiasi entità che derivi da ActionRequest e non un
     oggetto di tipo ActionRequest, se non diversamente specificato.
Architettura                                                                   17



                            Response

   Request                    Document
                                                                 Page
   ActionRequest               ActionResponse
                                 ResponsePage                    Page
   ActionRequest                  ResponsePage
                                                                 Page
                               ActionResponse
                                 ResponsePage                    Page
   AdditionalData
                                  ResponsePage


                              Document
                               ActionResponse                    Page
                                  ResponsePage


                               ActionResponse
                                 ResponsePage




Figura 3.2: Esposizione grafica della struttura di Request e Response; le
frecce indicano che l’oggetto d’origine mantiene internamente un riferimento
all’oggetto puntato.


    Le azioni intraprese da GEC_Scan alla ricezione di una Request
dipendono dal tipo specializzato di ogni ActionRequest contenuta;
AdditionalData contiene dei meta dati che devono essere interpreta-
ti da GEC_Scan per soddisfare correttamente ogni richiesta e possono
essere associati ai documenti acquisiti.
18                                                                    3. SyncUtils

           Per quanto riguarda Response essa contiene sempre:

           • la sezione Documents;

           • la sezione Errors, relativa agli errori generici di comunicazione.

     Si ponga attenzione sul fatto che un documento è stato definito come
     un’insieme di una o più immagini: finora non si è parlato di alcun limite
     al numero di immagini acquisibili dall’utente, o di vincoli sul modo di
     raggrupparle in documenti; quindi nè il numero di documenti che ver-
     ranno elaborati nè il numero di pagine di ognuno di questi è predicibile
     salvo casi particolari1 .
         Per questi motivi, in una Response

           • Documents contiene uno o più oggetti Document, entità
             rappresentante un gruppo di immagini;

           • ogni Document contiene una lista di oggetti Page, entità
             rappresentanti le singole immagini scansionate dall’utente;

           • ogni Document contiene una o più ActionResponse (con
             considerazioni simili al caso di ActionRequest);

           • ogni ActionResponse rappresenta il rapporto su una sola
             azione intrapresa per il Document che la contiene in seguito
             all’elaborazione di una ActionRequest;

           • ogni ActionResponse contiene una lista di ResponsePage,
             enumerazione delle azioni intraprese sulle singole Page del
             Document.

     Anche in questo caso l’esatto contenuto di una ActionResponse dipen-
     de dalla classe specializzata che la estende. Si pensi al seguente esempio
     pratico: si ha la necessità di archiviare una fattura del signor Mario Ros-
     si presso un servizio di archiviazione remota chiamato “MyArchive”; a
     tale scopo saranno stati precedentemente definiti alcuni tipi specializzati
     come
       1
        In realtà GEC può richiedere un numerno minimo ed uno massimo di gruppi di
     immagini (vedi 4.1.1 nella pagina 47).
Architettura                                                                  19

   • SendToMyArchiveActionRequest;

   • SendToMyArchiveActionResponse;

   • SendToMyArchiveActionPerformer;

   • SendToMyArchiveResponsePage;
derivanti rispettivamente da
   • ActionRequest;

   • ActionResponse;

   • ActionPerformer;

   • ResponsePage.
In più, per veicolare correttamente i dati relativi ad una fat-
tura, InvoiceAdditionalData è stato derivato—con l’ag-
giunta di appositi campi—da AdditionalData.            A que-
sto punto è possibile costruire una Request contenente ad
esempio una sola SendToMyArchiveActionRequest ed un
InvoiceAdditionalData.
SendToMyArchiveActionRequest conterrà informazioni relative
    l’indirizzo al quale raggiungere il servizio MyArchive ed
    impostazioni simili;

InvoiceAdditionalData potrebbe contenere l’anagrafica del signor
    Mario Rossi e ogni altro dato utile ai fini della compilazione dei
    meta dati associati ai documenti veri e propri.
Se l’utente ha acquisito due documenti da tre pagine ciascuno, con tale ri-
chiesta è lecito aspettarsi una risposta per cui vi saranno due Document
contenenti tre Page e una SendToMyArchiveActionResponse cia-
scuno; ogni SendToMyArchiveActionResponse conterrà a sua volta
tre SendToMyArchiveResponsePage, ognuna delle quali—facendo
riferimento ad una singola Page—fornirà ad esempio informazioni sul
successo o meno dell’archiviazione, un link per recuperare l’immagine
corrispondente ecc. . .
20                                                                    3. SyncUtils

         Tutti i tipi specializzati, finalizzati a specifiche richieste, sono defi-
     niti nei moduli aggiuntivi chiamati plug in, caricati in modo dinamico
     all’avvio di GEC_Scan.


     3.3     Dettagli implementativi e tecnologie
     Posto che GEC_Scan è un modulo software a se stante, anche il solo
     aggiungere a GEC le funzionalità di comunicazione con quest’ultimo ri-
     chiede necessariamente la modifica del programma e l’aggiunta di molto
     codice.
         Integrare direttamente in GEC queste capacità sviluppandole in Vi-
     sual Basic 6—lo stesso linguaggio in cui è stato scritto—sarebbe potuta
     sembrare una buona idea: al contrario, aggiungere a del codice già ma-
     turo una ulteriore complessità per quanto lieve, potrebbe portare a dei
     problemi di manutenibilità.
         Se si aggiunge il fatto che il kit di sviluppo di Visual Basic 6 è alla
     fine del suo ciclo di vita, si capisce come sia stato preferibile comporre il
     sistema di comunicazione con una tecnologia più moderna: si è scelto di
     sviluppare con dotNet e la tecnologia COM del codice che—proprio dal
     punto di vista del ciclo di vita—è autonomo e interfacciabile con GEC
     con un ridotto numero di modifiche a quest’ultimo.
         La libreria SyncUtils è utilizzabile da codice dotNet come un qualsiasi
     altro assembly e (previa registrazione di alcuni tipi, 3.4 nella pagina 40)
     come componente COM.


     3.3.1    Perché il file system?
     La comunicazione tra sistemi informatici è sempre un ambito insidioso
     e ricco di difficoltà, spesso nemmeno troppo palesi; anche per questo
     motivo, nell’affrontarlo si tenta quasi sempre di evitare di reinventare la
     ruota: come in molte altre situazioni ci si affida più il possibile a soluzioni
     già note ed affermate, almeno per i problemi più comuni.
         Nel caso in esame, ci si trova nella situazione abbastanza tipica di un
     software (GEC_Scan) che pur eseguendo sull’elaboratore di un utente
     finale (ed essendo perciò molto probabilmente isolato dalla rete da un
Dettagli implementativi e tecnologie                                                     21

firewall e da un sistema NAT/NAPT) deve comportarsi come server,
attendendo richieste e non iniziandole.
    Le possibili soluzioni note che usino protocolli consueti come
TCP/IP, sarebbero comunque state tutte piuttosto complesse da mettere
in pratica: fortunatamente il sistema ASP—come già accennato—mette
a disposizione un file system condiviso tra i suoi utilizzatori.
    L’utilizzo di un file system condiviso per la sincronia tra processi, la
regolamentazione di accesso esclusivo a risorse e lo scambio di informazio-
ni, è una pratica da tempo largamente diffusa e di dimostrata efficacia2 :
lo studio di alcune specifiche Microsoft [8] ed alcuni esperimenti condotti,
hanno consentito di giudicare tali metodologie idonee anche all’utilizzo
su un file system condiviso con una macchina remota tramite il sistema
ASP.
    Ciò permette di delegare al gestore del file system alcune problemati-
che descritte in seguito come l’atomicità della creazione di un oggetto di
sincronia, la sicurezza del canale trasmissivo, la capacità di comunicare
in determinate condizioni.


3.3.2     Meccanismo di sincronizzazione
L’acquisizione del lock per il file system i, si effettua tramite la scrittura
in esso di un file—vuoto—di nome concordato che non possa collidere
con gli eventuali file .in e .out già presenti (attualmente esso si chiama
lockfile.lck). Si dice che tale lock viene rilasciato quando il file viene
cancellato.
    Un attore che volesse acquisire il lock dovrebbe per prima cosa veri-
ficare che tale file non esista già e solo in tal caso provvedere a crearlo;
una volta creato, altri attori desiderosi di acquisire il lock rileverebbero
la presenza del file sopra citato e desisterebbero (o resterebbero in attesa
che il file venga rimosso, a seconda dei casi).
    È di fondamentale importanza capire come l’operazione di verifica e
creazione del file di lock debba necessariamente essere atomica per gestire
le eventuali situazioni di concorrenza: non è accettabile alcuna situazio-
   2
    Basti pensare ai files di lock utilizzati da alcuni software di database o a quelli
usati del popolare Microsoft Word per regolare l’accesso ai suoi documenti.
22                                                                   3. SyncUtils

     ne di inconsistenza come quella riportata di seguito a titolo d’esempio:
     nell’ordine

       1. l’attore A vuole acquisire il diritto di parola, pertanto tenta di
          segnalarlo, provando a creare il file di lock ;

       2. in un istante di tempo ravvicinato ad (1) l’attore B vuole acquisire
          anch’esso il diritto di parola, pertanto tenta di creare a sua volta
          il file di lock ;

       3. A verifica che il file di lock non esiste;

       4. B verifica che il file di lock non esiste;

       5. A crea fisicamente il file di lock ;

       6. B—visto il punto 4—crede che il file di lock non esista e lo
          sovrascrive.

     Se il sistema di sincronia fosse prono ad un tale tipo di errore, due attori
     potrebbero ritenere di essere ognuno l’unico autorizzato ad accedere al
     file system in un dato istante di tempo, creando JobId non certamente
     univoci e sovrascrivendo potenzialmente l’uno i file dell’altro, portando
     così ad evoluzioni impredicibili nella comunicazione.
         Il problema della atomicità delle operazioni di verifica e creazione
     del file di lock viene risolto considerando che all’atto della creazione di
     un nuovo file, in ambiente Microsoft Windows si può indicare al sistema
     cosa fare nel caso in cui non sia possibile completare l’operazione (es:
     perché il file esiste già): sovrascrivere il file, accodare al contenuto o
     segnalare un’errore. Quando un attore desidera acquisire il lock, può
     semplicemente provare a creare il file, istruendo il sistema operativo a
     sollevare un’errore in caso di fallimento: se non si riceve alcun errore il
     lock è acquisito, altrimenti no.
         Al sistema operativo si delega la responsabilità della consistenza del
     suo file system; in caso di file system remoti, il sistema operativo che
     fornisce l’accesso remoto ad un file system da lui mantenuto si occupa di
     garantire la consistenza quando più processi tentino di creare lo stesso
     file [8].
Dettagli implementativi e tecnologie                                              23

    Per impedire che altri processi come un antivirus o lo stesso uten-
te possano inavvertitamente interferire col meccanismo di sincronia, il
file viene mantenuto aperto in modalità esclusiva per tutto il tempo di
detenzione del lock : in questo modo è impossibile per chiunque altro
cancellarlo, rinominarlo o modificarlo.
    Nel caso il processo detentore del lock venga terminato, il file resta
scritto sul file system, ma la modalità esclusiva viene a mancare: ogni
eventuale altro processo in attesa di rilascio del lock non avrà speranze
di acquisirlo fino al prossimo riavvio di GEC_Scan che causa la pulizia
dei file residui di vecchie esecuzioni.


3.3.3    Identificativi di richieste e risposte
Richieste e risposte vengono scambiate tramite dei file di estensione .IN
e .OUT, diversi dal file di lock ma residenti nel suo stesso file system.
Questi file hanno sempre il nome costituito da dodici cifre ed un trattino
orizzontale, che rappresenta il JobId del lavoro in questione.
    Un JobId è stato definito come l’identificativo univoco all’interno
di un file system, utilizzato per identificare univocamente richieste e ri-
sposte. Esso viene generato a partire dalla data-ora della sua creazione;
nell’implementazione C# è in realtà un oggetto che conserva come stato
interno un timestamp, e permette di ricavare da questo una rappresenta-
zione stringa nel formato yyyyMMdd-hhmmss dove “y” sono le quattro
cifre corrispondenti all’anno, “M” quelle corrispondenti al mese, “d” al
giorno, “h” all’ora, “m” ai minuti e “s” ai secondi.
    Per creare un JobId valido (avendo certezza della sua univocità per
un determinato file system) ed associarlo ad una richiesta si effettua la
seguente procedura:

   • si acquisisce il lock ;

   • si crea a partire da              data   e   ora   correnti   la   stringa
     yyyyMMdd-hhmmss;

   • si usa la stringa come nome file, considerando che l’estensione per
     una richiesta dev’essere .IN;
24                                                                          3. SyncUtils

            • se tale nome file esiste già, si incrementa di uno il numero indi-
              viduato graficamente da yyyyMMddhhmmss e si torna al punto
              precedente (senza preoccuparsi del fatto che il numero corrisponda
              ancora ad una data-ora valida; es: 800419170261 non corrisponde
              ad una data-ora valida, ma è comunque valido come base per creare
              un JobId);

            • si crea il file;

            • si scrive una richiesta valida nel file;

            • si rilascia il lock.

     Una risposta ad una richiesta ha il suo stesso nome file ma con estensione
     .OUT; i file di richiesta e di risposta, contengono dati in formato che
     vedremo in seguito (vedi 3.3.6 nella pagina 28).
         Spesso una risposta fornisce anche un certo quantitativo di dati—
     nel nostro caso, ad esempio le immagini catturate: formato e ubicazione
     di questi dati sono indipendenti dal sistema di comunicazione, e deter-
     minati dai singoli plug in che gestiscono l’archiviazione (vedi 5.2 nella
     pagina 76), ma vengono comunque specificati in apposite sezioni nel file
     .OUT.

     3.3.4        Protocollo
     Di seguito vengono riportate in pseudo codice alcune delle procedure che
     costituiscono il protocollo di comunicazione3 . Le procedure con prefisso
     GEC sono eseguite su iniziativa di GEC sulla macchina ove questo è in
     esecuzione, mentre quelle con prefisso SCAN si riferiscono al software
     di scansione GEC_Scan. FS sta per file system. L’indice i riferisce il
     prefisso al file system i-esimo. “Lavoro” o “Job” è il termine generico per
     indicare una richiesta, solitamente coincidente con la richiesta di inizio
     sessione di acquisizione.
        3
          Protocollo studiato dal prof. Alberto Bartoli con l’aiuto della documentazione
     prodotta dall’ing. Giorgio Davanzo; implementazione pratica in C#, sostituzione
     dell’active poll con sistemi di notifica e cura di dettagli tecnici pratici a cura di
     Giancarlo Todone.
Dettagli implementativi e tecnologie                                       25

Algorithm 3.1 Lock-CleanUp: Da eseguire all’avvio di GEC_Scan.
 1: if EXISTS(lockfile-i) then
 2:    TIMEOUT = 10sec
 3:    BeginWait = now()
 4:    while now()  BeginWait + TIMEOUT do
 5:      if NOT EXISTS(lockfile-i) then
 6:         break;
 7:      end if
 8:    end while
 9:    DELETE lockfile-i
10: end if




Algorithm 3.2 GEC-RequestJob: Da eseguire per richiedere un lavoro.
 1: GET lock-i
 2: GET NEW JobId-i
 3: RELEASE lock-i




Algorithm 3.3 GEC-Abort: Da eseguire per annullare una richiesta di
lavoro pendente su iniziativa di GEC, dato il suo JobId.
  1: GET lock-i
  2: DELETE request-file (filename = JobId.IN) in FS-i
  3: RELEASE lock-i




Algorithm 3.4 SCAN-CleanUp: Da eseguire all’avvio del programma
di scansione; FS-i viene riportato nello stato iniziale. Per semplicità,
non si cerca di recuperare eventuali lavori effettuati nella incarnazione
precedente ma non completati.
 1: EXEC Lock-CleanUp
 2: GET lock-i
 3: DELETE ALL response, data, request files (in quest’ordine)
 4: RELEASE lock-i
26                                                                   3. SyncUtils

     Algorithm 3.5 SCAN-Abort: Da eseguire per annullare (su iniziativa
     del software di acquisizione) una richiesta di lavoro pendente, dato il suo
     JobId.
      1: GET lock-i
      2: GENERATE EMPTY response-file (name = JobId.OUT) in FS-i
      3: RELEASE lock-i



     Algorithm 3.6 SCAN-CompleteJob Da usarsi per segnalare il
     completamento (andato a buon fine o meno) di una richiesta di lavoro.
      1: GET lock-i
      2: if EXISTS(Input) then
      3:    CREATE data-files in FS-i
      4:    CREATE Output-file in FS-i
      5: else
      6:    DISMISS data
      7: end if
      8: RELEASE lock-i


        In pratica:
        • Per effettuare una richiesta, il GEC deve:

              acquisire il lock;
              calcolare un JobId valido;
              scrivere un file {JobId}.IN contenente la richiesta nel
               corretto formato;
              rilasciare il lock;
              restare in attesa che venga scritto nella stessa posizione un
               file con lo stesso nome ma estensione .OUT.

        • Per recepire la richiesta ed effettuare una risposta, il GEC_Scan
          deve:

              restare in attesa finché sul file system predefinito non viene
               creato un file con nome corrispondente ad un JobId valido
               ed estensione .IN;
Dettagli implementativi e tecnologie                                          27

         acquisire il lock;
         leggere il contenuto del file di richiesta;
         rilasciare il lock ;
         elaborare la richiesta;
         acquisire il lock ;
         scrivere il file .OUT;
         rilasciare il lock.

Come si può notare dall’ultima esemplificazione, l’elaborazione viene
fatta da GEC_Scan mentre il lock non è mantenuto, per permette-
re che altre comunicazioni avvengano mentre è in atto un processo di
archiviazione molto lungo.
    Inoltre è visibile che se GEC_Scan notasse la presenza del file di
richiesta e tentasse di leggerlo prima che il GEC abbia finito di scriverlo,
non vi riuscirebbe semplicemente perché prima dovrebbe acquisire il lock
ancora detenuto dalla controparte. Un analogo ragionamento si può fare
per il file di risposta.
    Se questo tipo di meccanismo da un lato permette una corretta evolu-
zione delle dinamiche di comunicazione, dall’altro introduce anche delle
situazioni in cui i processi comunicanti si intralciano a vicenda, spre-
cando delle risorse; per questo motivo nell’implementazione reale degli
algoritmi di comunicazione si sono previsti dei piccoli ritardi program-
mabili, impostati poi a valori dedotti in modo sperimentale. Questi non
alterano in alcun modo la logica della comunicazione, ma minimizzano i
tempi di attesa attiva di ciascuna parte.

3.3.5    Problematiche delle notifiche
Inizialmente si erano concepite ulteriori due procedure:
SCAN-CheckForRequests con la quale il software di acquisizione
    controllava l’eventuale arrivo di nuove richieste;

GEC-CheckJobCompleted che si occupava di controllare—dal lato
    di GEC—se una richiesta fatta in precedenza non fosse stata
    soddisfatta.
28                                                                           3. SyncUtils

     Le due funzioni utilizzavano la tecnica dell’active poll, interrogando di
     continuo il file system sulla presenza o meno di determinati file. Consi-
     derato che questo caricava notevolmente i file system (e in minor parte
     anche la rete, in caso di sistema acceduto da remoto) si è provveduto
     a modificare il meccanismo in modo da utilizzare strumenti chiamati
     FileSystemWatcher [9].
         Questi consistono fondamentalmente in hook 4 di sistema alle funzioni
     di base di accesso al disco, che sollevano un evento quando si presentano
     determinate condizioni, come il tentativo da parte di un programma di
     scrivere un nuovo file in una cartella.
         Purtroppo, come rilevato anche da una nutrita schiera di utenti5 ,
     il codice che implementa questa tecnica a volte ha dei comportamenti
     inattesi quando eseguito in ambiente Microsoft Windows 2003 Server.
         All’epoca della prima stesura del programma non erano disponibili
     dei work around efficaci o soluzioni pubbliche: si è stati costretti a svi-
     luppare una soluzione alternativa poi segnalata sulla pagina ufficiale di
     bug report6 .
         La soluzione consiste nel sopperire ai comportamenti inattesi con de-
     gli snapshot della cartella ove avvengono gli scambi dei file: se tutto
     funziona come da specifiche Microsoft, l’esecuzione procede normalmen-
     te e le operazioni sul file system generano le notifiche attese; se invece
     qualcosa dovesse andare male, viene richiamato un gestore d’errore con
     del codice d’emergenza che confrontando il sotto albero della cartella al
     momento dell’errore con quello stimato durante le esecuzioni corrette, lo
     aggiorna e genera le notifiche di conseguenza.

     3.3.6     Formati dei file di comunicazione
     Il formato interno dei file di comunicazione si basa su XML. Una richiesta
     tipo, contenuto di un file .IN si presenta come nel listato 3.1.
        4
           Tecnica di intercettazione e modifica al volo di dati comunicati tra funzioni di
     sistema; può essere “installato” in una catena di messaggi o in mezzo ad una serie di
     chiamate a routine [10, 13].
         5
           https://connect.microsoft.com/VisualStudio/feedback/
     ViewFeedback.aspx?FeedbackID=337917
         6
           https://connect.microsoft.com/VisualStudio/feedback/
     Workaround.aspx?FeedbackID=337917
Dettagli implementativi e tecnologie                                            29


     Listing 3.1: Esempio di XML generato da SyncUtils per effettuare una
     richiesta.
 1   Request
 2     ActionRequest xmlns:xsi=http://www.w3.org/2001/
          XMLSchema-instance xmlns:xsd=http://www.w3.org
          /2001/XMLSchema xsi:type=SaveToFileActionRequest
           ARQID=0
 3       Performer name=SaveToFileActionPerformer /
 4       RequiredFileFormatpng/RequiredFileFormat
 5       Pathc:lockpath/Path
 6     /ActionRequest
 7     AdditionalData xmlns:xsi=http://www.w3.org/2001/
          XMLSchema-instance xmlns:xsd=http://www.w3.org
          /2001/XMLSchema
 8       OwnerID64/OwnerID
 9       CustomerIDmyCustomerID/CustomerID
10     /AdditionalData
11     Timestamp2009-02-25T16:59:48.375+01:00/Timestamp
12   /Request



         Il codice XML viene generato semi automaticamente per serializza-
     zione di oggetti (vedi 3.3.7 nella pagina 32), quindi in questo frangente,
     con un nome ci si potrà riferire indistintamente al tag o alla classe che
     lo ha generato.
         In 3.2 nella pagina 16 parlando della struttura del sistema di comu-
     nicazione, è stato detto che Request e Response reali contengono solo
     tipi specializzati di ActionRequest, ActionResponse ecc. . . Nel
     listato di esempio è immediato però notare che i nomi dei tag di alcune
     entità derivabili sono dati da quelli delle loro classi base; questo fa parte
     del meccanismo di serializzazione: il nome della classe specializzata è
     contenuto in questi casi dall’attributo xsi:type. Non si fa affidamen-
     to a xsi:type per la corretta serializzazione del campo Performer
     che contiene semplicemente il nome della classe preposta a gestire la
     ActionRequest che lo contiene.
         In 3.2 nella pagina seguente si può osservare un esempio di risposta,
     contenuto nel file .OUT corrispondente ad un file .IN di richiesta.
30                                                             3. SyncUtils

     Listing 3.2: Esempio di XML generato da SyncUtils per effettuare una
     risposta.
 1   Response xmlns:xsi=http://www.w3.org/2001/XMLSchema-
        instance xmlns:xsd=http://www.w3.org/2001/XMLSchema
        
 2     Documents
 3       Document GID=0
 4          Pages
 5            Page PID=0 /
 6            Page PID=1 /
 7            Page PID=2 /
 8          /Pages
 9          ActionResponses
10            ActionResponse xsi:type=
                 SaveToFileActionResponse ARSID=0 Request=
                 0
11              Errors /
12              Pages
13                ResponsePage xsi:type=FSPage Page=0
                     Format=png FileName=fileName1 /
14                ResponsePage xsi:type=FSPage Page=1
                     Format=png FileName=fileName2 /
15                ResponsePage xsi:type=FSPage Page=2
                     Format=png FileName=fileName3 /
16              /Pages
17              Pathc:lockpath/Path
18            /ActionResponse
19          /ActionResponses
20       /Document
21     /Documents
22     Errors
23       Error IsCrytical=true EID=0
24          Test error message 2 !
25       /Error
26     /Errors
27     Timestamp2009-02-27T23:14:52.640625+01:00/Timestamp
           
28   /Response


        Si possono notare gli attributi PID, GID, EID ecc. . . che fungono
Dettagli implementativi e tecnologie                                           31

     da identificatori univoci per l’entità cui appartengono all’interno del
     loro contenitore; in figura 3.2 nella pagina 17 le frecce indicano che
     l’oggetto da cui partono conserva un identificativo dell’oggetto punta-
     to, cui si riferiscono logicamente, come una ActionResponse indica
     l’ActionRequest da cui è originata.
         Il meccanismo di distribuzione degli identificativi è tale che un
     identificativo sia univoco tra quelli degli oggetti contenuti nello stes-
     so contenitore (ad esempio: non ci sono ripetizioni tra gli id del-
     le ActionResponse in un medesimo Document, ma due id di
     ActionResponse in due Document distinti possono essere uguali
     poiché non è comunque possibile equivocare tra loro).
         Dal punto di vista dell’implementazione, ogni oggetto che può funge-
     re da contenitore per altri oggetti mantiene internamente un oggetto
     di tipo IdFactory per la generazione consistente e la distribuzio-
     ne degli identificativi; tutti gli oggetti che possono venire identificati
     per qualche motivo implementano l’interfaccia IHasId; tutti gli oggetti
     che possono fare riferimento ad un altro oggetto implementante IHasId
     implementano a loro volta l’interfaccia IIdPointer.
         È forse doveroso ribadire che normalmente per individuare precisa-
     mente un oggetto manterremmo semplicemente una managed reference
     a quest’ultimo; ma questo tipo di riferimento, nella situazione proposta
     è di difficile espressione durante la serializzazione XML.
     Listing 3.3:     Riassunto dei meccanismi di distribuzione consistente degli
     identificativi.
 1   public interface IHasId
 2   {
 3     int Id         { get; set; }
 4   }
 5
 6   public interface IIdPointer
 7   {
 8     int PointedId { get; set; }
 9     void PointTo(IHasId item);
10   }
11
12   public class IdFactory
13   {
32                                                                   3. SyncUtils

14       int _count = 0;
15       ...
16       public virtual IHasId SetID(IHasId item)
17       {
18         item.Id = _count++;
19         return item;
20       }
21       ...
22   }
23
24   public class IdFactoryT : IdFactory where T : IHasId,
         new()
25   {
26     ...
27     public override IHasId SetID(IHasId item)
28     {
29        ...
30        return base.SetID(item);
31     }
32   }




     3.3.7    Serializzazione XML

     Le tecniche di serializzazione XML in generale, e quelle utilizzate secon-
     do le usanze del framework dotNet in particolare, sono estremamente
     note in letteratura [12], ma è bene soffermarsi su certi loro aspetti per
     gli interessanti risvolti scaturiti durante lo sviluppo di alcune parti del
     software di interscambio dati.
         La serializzabilità di un tipo in ambito dotNet è cosa diversa dalla
     sua serializzabilità XML: ai nostri scopi tutti i tipi primitivi sono XM-
     L-serializzabili e in aggiunta—grazie all’uso della reflection—anche molti
     tipi complessi non espressamente pensati in ottica di serializzazione XML
     sono comunque XML-serializzabili.
         Nel package System.Xml.Serialization si trovano gli strumen-
     ti per effettuare serializzazione e deserializzazione di oggetti secondo due
     modalità che potremmo definire “esplicita” ed “implicita”:
Dettagli implementativi e tecnologie                                            33

   • nella modalità esplicita, gli oggetti candidati alla serializ-
     zazione devono implementare esplicitamente l’interfaccia
     IXmlSerializable, che prescrive l’implementazione di tre
     metodi per la serializzazione, la deserializzazione e la definizione
     di uno schema;

   • nella modalità implicita, il framework ispeziona tramite reflection
     le classi degli oggetti da serializzare e considerando solo campi e
     proprietà pubbliche genera al volo un oggetto serializzatore adatto.

Nella maggior parte dei casi la modalità implicita è più che sufficiente,
se si considera che è possibile istruire in certa misura il serializzatore su
alcuni dettagli come nomi dei tag, tipo dei nodi ecc. . . mentre con la mo-
dalità esplicita—che pur permette di risolvere problemi più complessi—è
necessario scrivere molto codice, introducendo problemi di leggibilità e
manutenibilità del sorgente.
    Solitamente si fa uso di una sola tecnica per volta, ma accade anche
che le due vengano combinate, ad esempio quando si serializza un ogget-
to implicitamente serializzabile che però serba in alcuni dei suoi campi
oggetti esplicitamente serializzabili; ciò che accade è esemplificato nel
seguente algoritmo:

   • se l’oggetto da serializzare è un tipo primitivo, allora è ben
     conosciuto: si richiama una procedura standard per la sua
     serializzazione e si termina la procedura;

   • se l’oggetto da serializzare implementa IXmlSerializable, al-
     lora si chiama il metodo IXmlSerializable.WriteXml() e si
     termina la procedura;

   • se l’oggetto non appartiene alle precedenti due categorie ma è
     comunque XML-serializzabile, allora si itera l’algoritmo su ogni
     campo.

Analogamente per la deserializzazione. È ovvio che nel caso di un og-
getto complesso con campi complessi tutti implicitamente serializzabili,
34                                                                    3. SyncUtils

     l’algoritmo itera finché non è stato analizzato l’intero albero7 ; è altresì
     visibile che qualora venga incontrato un oggetto IXmlSerializable,
     i suoi metodi WriteXml/ReadXml si occuperanno della sua intera
     serializzazione/deserializzazione, fermando la ricorsione dell’algoritmo
     summenzionato.
         Nello sviluppo del progetto si sono affrontati dei casi in cui ciò rappre-
     senta un problema: gli oggetti che gestiscono richieste e risposte utilizza-
     no meccanismi di serializzazione complessi, poichè gli oggetti scambiati
     durante una comunicazione non sempre sono ben conosciuti da entram-
     bi gli interlocutori; quindi questi oggetti implementano esplicitamente i
     meccanismi con IXmlSerializable. Nonostante ciò, per semplificare
     lo sviluppo futuro di ulteriori oggetti contenuti in richieste e risposte, si
     desidera che tali oggetti non debbano necessariamente implementare essi
     stessi le loro procedure di serializzazione in maniera esplicita.
         È stato quindi adottato un espediente: nel codice di serializzazione
     personalizzato di Request e Response, ogni loro campo viene serializ-
     zato/deserializzato istanziando di volta in volta un nuovo serializzatore,
     che inizia nuovamente per ogni loro campo l’algoritmo descritto in pre-
     cedenza; i flussi di codice XML prodotto nelle singole serializzazioni di
     questi oggetti vengono poi fusi col flusso principale dell’oggetto padre a
     posteriori (analogamente, durante la deserializzazione avviene l’estrazio-
     ne di porzioni di XML dal flusso principale che generano oggetti reinseriti
     negli appositi campi dell’oggetto padre a posteriori).
         Tutti i tipi conosciuti da un’esecuzione della libreria di comunicazio-
     ne, vengono mantenuti in un registro statico e pubblico, accessibile da
     ogni serializzatore; l’insieme di queste tecniche permette la serializzazio-
     ne/deserializzazione di tipi non noti a compile time, e la corretta gestio-
     ne della loro ereditarietà, mantenendo comunque semplice lo sviluppo di
     funzionalità aggiuntive.



       7
          Per semplicità e compattezza vengono taciute le problematiche di visita
     come ad esempio riferimenti incrociati e similari, pur esistenti ed affrontati
     dall’implementazione reale dell’algoritmo.
Dettagli implementativi e tecnologie                                           35

    3.3.8    COM

    COM è acronimo di Component Object Model, un’architettura che
    permette l’interfaccia di componenti software di varie parti senza
    che queste siano ricompilate in un progetto, al fine di promuoverne
    l’interoperabilità.
        Esso non è dipendente da un particolare linguaggio—ogni linguaggio
    che sia in grado di chiamare funzioni tramite puntatori può accedere alle
    sue funzionalità—e si basa sui concetti di componente ed interfaccia.
        Tali componenti ed interfacce sono conservati in delle DLL struttu-
    rate secondo un metodo prestabilito, e riferiti durante il loro utilizzo
    secondo un peculiare meccanismo di doppia indirezione: si mantiene il
    riferimento ad un componente tramite l’indice di una tabella—chiamata
    “vtable”—che a sua volta conserva un’indirizzo reale alla struttura dati
    desiderata: in questo modo le vtable possono essere condivise da più
    istanze di un oggetto riducendo l’utilizzo di memoria.
        Un componente COM somiglia in struttura a ciò che è una classe per
    la programmazione ad oggetti.
        In una gerarchia di classi, in qualsiasi contesto di programmazione
    esiste un ancestor, ovvero il modello di un’entità di base con un insieme
    minimo di caratteristiche e funzionalità di base che qualsiasi altro oggetto
    deve possedere; in ambito COM, si dice che tale oggetto implementa
    almeno l’interfaccia IUnknown.


              Listing 3.4: Interfaccia IUnknown come appare in C++.
1   class IUnknown
2   {
3     virtual   HRESULT QueryInterface(IID iid, void**
         ppvObj) = 0;
4     virtual   ULONG   AddRef() = 0;
5     virtual   ULONG   Release() = 0;
6   }



        Questa interfaccia prescrive l’implementazione di tre metodi:
36                                                                            3. SyncUtils

     QueryInterface permette di interrogare il componente imple-
         mentante circa il supporto o meno di un’altra specifica
         interfaccia;
     AddRef viene chiamato per aumentare il conteggio interno degli uti-
         lizzatori (insieme a Release implementa un primitivo Garbage
         Collector);
     Release decrementa il conteggio interno degli utilizzatori e libera la
         memoria quando questo raggiunge lo 0.
     Un componente COM può supportare un numero qualsiasi di interfacce
     a partire da un minimo di una (IUnknown); le interfacce possono essere
     prese dal programmatore tra alcune predefinite, derivate da esse o create
     ex novo.
          Per permettere la risoluzione degli identificativi univoci che contrad-
     distinguono componenti ed interfacce COM a partire da nomi, tali ele-
     menti devono necessariamente essere registrati, cioè iscritti ad elenchi
     siti in determinate aree del registro di configurazione di Windows8 .
          La tecnologia dotNet, con il suo proprio concetto di riusabilità sta
     soppiantando di fatto il Component Object Model, nonostante que-
     st’ultimo sia stato forse una delle tecnologie più usate dal 1993 ad
     oggi9 .
          Il passaggio da una tecnologia all’altra viene reso più facile dalla
     prevista possibilità di interazione tra le due: questa opportunità si espli-
     cita con il Runtime Callable Wrapper (RCW) necessario per eseguire
     una chiamata a un server COM da un client dotNet, e il COM Callable
     Wrapper (CCW) per eseguire viceversa una chiamata a un server dotNet
     da client COM10 . Come suggerito dai nomi, queste due entità sono del
        8
           In realtà COM fu portato anche su sistemi operativi diversi da Windows e addi-
     rittura su macchine diverse dai PC compatibili; in questi sistemi la risoluzione degli
     identificativi avviene in modo analogo ma implementativamente diverso; l’uso più
     esteso di COM rimane quello su piattaforme Windows, dal 3.x fino alle più moderne
     XP, Vista e Seven.
         9
           Nata nel 1993, questa tecnologia è stata menzionata con enfasi da Microsoft solo
     a partire dal 1997.
        10
           Chiamiamo “client COM” una porzione di un programma in grado di utilizzare un
     servizio esposto da un oggetto COM; chiamiamo altresì “server COM” il componente
     che espone tale funzionalità.
Dettagli implementativi e tecnologie                                                        37

   codice di contorno aggiunto automaticamente ai componenti di una del-
   le due metodologie di sviluppo per essere interpretati ed utilizzati anche
   dalla controparte tecnologica.


                  



                 Component                RCW                       Consumer
Unmanaged




                                                                                     Managed
                 Consumer                 CCW                          Class



   Figura 3.3: Schema di funzionamento di RCW e CCW; nella prima riga un
   componente dotNet richiama funzionalità da un provider COM; nella seconda,
   del codice capace di richiamare funzionalità COM chiama codice dotNet tramite
   il CCW.

       Nonostante ogni CCW sia generato automaticamente dal runtime
   dotNet, le classi da esporre come componenti COM devono venire ade-
   guatamente preparate; l’ambiente integrato di sviluppo Visual Studio
   2008 offre degli automatismi per assolvere a questo compito, ma resta
   preoccupazione del programmatore decorare le classi dotNet con attributi
   atti ad istruire il runtime nella creazione dei CCW ad esse dedicati.
       Fondamentali ComVisible che abilita il processo di wrapping e
   ProgId che assegna il nome al componente. Eventuali altri attributi
   da applicare possono essere Guid, che specifica un identificativo univoco
   altrimenti assegnato automaticamente e DispId che specifica in maniera
   esplicita l’ordine in cui i metodi devono comparire in un’interfaccia11 .
            11
       Per la corretta compilazione del codice, se almeno un metodo di una classe è stato
   decorato con DispId, allora lo devono essere tutti all’interno della stessa classe.
38                                                                 3. SyncUtils


     Listing 3.5: Esempio della decorazione minima di un componente da esporre
     tramite COM.
 1   [InterfaceTypeAttribute(ComInterfaceType.
        InterfaceIsIDispatch)]
 2   public interface _JobId
 3   {
 4     string ToString();
 5     bool Equals(object value);
 6     void Increment();
 7     JobId Clone();
 8   }
 9
10   [ClassInterface(ClassInterfaceType.None)]
11   [ProgId(SyncUtils.JobID)]
12   [ComVisible(true)]
13   public class JobId : _JobId
14   {
15     ...
16   }



         Una particolare menzione meritano la gestione degli eventi e quella
     degli errori; mentre i secondi sono propagati automaticamente dal siste-
     ma semplicemente assegnando un codice d’errore ad ogni eccezione non
     gestita, l’utilizzo dei primi richiede del codice aggiuntivo.
         Proprietà di un’interfaccia C# come potrebbe essere
 1   event JobCompletedDelegate OnJobCompleted;

        vengono viste in realtà dai client COM come una coppia di metodi
     per l’aggiunta e la rimozione di gestori d’evento
 1   AddJobCompletedDelegate();
 2   RemoveJobCompleteDelegate():

         ma per permettere ad un COM client di venire notificato da un
     componente, è necessario assegnare esplicitamente a quest’ultimo an-
     che un’interfaccia in cui si specifica il metodo da chiamare al verificarsi
     dell’evento; del tipo
Dettagli implementativi e tecnologie                                            39


1   [InterfaceTypeAttribute(ComInterfaceType.
       InterfaceIsIDispatch)]
2   public interface UserEvents
3   {
4     void OnJobCompleted(JobId job, Response response);
5     ...
6   }

        Dal punto di vista dell’utilizzo con Visual Basic 6, l’utilizzo di un
    oggetto COM richiede un file che ne specifichi le funzioni presenti: tale
    file—di estensione .tlb—viene chiamato “type library”, ed è generato
    automaticamente all’atto della registrazione di un componente. Impor-
    tando la type library, è poi possibile cominciare ad usare qualsiasi dei tipi
    ivi definiti, curandosi di dichiarare con la clausola WithEvents quelli
    dei quali si voglia usare la capacità di sollevare eventi.
        Nel progetto del sistema di archiviazione proposto, le classi ad essere
    predisposte per l’utilizzo come componenti COM sono essenzialmente
    quelle riguardanti la libreria della comunicazione, e in maggior dettaglio
    quelle che permettono a GEC di richiedere un servizio a GEC_Scan:

    ClientSideFileSync;

    Request;

    Response;

    ActionRequest;

    ActionResponse;

    Document;

    DocInfo;

    Page;

    ResponsePage;

    Error
40                                                                     3. SyncUtils

     e classi da queste derivate. Lo sviluppatore che intendesse creare ulteriori
     plug in aggiuntivi dovrà curarsi che le sue classi siano accessibili a client
     COM per permetterne l’uso da parte di GEC.


     3.4     Installazione e preparazione dell’ambiente di
             esecuzione
     Il software in tutte le sue parti è in fase di test, e non viene quindi ancora
     distribuito al di fuori del contesto di sviluppo. Per questo motivo non è
     fornito di un programma di installazione e di istruzioni user friendly, ma
     solo di note tecniche, la maggior parte delle quali messe insieme durante
     la soluzione di reali problematiche di set up, o collezione di alcuni brani
     rilevanti dalla documentazione e dai commenti al codice sorgente.
          I tre tipi di software prodotti eseguono in due ambienti eventualmente
     coincidenti:
        • il calcolatore che esegue GEC
        • il personal computer dove viene eseguito il software di acquisizione
          e i suoi plug in
     Per quanto riguarda il lato controllore, devono essere distribuiti assieme a
     GEC tutti gli assembly inerenti la libreria di comunicazione. Le seguenti
     DLL contenenti codice dotNet racchiuso in oggetti COM vanno copiate
     in una cartella apposita su un volume non rimovibile del PC e registrate
     nell’ordine:
        • CommonUtils.dll
        • SyncUtils.dll
        • SerializationSetupHelper.dll
        • BasicPlugins.dll
        • ClientSync.dll
     che in buona parte dipendono da (e quindi richiedono anche)
     SimpleLogger.dll
        Per la registrazione, è possibile utilizzare il comando
Installazione e preparazione dell’ambiente di esecuzione                        41


1   RegAsm.exe nomeDll

        residente nella cartella
    %WINDIR%Microsoft.NETFrameworkv2.X
    Come si può notare, la cartella è parte integrante del framework dotNet
    2.x (dove “x” sta per qualsiasi numero), palesando che l’installazione del
    runtime dotNet 2.0 o superiore è un prerequisito.
        Da osservare anche il fatto che gli assembly preparati per essere utiliz-
    zati come oggetti COM hanno bisogno di un trattamento particolare, uti-
    lizzando per la registrazione l’apposito regasm.exe al posto dell’usuale
    regsvr32.exe
        Molte di queste librerie sono utilizzate anche dal lato del software
    di acquisizione: anche se questo dovesse essere installato sulla stessa
    macchina di GEC, le librerie non possono essere condivise. Andranno
    quindi replicate nella cartella dedicata solo al programma di scansione.
42   3. SyncUtils
Capitolo       4
GEC_Scan

4.1     Requisiti e progetto dell’interfaccia utente
Il software di acquisizione GEC_Scan dev’essere funzionalmente inte-
grato con GEC. L’utente, una volta installato il sistema, non deve avere
coscienza che GEC_Scan è un programma diverso da GEC ma deve
essere portato a considerarlo come una sua estensione: per ottenere que-
sto risultato GEC_Scan deve essere eseguito all’avvio della macchina su
cui è installato e rimanere nascosto finchè non si presenti un determinato
evento (come l’arrivo di una comunicazione da GEC) nel qual caso dovrà
essere mostrata una schermata adatta a gestire l’evento.
    In questo modo, la finestra di GEC_Scan si comporterà come se fos-
se un form dell’applicazione principale, lasciando trasparente all’utente
tutta la gestione delle comunicazioni tra un software e l’altro.
    GEC_Scan deve utilizzare SyncUtils o essere compatibile con il suo
metodo di comunicazione a file system condiviso: deve quindi avere ac-
cesso in lettura e scrittura alla porzione del file system sul suo elaboratore
che viene acceduta da GEC tramite SyncUtils.
    GEC_Scan deve poter accettare da GEC un numero qualsiasi di
richieste di inizio sessione di acquisizione a prescindere dal suo stato di
occupazione: se arrivano ulteriori richieste mentre l’utente sta operando
il programma per soddisfarne una, tali richieste vanno inserite in una

                                       43
44                                                                 4. GEC_Scan

     coda di tipo First In First Out, e vanno presentate all’utente in ordine
     una ogni volta che la precedente sia terminata.
         L’utente deve essere posto in grado di valutare la lunghezza della
     coda e di annullare una o tutte le richieste senza interrompere il suo
     lavoro corrente. A tale scopo deve essere presente un form separato da
     quello principale che permette di osservare in tempo reale l’occupazione
     della coda.
         GEC_Scan deve poter comunicare con il maggior numero possibile di
     periferiche di acquisizione come scanner, fotocamere e basi di dati; tale
     connettività deve però essere assolutamente trasparente, cioè: il com-
     portamento e l’apparenza grafica del programma devono essere sempre
     uguali e garantire un’esperienza di utilizzo consistente qualsiasi sia la
     sorgente di dati scelta.
         Le immagini acquisite singolarmente o in gruppi, devono essere
     presentate tramite piccole anteprime che permettano quantomeno di
     identificare in linea di massima ogni documento.
         Non ci deve essere un limite—se non quello fisico della macchina
     di esecuzione—al numero di immagini acquisibili e gestibili: allo sco-
     po di facilitare la gestione delle immagini (operazioni di ispezione, se-
     lezione, riordino, rotazione) il programma deve essere provvisto di un
     visualizzatore integrato, che permetta di ingrandire le piccole anteprime
     e presentare le immagini a più alta risoluzione a vari livelli di zoom.


     4.1.1    Interfaccia grafica e usabilità

     Normalmente il programma di acquisizione documenti viene eseguito al-
     l’avvio del sistema dell’utente, ma la maggior parte delle sue funziona-
     lità è preclusa finché GEC—a seguito di un’operazione dell’utente—non
     inizia una sessione; per l’utente è tuttavia sempre possibile accedere tra-
     mite icona nella barra dell’orologio ad un menu di opzioni che permette
     di impostare:


        • il dispositivo da utilizzare tra una lista di scanner, fotocamere ed
          altre sorgenti TWAIN disponibili sul sistema;
Requisiti e progetto dell’interfaccia utente                                  45




       Figura 4.1: Finestra di opzioni del programma di acquisizione.


    • la risoluzione (impostata alla prima esecuzione sulla risoluzio-
      ne disponibile più vicina—possibilmente per eccesso—a 300 dpi,
      risoluzione richiesta dalla maggior parte dei software OCR);

    • modalità di colore (impostata alla prima esecuzione sulla modalità
      più semplice che si avvicini a RGB);

    • orientamento pagine (impostato alla prima esecuzione a 0º);

    • utilizzo dell’alimentatore automatico fogli (se disponibile, imposta-
      to a vero alla prima esecuzione);

    • utilizzo della scansione automatica fronte e retro (inizialmente
      falso);

    • utilizzo dell’eliminazione automatica pagine vuote (inizialmente
      falso);

    • utilizzo della rotazione automatica pagine (inizialmente falso);
46                                                                    4. GEC_Scan

        • utilizzo del rilevamento automatico delle dimensioni di una pagina
          (se disponibile inizialmente vero);

     Ogni controllo di impostazione risulta operabile se pertinente, e non
     presente o disegnato in grigio se non disponibile o non applicabile.
         Ogni impostazione si riferisce al dispositivo correntemente seleziona-
     to: scegliere un’altra periferica causerà l’adattamento dei parametri alle
     capacità della nuova sorgente scelta.
         Alla chiusura della finestra delle preferenze, queste vengono rese
     ufficiali e salvate su disco.




          Figura 4.2: Schermata principale del programma di acquisizione.


         Quando l’utente effettua in GEC un’operazione che causa l’inizio di
     una sessione di acquisizione, la schermata principale del programma di
     scansione compare in primo piano.
         Tramite il tasto “Acquisisci” si inizia la scansione dalla periferica sele-
     zionata di una o più pagine dipendentemente dalle preferenze impostate:
     eventuali operazioni lunghe comporteranno la comparsa di un indicato-
     re di avanzamento che consente anche di interrompere le operazioni in
     corso.
         Ad esempio, un’operazione di acquisizione molto lunga potrebbe pre-
     sentarsi nel caso in cui si sia scelto di scansionare molti documenti con
Requisiti e progetto dell’interfaccia utente                                      47

un trascinatore automatico, oppure nel caso si sia scelto di utilizzare una
risoluzione molto alta.
    Una volta raccolte delle immagini, queste compaiono sotto forma di
icone sullo sfondo grigio della finestra principale: passandoci sopra con
il puntatore esse si ingrandiscono per permettere di comprendere meglio
di che pagina si tratta e per consentire all’operatore di capire qual è il
foglio correntemente puntato. Aumentando le dimensioni della finestra,
aumentano anche quelle delle icone delle pagine.
    Facendo doppio click su un’immagine, questa viene mostrata in una
finestra di anteprima, nella quale è possibile effettuare zoom (operando
la rotella del mouse o i tasti + e -) sulle sue varie parti a fini di ispezione.
    Tenendo premuto il tasto sinistro del mouse e trascinando, l’imma-
gine puntata viene rimossa dalla sua sede per consentire di posizionarla
in altra locazione: rilasciando il tasto sinistro, essa verrà inserita su-
bito prima dell’immagine correntemente sotto il puntatore (locazione
evidenziata da una barra nera sfumata).
    Una barra di posizionamento compare al di sotto delle immagi-
ni quando queste sono troppe per essere contenute in una sola scher-
mata: sia quando si scorrono semplicemente le immagini, sia duran-
te le operazioni di trascinamento, avvicinandosi al bordo sinistro o de-
stro il programma effettua automaticamente una carrellata—tanto più
velocemente quanto più si è vicini al bordo.
    Tenendo premuto il tasto sinistro del mouse sull’area recante la di-
citura “inserisci separatore” e trascinando, viene creato un elemento se-
paratore (delle sembianze di una barra nera verticale) che è possibile
rilasciare tra due immagini secondo le modalità già viste: anche una
volta rilasciato un separatore, è sempre possibile riprenderlo e spostarlo
come una immagine qualsiasi.
    Verrà considerato “documento” o “gruppo” l’insieme delle pagine con-
tenute fra due separatori (o tra un separatore e l’inizio/fine della lista):
il programma può essere forzato da GEC a richiedere un numero mini-
mo e un numero massimo di gruppi di pagine: è possibile sapere quali
sono i vincoli lasciando il puntatore sull’area di inserzione separatore e
aspettando la comparsa di un fumetto contenente tali informazioni.
    Facendo click destro su un’immagine o un separatore, appare un
menu contestuale con diverse opzioni auto esplicative:
48                                                                    4. GEC_Scan

        • ruota in senso orario;

        • ruota in senso antiorario;

        • elimina.

     La pressione del tasto “cancella immagini” causa la cancellazione di tutte
     le immagini acquisite.
          Una volta catturate, riordinate e divise le pagine è possibile annullare
     tutto il lavoro o proseguire con l’archiviazione dei dati; la differenza tra
     “cancella immagini” e “scarta” consiste proprio nel fatto che il primo co-
     mando lascia la finestra aperta per effettuare ulteriori operazioni, mentre
     il secondo chiude e manda contestualmente a GEC un messaggio di er-
     rore comunicandogli che non è stato possibile completare correttamente
     il lavoro per annullamento da parte dell’utente.
          Se nel frattempo erano pervenute altre richieste di inizio sessione
     (es: l’utente ha effettuato altre operazioni su GEC che hanno originato
     altre richieste), il programma lo palesa restando in attesa di istruzioni,
     altrimenti torna nel suo stato quiescente. In ogni momento è possibile
     controllare e gestire lo stato della coda di richieste tramite l’apposita
     finestra, richiamabile dalla tray icon.




       Figura 4.3: Finestra di gestione della coda in caso di richieste multiple.
Composizione di GEC_Scan                                                    49

    Infine, chiudendo semplicemente la finestra principale (con la classi-
ca “x” in alto a destra) o tramite il tasto “Nascondi” senza scegliere di
memorizzare o scartare il materiale raccolto, si sospende la sessione di
lavoro nascondendo la finestra, recuperabile (senza perdere alcun dato)
tramite icona nella barra dell’orologio.


4.2             Composizione di GEC_Scan




                                                  Plug in
                                                              Servizi
                            Plug in manager
                                                              esterni
                                                  Plug in
      codice principale




                               SyncUtils        File System   GEC




                             dotNetTwain         TWAIN        Periferiche


                            VisualSlideShow
                                                 WinForms
                            e     interfaccia                 Utente
                                                 GDI
                            grafica

                          GEC_Scan



Figura 4.4: Composizione di GEC_Scan e sue relazioni con tecnologie ed
altre parti del progetto.

   In figura 4.4, si può osservare l’architettura di GEC_Scan e le sue
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone
Tesi Todone

Contenu connexe

Tendances

Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...
Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...
Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...
Ce.Se.N.A. Security
 
Analisi e sviluppo di uno strumento per l'automazione della verifica di confo...
Analisi e sviluppo di uno strumento per l'automazione della verifica di confo...Analisi e sviluppo di uno strumento per l'automazione della verifica di confo...
Analisi e sviluppo di uno strumento per l'automazione della verifica di confo...
Grogdunn
 
a1dddf507ce838f51f5349d2b2c25241
a1dddf507ce838f51f5349d2b2c25241a1dddf507ce838f51f5349d2b2c25241
a1dddf507ce838f51f5349d2b2c25241
Nunzio Meli
 
NunzioMeliTesi-up1
NunzioMeliTesi-up1NunzioMeliTesi-up1
NunzioMeliTesi-up1
Nunzio Meli
 
Rilevamento di facce in flussi video per l'ausilio ai non vedenti - Tesi
Rilevamento di facce in flussi video per l'ausilio ai non vedenti - TesiRilevamento di facce in flussi video per l'ausilio ai non vedenti - Tesi
Rilevamento di facce in flussi video per l'ausilio ai non vedenti - Tesi
temp temp
 
Rilevamento di attacchi di rete tramite protocolli di monitoraggio per route...
 Rilevamento di attacchi di rete tramite protocolli di monitoraggio per route... Rilevamento di attacchi di rete tramite protocolli di monitoraggio per route...
Rilevamento di attacchi di rete tramite protocolli di monitoraggio per route...
Ce.Se.N.A. Security
 
Progetto e Realizzazione di un Software per la Rilevazione Automatica di Codi...
Progetto e Realizzazione di un Software per la Rilevazione Automatica di Codi...Progetto e Realizzazione di un Software per la Rilevazione Automatica di Codi...
Progetto e Realizzazione di un Software per la Rilevazione Automatica di Codi...
danielenicassio
 

Tendances (18)

Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...
Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...
Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...
 
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - TesiAnalisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Tesi
 
LEARNING OBJECT MODELLO DI RIFERIMENTO SCORM E AUTHORING APPLICATIONS
LEARNING OBJECT MODELLO DI RIFERIMENTO SCORM E AUTHORING APPLICATIONSLEARNING OBJECT MODELLO DI RIFERIMENTO SCORM E AUTHORING APPLICATIONS
LEARNING OBJECT MODELLO DI RIFERIMENTO SCORM E AUTHORING APPLICATIONS
 
Thesis marco de_marco
Thesis marco de_marcoThesis marco de_marco
Thesis marco de_marco
 
Analisi e sviluppo di uno strumento per l'automazione della verifica di confo...
Analisi e sviluppo di uno strumento per l'automazione della verifica di confo...Analisi e sviluppo di uno strumento per l'automazione della verifica di confo...
Analisi e sviluppo di uno strumento per l'automazione della verifica di confo...
 
a1dddf507ce838f51f5349d2b2c25241
a1dddf507ce838f51f5349d2b2c25241a1dddf507ce838f51f5349d2b2c25241
a1dddf507ce838f51f5349d2b2c25241
 
Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...
Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...
Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...
 
Algoritmo di Dijkstra
Algoritmo di DijkstraAlgoritmo di Dijkstra
Algoritmo di Dijkstra
 
Profilazione utente in ambienti virtualizzati
Profilazione utente in ambienti virtualizzatiProfilazione utente in ambienti virtualizzati
Profilazione utente in ambienti virtualizzati
 
TesiEtta
TesiEttaTesiEtta
TesiEtta
 
NunzioMeliTesi-up1
NunzioMeliTesi-up1NunzioMeliTesi-up1
NunzioMeliTesi-up1
 
Rilevamento di facce in flussi video per l'ausilio ai non vedenti - Tesi
Rilevamento di facce in flussi video per l'ausilio ai non vedenti - TesiRilevamento di facce in flussi video per l'ausilio ai non vedenti - Tesi
Rilevamento di facce in flussi video per l'ausilio ai non vedenti - Tesi
 
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
 
Digitalizzazione di un processo industriale
Digitalizzazione di un processo industrialeDigitalizzazione di un processo industriale
Digitalizzazione di un processo industriale
 
Rilevamento di attacchi di rete tramite protocolli di monitoraggio per route...
 Rilevamento di attacchi di rete tramite protocolli di monitoraggio per route... Rilevamento di attacchi di rete tramite protocolli di monitoraggio per route...
Rilevamento di attacchi di rete tramite protocolli di monitoraggio per route...
 
repairpdf_Oy51nCFX
repairpdf_Oy51nCFXrepairpdf_Oy51nCFX
repairpdf_Oy51nCFX
 
Progetto e Realizzazione di un Software per la Rilevazione Automatica di Codi...
Progetto e Realizzazione di un Software per la Rilevazione Automatica di Codi...Progetto e Realizzazione di un Software per la Rilevazione Automatica di Codi...
Progetto e Realizzazione di un Software per la Rilevazione Automatica di Codi...
 
Schema di watermarking robusto per un bitstream jpeg cifrato
Schema di watermarking robusto per un bitstream jpeg cifratoSchema di watermarking robusto per un bitstream jpeg cifrato
Schema di watermarking robusto per un bitstream jpeg cifrato
 

En vedette (10)

I Romani Ooookk
I Romani OoookkI Romani Ooookk
I Romani Ooookk
 
Creative Urban Renewal Knowledge Event (CURE)
Creative Urban Renewal Knowledge Event (CURE)Creative Urban Renewal Knowledge Event (CURE)
Creative Urban Renewal Knowledge Event (CURE)
 
2013 hku cultuurfabriek1 sessie 2
2013 hku cultuurfabriek1 sessie 22013 hku cultuurfabriek1 sessie 2
2013 hku cultuurfabriek1 sessie 2
 
2013 hku intr eco 4
2013 hku intr eco 42013 hku intr eco 4
2013 hku intr eco 4
 
091122 Determinants Creative Industries
091122 Determinants Creative Industries091122 Determinants Creative Industries
091122 Determinants Creative Industries
 
2013 hku cultuurfabriek1
2013 hku cultuurfabriek12013 hku cultuurfabriek1
2013 hku cultuurfabriek1
 
I Romani Ok! Modificato X Sito
I Romani Ok! Modificato X SitoI Romani Ok! Modificato X Sito
I Romani Ok! Modificato X Sito
 
Tesi-Todone
Tesi-TodoneTesi-Todone
Tesi-Todone
 
I Romani Ooookk
I Romani OoookkI Romani Ooookk
I Romani Ooookk
 
I Romani Ooookk
I Romani OoookkI Romani Ooookk
I Romani Ooookk
 

Similaire à Tesi Todone

Generazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptxGenerazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptx
GiacomoZorzin
 
SESAMO (application login automator): evoluzioni applicative e considerazioni...
SESAMO (application login automator): evoluzioni applicative e considerazioni...SESAMO (application login automator): evoluzioni applicative e considerazioni...
SESAMO (application login automator): evoluzioni applicative e considerazioni...
AndrijaCiric1
 
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
danieledegan
 
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Raffaele Bernardi
 
Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...
Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...
Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...
artemedea
 
Cloud Computing e Modelli di Business
Cloud Computing e Modelli di Business Cloud Computing e Modelli di Business
Cloud Computing e Modelli di Business
Andrea Cavicchini
 
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
daniel_zotti
 
Implementazione in Java di plugin Maven per algoritmi di addestramento per re...
Implementazione in Java di plugin Maven per algoritmi di addestramento per re...Implementazione in Java di plugin Maven per algoritmi di addestramento per re...
Implementazione in Java di plugin Maven per algoritmi di addestramento per re...
Francesco Komauli
 

Similaire à Tesi Todone (20)

Progettazione e sviluppo di un software applicativo su un single board computer
Progettazione e sviluppo di un software applicativo su un single board computerProgettazione e sviluppo di un software applicativo su un single board computer
Progettazione e sviluppo di un software applicativo su un single board computer
 
Prototipazione di una piattaforma di controllo degli accessi fisici cross ven...
Prototipazione di una piattaforma di controllo degli accessi fisici cross ven...Prototipazione di una piattaforma di controllo degli accessi fisici cross ven...
Prototipazione di una piattaforma di controllo degli accessi fisici cross ven...
 
Generazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptxGenerazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptx
 
Cecutti Federico - Progetto e sviluppo di un'applicazione domotica per telefo...
Cecutti Federico - Progetto e sviluppo di un'applicazione domotica per telefo...Cecutti Federico - Progetto e sviluppo di un'applicazione domotica per telefo...
Cecutti Federico - Progetto e sviluppo di un'applicazione domotica per telefo...
 
Cecutti Federico - Progetto e sviluppo di un'applicazione domotica per telefo...
Cecutti Federico - Progetto e sviluppo di un'applicazione domotica per telefo...Cecutti Federico - Progetto e sviluppo di un'applicazione domotica per telefo...
Cecutti Federico - Progetto e sviluppo di un'applicazione domotica per telefo...
 
SESAMO (application login automator): evoluzioni applicative e considerazioni...
SESAMO (application login automator): evoluzioni applicative e considerazioni...SESAMO (application login automator): evoluzioni applicative e considerazioni...
SESAMO (application login automator): evoluzioni applicative e considerazioni...
 
Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...
Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...
Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...
 
PALUZZANO TESI
PALUZZANO TESIPALUZZANO TESI
PALUZZANO TESI
 
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
 
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
 
Tesi Tamiazzo09
Tesi Tamiazzo09Tesi Tamiazzo09
Tesi Tamiazzo09
 
Dynamic Scheduling
Dynamic SchedulingDynamic Scheduling
Dynamic Scheduling
 
Public Light Manager - Una GUI per la gestione remota di un impianto di illum...
Public Light Manager - Una GUI per la gestione remota di un impianto di illum...Public Light Manager - Una GUI per la gestione remota di un impianto di illum...
Public Light Manager - Una GUI per la gestione remota di un impianto di illum...
 
Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...
Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...
Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...
 
Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...
Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...
Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...
 
Cloud Computing e Modelli di Business
Cloud Computing e Modelli di Business Cloud Computing e Modelli di Business
Cloud Computing e Modelli di Business
 
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
 
Application_level_SLA_monitoring
Application_level_SLA_monitoringApplication_level_SLA_monitoring
Application_level_SLA_monitoring
 
Implementazione in Java di plugin Maven per algoritmi di addestramento per re...
Implementazione in Java di plugin Maven per algoritmi di addestramento per re...Implementazione in Java di plugin Maven per algoritmi di addestramento per re...
Implementazione in Java di plugin Maven per algoritmi di addestramento per re...
 
Progettazione e Sviluppo di un Sistema per Migliorare il Codice Generato da u...
Progettazione e Sviluppo di un Sistema per Migliorare il Codice Generato da u...Progettazione e Sviluppo di un Sistema per Migliorare il Codice Generato da u...
Progettazione e Sviluppo di un Sistema per Migliorare il Codice Generato da u...
 

Tesi Todone

  • 1. Università Degli Studi di Trieste Facoltà di Ingegneria Corso di Laurea Specialistica in Ingegneria Informatica Tesi di laurea in reti di calcolatori Progetto e realizzazione di una infrastruttura modulare per acquisizione ed archiviazione remota di documenti LAUREANDO RELATORE Giancarlo Todone Prof. Alberto Bartoli CORRELATORE Ing. Giorgio Davanzo Anno Accademico 2008/2009
  • 2.
  • 3. Talk is cheap. Show me the code! (Linus Torvalds)
  • 4.
  • 5. Indice 1 Introduzione 1 2 Il caso di studio 3 2.1 Situazione iniziale e requisiti . . . . . . . . . . . . . . . . . 3 2.2 Architettura generale e definizioni . . . . . . . . . . . . . . 5 2.2.1 Flusso di un tipico caso di utilizzo . . . . . . . . . 9 2.3 Cenni di implementazione e tecnologie utilizzate . . . . . . 11 3 SyncUtils 13 3.1 Requisiti e scopi di SyncUtils . . . . . . . . . . . . . . . . 13 3.2 Architettura . . . . . . . . . . . . . . . . . . . . . . . . . . 14 3.3 Dettagli implementativi e tecnologie . . . . . . . . . . . . 20 3.3.1 Perché il file system? . . . . . . . . . . . . . . . . . 20 3.3.2 Meccanismo di sincronizzazione . . . . . . . . . . . 21 3.3.3 Identificativi di richieste e risposte . . . . . . . . . 23 3.3.4 Protocollo . . . . . . . . . . . . . . . . . . . . . . . 24 3.3.5 Problematiche delle notifiche . . . . . . . . . . . . 27 3.3.6 Formati dei file di comunicazione . . . . . . . . . . 28 3.3.7 Serializzazione XML . . . . . . . . . . . . . . . . . 32 3.3.8 COM . . . . . . . . . . . . . . . . . . . . . . . . . 35 3.4 Installazione e preparazione dell’ambiente di esecuzione . . 40 i
  • 6. ii INDICE 4 GEC_Scan 43 4.1 Requisiti e progetto dell’interfaccia utente . . . . . . . . . 43 4.1.1 Interfaccia grafica e usabilità . . . . . . . . . . . . 44 4.2 Composizione di GEC_Scan . . . . . . . . . . . . . . . . . 49 4.2.1 TWAIN . . . . . . . . . . . . . . . . . . . . . . . . 50 4.2.2 VisualSlideShow e design delle classi coinvolte . . . 55 4.3 Tecnologie e tecniche implementative . . . . . . . . . . . . 58 4.3.1 dotNetTwain . . . . . . . . . . . . . . . . . . . . . 59 4.3.2 Grafica . . . . . . . . . . . . . . . . . . . . . . . . 68 4.4 Installazione e preparazione dell’ambiente di esecuzione . . 70 5 Sottosistema di archiviazione e plug in 73 5.1 Caratteristiche del sottosistema di archiviazione . . . . . . 73 5.1.1 Funzionalità di manipolazione file . . . . . . . . . . 75 5.2 Design del sottosistema di archiviazione . . . . . . . . . . 76 5.3 Specifiche e tecnologie . . . . . . . . . . . . . . . . . . . . 80 5.3.1 Archiviazione locale e debug . . . . . . . . . . . . . 84 5.3.2 Funzionalità estese ed archiviazione Remota . . . . 85 5.3.2.1 Sharepoint . . . . . . . . . . . . . . . . . 86 5.3.2.2 Google Documents . . . . . . . . . . . . . 92 5.4 Setup dei sistemi di archiviazione . . . . . . . . . . . . . . 97 6 Conclusioni 99 Bibliografia 103
  • 7. Capitolo 1 Introduzione La gestione di un documento cartaceo per via informatica inizia con le operazioni di acquisizione ed archiviazione. Per “acquisizione” si intende l’operazione di traduzione e codifica di un documento cartaceo in una forma comprensibile e fruibile da un elaboratore. Per “archiviazione” si può distinguere tra la mera operazione di immagazzinamento dati e la “conservazione sostitutiva”—con la quale si intende tutto il complesso di azioni che permettono di conservare elettronicamente dati di valore legale o tributario senza per questo conservare anche i documenti cartacei originali. A seguito e come proseguimento del tirocinio svolto presso la soft- ware house MIDA4, lo scrivente ha realizzato un pacchetto software per consentire di aggiungere le funzionalità di archiviazione al software di contabilità preesistente GEC. Tale pacchetto fornisce una infrastruttura per interfacciare GEC con altri sistemi di archiviazione (già esistenti o futuri) grazie ad un sistema estendibile con plug in, e si inserisce in un più ampio contesto di gestione documentale in sviluppo nel “Laborato- rio Reti” del DEEI, Università Degli Studi di Trieste. Un tema trattato con particolare riguardo è quello dell’archiviazione remota, cioè l’inte- grazione con servizi di terze parti—come Google Documents o Microsoft Sharepoint—per la memorizzazione dei dati su un server connesso ad Internet. 1
  • 8. 2 1. Introduzione Dall’osservazione della situazione di partenza, dopo lo studio del pro- blema nella sua accezione più generale, sono stati definiti dei requisiti che hanno portato alla suddivisione del lavoro nei tre moduli software responsabili di comunicazione, acquisizione e archiviazione; per ognuno dei tre moduli sono stati definiti ulteriori requisiti in base ai quali sono state poi concepite l’architettura e le specifiche tecnologiche di ogni sin- gola parte. Ogni classe o componente sviluppato è stato verificato con metodologie di unit-test ed in alcuni casi anche con test automatici di carico. L’intero progetto ha subito anche diversi test funzionali condotti da operatori umani. I requisiti tecnologici del committente hanno portato alla scelta del linguaggio C# e del framework dotNet all’interno dell’ambiente di svi- luppo integrato Visual Studio 2008, su un sistema operativo Windows XP/Vista. L’interfacciamento con le periferiche di acquisizione è gestito con lo standard TWAIN mentre l’interfacciamento con il software GEC è gestito con le tecnologie COM e XML. Nel capitolo 2 si affrontano tematiche di carattere generale inerenti l’insieme del software sviluppato. Nei tre capitoli successivi ( 3 nella pa- gina 13, 4 nella pagina 43, 5 nella pagina 73) si affrontano separatamente i tre moduli software, esponendo di ognuno: • situazione pregressa e/o requisiti; • architettura e definizioni; • tecniche implementative e tecnologie utilizzate; aggiungendo—ove pertinente—un breve riassunto delle operazioni necessarie all’installazione e alla manutenzione del modulo.
  • 9. Capitolo 2 Il caso di studio 2.1 Situazione iniziale e requisiti La software house MIDA4 ha prodotto e mantiene il software di con- tabilità chiamato GEC. La necessità dei clienti di MIDA4 di archiviare documenti per via informatica contestualizzandoli con le loro situazioni amministrative e altri dati, ha spinto la software house a ricercare un modo per ampliare in tal senso le capacità del suo prodotto. La richiesta era quella di aggiungere le funzionalità desiderate in un modo che permettesse di iniziare a servirsi di tecnologie più recenti e promettenti senza per questo dover riscrivere da capo un programma già rodato e funzionante come GEC. GEC viene attualmente fornito in due versioni: installabile e ASP (2.2): • la versione installabile è un normale programma che risiede ed ope- ra sul personal computer dell’utente finale, ed eventualmente co- munica con un server centralizzato per recuperare informazioni di licenza ed aggiornamenti; • la versione ASP consiste nella versione installabile montata però su un server accessibile da molti fruitori contemporaneamente tramite Internet ed un software di remote desktop. 3
  • 10. 4 2. Il caso di studio Il software necessario ad aggiungere le funzionalità di archiviazione de- siderate, deve necessariamente interagire con GEC—qualsiasi sia la sua ubicazione—ma deve anche interagire con l’hardware dell’utente fina- le (es: scanner e fotocamere) e deve essere in grado di comunicare autonomamente con eventuali servizi di archiviazione di terze parti. Il modo in cui il nuovo software si integra con GEC deve 1. richiedere il minimo sforzo in termini di modifiche al codice sorgente di GEC; 2. essere facilmente utilizzabile dagli sviluppatori di GEC; 3. permettere l’integrazione futura con nuovi servizi di terze parti senza riscrivere il codice sorgente; per poter permettere rispettivamente: 1. di rendere il più possibile indipendenti lo sviluppo e il manteni- mento di GEC da quelli del nuovo software di archiviazione; 2. di consentire una rapida integrazione al momento del rilascio; 3. di poter essere rapidamente espandibile con nuove funzionalità. Dal punto di vista dell’utente, il software sviluppato dev’essere: • facilmente integrabile con il proprio sistema di produzione; • di utilizzo semplice ed immediato. In quest’ottica, un sistema di astrazione delle periferiche di acquisi- zione immagini dell’utente è stato posto come requisito; fondamentale è anche la trasparenza di tale meccanismo, necessaria al fine di ottenere un’interfaccia grafica consistente per tutti gli utenti, a prescindere da marca e modello dei loro hardware. Infine, la scelta dell’ambiente di sviluppo ha dovuto tenere conto di varie richieste: • GEC opera in ambiente Microsoft Windows, e quindi anche il nuovo software di archiviazione deve funzionare almeno in tale sistema;
  • 11. Architettura generale e definizioni 5 • esso deve consentire di proporre all’utente finale un’interfaccia piacevole, immediata e consistente; • metodologie, linguaggi, librerie, framework utilizzati (a parte quelli finora citati che hanno diverse motivazioni) devono essere allo stato dell’arte, o quantomeno ancora vivamente supportati da produttori e da una nutrita schiera di sviluppatori; essi devono però permet- tere allo sviluppatore di interfacciarsi anche con moduli software utilizzanti tecnologie meno recenti, come TWAIN o Visual Basic 6 (di cui—come vedremo—fanno uso alcune parti del sistema). Da ciò si evince come la capacità di interoperabilità tra diverse tecnolo- gie sia essa stessa un requisito; viste queste necessità, in fase di analisi preliminare è stato posto l’utilizzo del dotNet framework di Microsoft come requisito. 2.2 Architettura generale e definizioni Per motivi di natura tecnica e per questioni di manutenibilità del codice che vedremo in seguito, il modulo che dovrà svolgere le operazioni di acquisizione e archiviazione dev’essere indipendente, cioè non fare parte di GEC, ma essere compilato in un eseguibile autonomo: questo significa che GEC e il nuovo software di acquisizione sono due entità distinte che necessitano di comunicare. Si considerino quindi i seguenti attori: GEC è il programma di contabilità già esistente, che dovrà subire delle modifiche per poter utilizzare SyncUtils e comunicare con il soft- ware di nuova creazione dedicato all’acquisizione e archiviazione; in seguito, se non esplicitamente specificato, col nome di GEC ci si riferirà indistintamente al programma in versione tradizionale o ASP; GEC_Scan è il software di acquisizione e archiviazione: esso è un soft- ware a se stante, ma può dialogare con GEC—tramite un mec- canismo descritto in 3.3 nella pagina 20—e con servizi di terze parti—mediante dei moduli aggiuntivi chiamati plug in ( 5.3 nella pagina 80).
  • 12. 6 2. Il caso di studio ASP Remote desktop Internet (A) User 1 GEC_Scan ASP Remote desktop GEC-2 (B) User 2 ASP GEC-1 GEC_Scan GEC-3 (C) User 3 GEC_Scan Figura 2.1: Tre casi di utilizzo del sistema di archiviazione: nel caso (A) l’utente 1 utilizza solo l’istanza 1 di GEC tramite ASP e il suo sistema di remote desktop; nel caso (C) l’utente 3 utilizza solo GEC-3 in esecuzione sul suo computer locale; nel caso (B), l’utente 2 utilizza sia la locale istanza 2 di GEC, sia GEC-1 tramite sistema ASP. Queste due entità devono poter comunicare tra loro in vario modo. Nel caso più semplice GEC e GEC_Scan vengono eseguiti sullo stesso calcolatore e comunicano senza interferenze esterne; in figura 2.1 si os- servano anche i casi in cui GEC sia remoto e quello più complesso in cui
  • 13. Architettura generale e definizioni 7 un solo utente utilizzi più istanze di GEC, eventualmente miste tra locali e remote. plug in SyncUtils GEC GEC_Scan plug in plug in                         acquisizione archiviazione                                             comunicazioni funzionalità                                                                 software software preesistente nuovo Figura 2.2: Descrizione dei software coinvolti; GEC è preesistente e viene modificato solo per poter usare SyncUtils; il resto del software è sviluppato ex novo; di questo è visibile la suddivisione in comunicazioni, acquisizione ed archiviazione: solo le ultime due implementano funzionalità richieste, mentre la prima serve a rendere interoperabili nuovo e vecchio software. Come illustrato in figura 2.2, tutte le funzionalità aggiunte risiedono in GEC_Scan e nei suoi plug in, mentre la libreria SyncUtils consente a GEC di comunicare con GEC_Scan e di utilizzare tali funzionalità. Si consideri inoltre la seguente nomenclatura: Utente è l’utente finale di GEC e di GEC_Scan, colui che opera i pro- grammi per archiviare documenti; si faccia attenzione alla differen- za tra “utente finale” e l’utente di una libreria (sviluppatore) o di un servizio (potrebbe essere un modulo software);
  • 14. 8 2. Il caso di studio Documento un insieme di più immagini corredate da meta dati; ASP acronimo di Application Service Provider, è il sistema che permet- te tramite un remote desktop di utilizzare dal PC dell’utente finale un’istanza di GEC in esecuzione su un server remoto; da non con- fondersi con Active Server Pages di Microsoft (di cui non si parla mai in questo testo); Plug in è un modulo software che consente di aggiungere funzionalità a GEC_Scan senza la necessità di modificare o ricompilare il suo codice sorgente; Servizio esterno un qualsiasi servizio di archiviazione di documenti estraneo sia a GEC che a GEC_Scan, probabilmente pubblicato tramite un servizio web. Sessione di acquisizione l’insieme di operazioni iniziate dall’utente che portano all’acquisizione, riorganizzazione in documenti e archi- viazione di un insieme di immagini con i loro meta dati associati (punti da 2 a 9 in 2.2.1 nella pagina 10 e figura 2.3; si noti che tra il punto 3 e il punto 4 il sistema rimane indefinitamente in attesa di istruzioni dall’utente; quindi può essere un operazione che richiede molto tempo). In aggiunta—se non per esigenze particolari—si eviterà di seguito l’uti- lizzo di termini come “server” e “client” per riferirsi a GEC o GEC_Scan, poiché potrebbero essere causa di fraintendimenti; infatti nella sua ver- sione ASP, il software GEC viene eseguito su una macchina che interpreta il ruolo di server, ma per correttezza dovrebbe essere considerato client del software di acquisizione che gli offre per l’appunto un servizio.
  • 15. Architettura generale e definizioni 9 2.2.1 Flusso di un tipico caso di utilizzo 1.richiede inizio sessione di acquisizione Utente 2.Request 3.mostra form principale Acquisizione (tempo indefinito) 4.accetta o annulla (C): GEC_SCAN (B): SyncUtils (A): GEC tempo 5.esegue il plug in adeguato 6.sottomette (E): Servizio esterno documenti (D): Plug in 7.fine del job 8.fine del job 9.Response Figura 2.3: Flusso di esecuzione di una richiesta e relativa risposta; vede- re 2.2.1 nella pagina successiva per una descrizione puntuale dei passi nume- rati; la progettazione e creazione delle entità marcate come (B), (C) e (D) costituiscono il caso di studio; le linee ondulate indicano il punto in cui l’utente può causare un’attesa a tempo indeterminato del sistema; (B) risolve i proble- mi di comunicazione tra (A) e (C) siano essi sulla stessa macchina oppure su macchine diverse comunicanti tramite Internet.
  • 16. 10 2. Il caso di studio Un tipico caso di utilizzo del sistema—nel quale una singola istanza di GEC comunica con una singola istanza di GEC_Scan—si svolge co- me di seguito (i punti numerati si riferiscono a figura 2.3 nella pagina precedente): • il sistema dell’utente si avvia; parte automaticamente anche il soft- ware di acquisizione e carica dalla cartella plugins le estensioni di cui è stato dotato; • l’utente carica e opera GEC (versione installabile o ASP), mentre il programma di acquisizione (eseguito allo start up sul sistema dell’utente) resta in attesa nascosto; 1. l’utente esegue un’operazione su GEC per la quale è prevista l’acquisizione di un certo numero di documenti; 2. GEC—tramite una chiamata all’apposita libreria di comunicazione SyncUtils—effettua una richiesta a GEC_Scan; ad esso (sia que- sto in esecuzione sulla medesima macchina o su di una diversa) viene segnalato di mostrare la sua finestra principale, inviandogli nel contempo i meta dati da associare ai documenti che si andrà ad acquisire ed una lista di azioni desiderate da intraprendere su di essi; se la finestra era già aperta a seguito di una precedente richiesta non ancora soddisfatta, il lavoro viene messo in coda; 3. GEC_Scan accetta la richiesta e la accoda ad una lista o la scarta rispondendo con una lista di errori (ad esempio quando non è in grado di gestire la richiesta); 4. l’utente usa le funzionalità del programma di acquisizione per scan- sionare1 ed ordinare un certo numero di pagine inerenti la richiesta accettata; l’utente può inserire dei separatori tra gruppi di immagi- ni per organizzare il materiale acquisito in documenti: ad ogni do- cumento vengono associati tutti i meta dati ricevuti; alla fine della riorganizzazione e separazione dei documenti, l’utente sottomette i dati o annulla la sessione con appositi comandi; 1 Sulla scelta tra gli equivalenti italiani dell’inglese “to scan” l’Accademia della Crusca si è espressa nelle “Risposte ai quesiti” concludendo che sono accettabili tutte le soluzioni (scandire, scannare, scannerare, scannerizzare, scansionare) [3].
  • 17. Cenni di implementazione e tecnologie utilizzate 11 5. GEC_Scan cerca tra i plug in caricati quelli in grado di soddisfare le richieste effettuate da GEC tramite la libreria di comunicazione ed esegue ogni operazione ritenuta pertinente su ogni documento; 6. questo può comportare il dialogo con un ulteriore software di ar- chiviazione, anche residente su una macchina diversa da quella su cui è in esecuzione GEC e da quella su cui esegue il programma di acquisizione (esempio: inviare tutti i documenti ad un servizio web); 7. il software di acquisizione completa ogni elaborazione e compila un rapporto con il dettaglio delle operazioni effettuate e un’eventuale lista di errori; 8. il software di acquisizione invia la risposta così costruita a GEC sempre tramite libreria di comunicazione; 9. GEC riceve la notifica che i suoi lavori richiesti sono stati completati (o annullati); • nel caso la coda di lavori del software di acquisizione non sia vuo- ta, l’utente viene invitato a continuare il suo lavoro con un’altra sessione di sottomissione documenti. 2.3 Cenni di implementazione e tecnologie utilizzate Il programma preesistente GEC è stato sviluppato in Visual Basic 6, kit di sviluppo capace di generare file di codice eseguibile nativo; esso permette anche una buona interazione con componenti COM. Nei seguenti tre capitoli, viene trattato il software sviluppato ex novo per aggiungere a GEC le funzionalità di acquisizione e archiviazione: libreria di comunicazione (progetto di nome “SyncUtils”) che per- mette ad un’istanza di GEC di effettuare richieste ad un’istanza di GEC_Scan e riceverne risposta, in 3 nella pagina 13;
  • 18. 12 2. Il caso di studio software GEC_Scan che tramite interfaccia grafica permette l’acqui- sizione di documenti, in 4 nella pagina 43; plug in che permettono a GEC_Scan di accedere a servizi di archiviazione di terze parti, in 5 nella pagina 73. Tutti questi moduli software sono stati sviluppati nel linguaggio C# e utilizzano quindi il dotNet framework (versione 2.0 o successive). Con riguardo alla libreria di comunicazione, in 3.3.8 nella pagina 35 si parla della necessaria metodologia di interazione tra codice mana- ged e codice nativo: l’utilizzo di oggetti dotNet come componenti COM tramite software wrapper. Quest’ultimo sistema è stato adottato per permettere a GEC di chia- mare delle funzioni sviluppate con tecnologia dotNet; in questo modo la libreria SyncUtils è richiamabile sia da codice nativo (come avviene per GEC) sia da codice dotNet. Le funzioni di comunicazione utilizzano un meccanismo di sincronia e comunicazione basato sulla condivisione di un file system ( 3.2 nella pa- gina 14) per scambiarsi messaggi XML (formato descritto in 3.3.6 nella pagina 28) secondo il protocollo descritto in 3.3.4 nella pagina 24. La ge- nerazione del codice XML avviene tramite meccanismo semi automatico per serializzazione di oggetti ( 3.3.7 nella pagina 32). Per l’interfacciamento di GEC_Scan con le periferiche di acquisizio- ne immagini è stato usato TWAIN ( 4.2.1 nella pagina 50)—secondo le specifiche versione 1.9 [5]—tramite l’apposito sviluppo della libreria dotNetTwain. TWAIN si presenta come una DLL contenente codice nativo a 32 bit; per l’utilizzo da parte di dotNet, è quindi necessa- rio adottare ulteriori tecniche di interoperabilità con l’aiuto del package System.Runtime.InteropServices ( 4.3.1 nella pagina 59). Ogni plug in è stato sviluppato come una classe dotNet residente in un assembly dotNet2 . Per permettere il rapido sviluppo di plug in sono state sfruttate alcune caratteristiche del framework dotNet come reflection e caricamento dinamico di classi. 2 Un assembly dotNet è una DLL contenente bytecode dotNet nella forma di una o più classi appartenenti anche a diversi namespace, con i rispettivi meta dati di contorno.
  • 19. Capitolo 3 SyncUtils 3.1 Requisiti e scopi di SyncUtils La parte del progetto che deve interagire più intimamente con GEC è la libreria di comunicazione chiamata SyncUtils. Mentre le funzionalità di archiviazione aggiuntive risiedono principalmente in GEC_Scan e nel- l’insieme dei suoi plug in, esse non potrebbero essere utilizzate da GEC senza l’ausilio di questa libreria: il suo scopo è quello di astrarre il meto- do di comunicazione dalle modalità tecniche con le quali le comunicazioni effettivamente avvengono. L’ambiente nel quale il sistema progettato deve operare prevede: • molti software di scansione (GEC_Scan) che hanno a disposizione varie sorgenti di dati e vengono manovrati da operatori umani; • uno o più software di controllo (GEC) che possano richiedere ad uno dei software di scansione di cominciare una sessione di acquisizione. GEC_Scan deve essere in grado di accettare una richiesta di inizio proce- dura di acquisizione, gestirla autonomamente e inviare alla fine la notifica dell’avvenuto lavoro senza tenere GEC in sospeso, permettendogli così di gestire nel frattempo eventuali altre comunicazioni. 13
  • 20. 14 3. SyncUtils Siamo perciò interessati ad un tipo di comunicazione nella quale—nel caso peggiore (facendo riferimento alle figure 2.1 nella pagina 6 e 3.1): • come attori, sono coinvolte m istanze di GEC in versione installa- bile (al massimo una per macchina), n istanze remote di GEC in versione ASP, i istanze di GEC_Scan (al massimo una per macchi- na), con i, m ed n numeri imprecisati non necessariamente uguali, maggiori di 1; • ogni attore può prendere l’iniziativa di parola; • ogni GEC in versione installata può parlare col GEC_Scan presente sulla sua stessa macchina (se presente); • ogni GEC in versione ASP può parlare con qualsiasi GEC_Scan; • ogni GEC_Scan può parlare con GEC installato sulla sua stessa macchina e con qualsiasi altro GEC in versione ASP. Cioè: ogni utente col suo calcolatore deve poter usare la sua unica copia di GEC_Scan facendola interagire con un GEC installato sulla sua stessa macchina e/o con un certo numero di altri GEC remoti. 3.2 Architettura Si assuma che ogni copia di GEC_Scan abbia accesso in lettura e scrit- tura ad una porzione privata del file system dell’elaboratore sul quale è installato; chiunque voglia dialogare con esso (ad es. GEC installato o GEC versione ASP) dovrà poter avere accesso in lettura e scrittura alla stessa porzione del file system (per brevità di seguito “file system” o “FS”). La comunicazione è dunque a mezzo condiviso, nel senso che gli attori che dialogano tra loro di volta in volta devono condividere un file system cui hanno accesso; per analizzare il caso più generale continueremo a dire che ogni GEC condivide con l’i-esimo GEC_Scan il file system i (o FS-i). Le richieste vengono effettuate da un GEC scrivendo nel FS-i dei file con estensione .IN contenenti i dettagli delle richieste in formato
  • 21. Architettura 15 XML ( 3.3.6 nella pagina 28); le risposte al termine di una sessione di acquisizione vengono fornite da GEC_Scan scrivendo nel FS-i dei file con estensione .OUT e nome file uguale alla corrispondente richiesta. GEC ASP ASP GEC GEC FS-i GEC_Scan-i Figura 3.1: Schema dell’utilizzo concorrente da più istanze di GEC del file system i, associato alla i-esima istanza di GEC_Scan. Naturalmente, più processi potrebbero accedere contemporaneamen- te ad uno stesso file system; è tuttavia stato approntato un meccanismo di mutua esclusione (descritto in 3.3.2 nella pagina 21): • per fare in modo che ogni richiesta abbia un nome univoco sul file system i; • per garantire che più GEC concorrenti nell’effettuare una richiesta allo stesso GEC_Scan non si intralcino a vicenda; • per fare in modo che le richieste siano ordinabili—per istante di arrivo—in una coda.
  • 22. 16 3. SyncUtils Un attore che voglia prendere possesso del mezzo comunicativo costitui- to dal FS-i, per prima cosa utilizzerà detto meccanismo impedendo a qualunque altro attore di impadronirsi a sua volta del file system. Ovviamente non sempre un attore riesce a prenotare l’uso esclusivo del file system, ad esempio quando questo è già in uso da un altro attore; in seguito ( 3.3.2 nella pagina 21) si darà spiegazione dei dettagli del meccanismo: si dica “tentativo di acquisizione del lock ” il tentativo di impadronirsi del mezzo di comunicazione, e “acquisizione del lock ” il provare reiteratamente ad acquisire il lock finché non si abbia successo. La generazione di un nome file univoco nel FS-i, necessaria per la scrittura dei file .IN dipende da una stringa originata a partire dalla da- ta/ora della sua creazione: questa stringa e l’entità che essa rappresenta assumono il nome di JobId. Definiamo quindi un JobId come l’iden- tificativo univoco all’interno di un file system, utilizzato per identificare esattamente richieste e relative risposte. Ogni file di nome {JobId}.IN contiene delle informazioni organiz- zate in un’entità chiamata Request; ogni file di nome {JobId}.OUT contiene dati relativi ad un’entità di tipo Response. Come si può osservare in figura 3.2 nella pagina successiva, ogni Request contiene: • una o più ActionRequest; • uno e un solo AdditionalData; • un Timestamp. In ottica di programmazione ad oggetti, ActionRequest e AdditionalData sono solo delle classi base astratte, atte a definire l’archetipo dei campi contenuti in ogni richiesta: una Request ben for- mata non conterrà mai direttamente una ActionRequest, bensì una classe derivata da essa (similmente per AdditionalData ed altre clas- si simili); d’ora in avanti per “una ActionRequest” ad esempio, si intenderà una qualsiasi entità che derivi da ActionRequest e non un oggetto di tipo ActionRequest, se non diversamente specificato.
  • 23. Architettura 17 Response Request Document Page ActionRequest ActionResponse ResponsePage Page ActionRequest ResponsePage Page ActionResponse ResponsePage Page AdditionalData ResponsePage Document ActionResponse Page ResponsePage ActionResponse ResponsePage Figura 3.2: Esposizione grafica della struttura di Request e Response; le frecce indicano che l’oggetto d’origine mantiene internamente un riferimento all’oggetto puntato. Le azioni intraprese da GEC_Scan alla ricezione di una Request dipendono dal tipo specializzato di ogni ActionRequest contenuta; AdditionalData contiene dei meta dati che devono essere interpreta- ti da GEC_Scan per soddisfare correttamente ogni richiesta e possono essere associati ai documenti acquisiti.
  • 24. 18 3. SyncUtils Per quanto riguarda Response essa contiene sempre: • la sezione Documents; • la sezione Errors, relativa agli errori generici di comunicazione. Si ponga attenzione sul fatto che un documento è stato definito come un’insieme di una o più immagini: finora non si è parlato di alcun limite al numero di immagini acquisibili dall’utente, o di vincoli sul modo di raggrupparle in documenti; quindi nè il numero di documenti che ver- ranno elaborati nè il numero di pagine di ognuno di questi è predicibile salvo casi particolari1 . Per questi motivi, in una Response • Documents contiene uno o più oggetti Document, entità rappresentante un gruppo di immagini; • ogni Document contiene una lista di oggetti Page, entità rappresentanti le singole immagini scansionate dall’utente; • ogni Document contiene una o più ActionResponse (con considerazioni simili al caso di ActionRequest); • ogni ActionResponse rappresenta il rapporto su una sola azione intrapresa per il Document che la contiene in seguito all’elaborazione di una ActionRequest; • ogni ActionResponse contiene una lista di ResponsePage, enumerazione delle azioni intraprese sulle singole Page del Document. Anche in questo caso l’esatto contenuto di una ActionResponse dipen- de dalla classe specializzata che la estende. Si pensi al seguente esempio pratico: si ha la necessità di archiviare una fattura del signor Mario Ros- si presso un servizio di archiviazione remota chiamato “MyArchive”; a tale scopo saranno stati precedentemente definiti alcuni tipi specializzati come 1 In realtà GEC può richiedere un numerno minimo ed uno massimo di gruppi di immagini (vedi 4.1.1 nella pagina 47).
  • 25. Architettura 19 • SendToMyArchiveActionRequest; • SendToMyArchiveActionResponse; • SendToMyArchiveActionPerformer; • SendToMyArchiveResponsePage; derivanti rispettivamente da • ActionRequest; • ActionResponse; • ActionPerformer; • ResponsePage. In più, per veicolare correttamente i dati relativi ad una fat- tura, InvoiceAdditionalData è stato derivato—con l’ag- giunta di appositi campi—da AdditionalData. A que- sto punto è possibile costruire una Request contenente ad esempio una sola SendToMyArchiveActionRequest ed un InvoiceAdditionalData. SendToMyArchiveActionRequest conterrà informazioni relative l’indirizzo al quale raggiungere il servizio MyArchive ed impostazioni simili; InvoiceAdditionalData potrebbe contenere l’anagrafica del signor Mario Rossi e ogni altro dato utile ai fini della compilazione dei meta dati associati ai documenti veri e propri. Se l’utente ha acquisito due documenti da tre pagine ciascuno, con tale ri- chiesta è lecito aspettarsi una risposta per cui vi saranno due Document contenenti tre Page e una SendToMyArchiveActionResponse cia- scuno; ogni SendToMyArchiveActionResponse conterrà a sua volta tre SendToMyArchiveResponsePage, ognuna delle quali—facendo riferimento ad una singola Page—fornirà ad esempio informazioni sul successo o meno dell’archiviazione, un link per recuperare l’immagine corrispondente ecc. . .
  • 26. 20 3. SyncUtils Tutti i tipi specializzati, finalizzati a specifiche richieste, sono defi- niti nei moduli aggiuntivi chiamati plug in, caricati in modo dinamico all’avvio di GEC_Scan. 3.3 Dettagli implementativi e tecnologie Posto che GEC_Scan è un modulo software a se stante, anche il solo aggiungere a GEC le funzionalità di comunicazione con quest’ultimo ri- chiede necessariamente la modifica del programma e l’aggiunta di molto codice. Integrare direttamente in GEC queste capacità sviluppandole in Vi- sual Basic 6—lo stesso linguaggio in cui è stato scritto—sarebbe potuta sembrare una buona idea: al contrario, aggiungere a del codice già ma- turo una ulteriore complessità per quanto lieve, potrebbe portare a dei problemi di manutenibilità. Se si aggiunge il fatto che il kit di sviluppo di Visual Basic 6 è alla fine del suo ciclo di vita, si capisce come sia stato preferibile comporre il sistema di comunicazione con una tecnologia più moderna: si è scelto di sviluppare con dotNet e la tecnologia COM del codice che—proprio dal punto di vista del ciclo di vita—è autonomo e interfacciabile con GEC con un ridotto numero di modifiche a quest’ultimo. La libreria SyncUtils è utilizzabile da codice dotNet come un qualsiasi altro assembly e (previa registrazione di alcuni tipi, 3.4 nella pagina 40) come componente COM. 3.3.1 Perché il file system? La comunicazione tra sistemi informatici è sempre un ambito insidioso e ricco di difficoltà, spesso nemmeno troppo palesi; anche per questo motivo, nell’affrontarlo si tenta quasi sempre di evitare di reinventare la ruota: come in molte altre situazioni ci si affida più il possibile a soluzioni già note ed affermate, almeno per i problemi più comuni. Nel caso in esame, ci si trova nella situazione abbastanza tipica di un software (GEC_Scan) che pur eseguendo sull’elaboratore di un utente finale (ed essendo perciò molto probabilmente isolato dalla rete da un
  • 27. Dettagli implementativi e tecnologie 21 firewall e da un sistema NAT/NAPT) deve comportarsi come server, attendendo richieste e non iniziandole. Le possibili soluzioni note che usino protocolli consueti come TCP/IP, sarebbero comunque state tutte piuttosto complesse da mettere in pratica: fortunatamente il sistema ASP—come già accennato—mette a disposizione un file system condiviso tra i suoi utilizzatori. L’utilizzo di un file system condiviso per la sincronia tra processi, la regolamentazione di accesso esclusivo a risorse e lo scambio di informazio- ni, è una pratica da tempo largamente diffusa e di dimostrata efficacia2 : lo studio di alcune specifiche Microsoft [8] ed alcuni esperimenti condotti, hanno consentito di giudicare tali metodologie idonee anche all’utilizzo su un file system condiviso con una macchina remota tramite il sistema ASP. Ciò permette di delegare al gestore del file system alcune problemati- che descritte in seguito come l’atomicità della creazione di un oggetto di sincronia, la sicurezza del canale trasmissivo, la capacità di comunicare in determinate condizioni. 3.3.2 Meccanismo di sincronizzazione L’acquisizione del lock per il file system i, si effettua tramite la scrittura in esso di un file—vuoto—di nome concordato che non possa collidere con gli eventuali file .in e .out già presenti (attualmente esso si chiama lockfile.lck). Si dice che tale lock viene rilasciato quando il file viene cancellato. Un attore che volesse acquisire il lock dovrebbe per prima cosa veri- ficare che tale file non esista già e solo in tal caso provvedere a crearlo; una volta creato, altri attori desiderosi di acquisire il lock rileverebbero la presenza del file sopra citato e desisterebbero (o resterebbero in attesa che il file venga rimosso, a seconda dei casi). È di fondamentale importanza capire come l’operazione di verifica e creazione del file di lock debba necessariamente essere atomica per gestire le eventuali situazioni di concorrenza: non è accettabile alcuna situazio- 2 Basti pensare ai files di lock utilizzati da alcuni software di database o a quelli usati del popolare Microsoft Word per regolare l’accesso ai suoi documenti.
  • 28. 22 3. SyncUtils ne di inconsistenza come quella riportata di seguito a titolo d’esempio: nell’ordine 1. l’attore A vuole acquisire il diritto di parola, pertanto tenta di segnalarlo, provando a creare il file di lock ; 2. in un istante di tempo ravvicinato ad (1) l’attore B vuole acquisire anch’esso il diritto di parola, pertanto tenta di creare a sua volta il file di lock ; 3. A verifica che il file di lock non esiste; 4. B verifica che il file di lock non esiste; 5. A crea fisicamente il file di lock ; 6. B—visto il punto 4—crede che il file di lock non esista e lo sovrascrive. Se il sistema di sincronia fosse prono ad un tale tipo di errore, due attori potrebbero ritenere di essere ognuno l’unico autorizzato ad accedere al file system in un dato istante di tempo, creando JobId non certamente univoci e sovrascrivendo potenzialmente l’uno i file dell’altro, portando così ad evoluzioni impredicibili nella comunicazione. Il problema della atomicità delle operazioni di verifica e creazione del file di lock viene risolto considerando che all’atto della creazione di un nuovo file, in ambiente Microsoft Windows si può indicare al sistema cosa fare nel caso in cui non sia possibile completare l’operazione (es: perché il file esiste già): sovrascrivere il file, accodare al contenuto o segnalare un’errore. Quando un attore desidera acquisire il lock, può semplicemente provare a creare il file, istruendo il sistema operativo a sollevare un’errore in caso di fallimento: se non si riceve alcun errore il lock è acquisito, altrimenti no. Al sistema operativo si delega la responsabilità della consistenza del suo file system; in caso di file system remoti, il sistema operativo che fornisce l’accesso remoto ad un file system da lui mantenuto si occupa di garantire la consistenza quando più processi tentino di creare lo stesso file [8].
  • 29. Dettagli implementativi e tecnologie 23 Per impedire che altri processi come un antivirus o lo stesso uten- te possano inavvertitamente interferire col meccanismo di sincronia, il file viene mantenuto aperto in modalità esclusiva per tutto il tempo di detenzione del lock : in questo modo è impossibile per chiunque altro cancellarlo, rinominarlo o modificarlo. Nel caso il processo detentore del lock venga terminato, il file resta scritto sul file system, ma la modalità esclusiva viene a mancare: ogni eventuale altro processo in attesa di rilascio del lock non avrà speranze di acquisirlo fino al prossimo riavvio di GEC_Scan che causa la pulizia dei file residui di vecchie esecuzioni. 3.3.3 Identificativi di richieste e risposte Richieste e risposte vengono scambiate tramite dei file di estensione .IN e .OUT, diversi dal file di lock ma residenti nel suo stesso file system. Questi file hanno sempre il nome costituito da dodici cifre ed un trattino orizzontale, che rappresenta il JobId del lavoro in questione. Un JobId è stato definito come l’identificativo univoco all’interno di un file system, utilizzato per identificare univocamente richieste e ri- sposte. Esso viene generato a partire dalla data-ora della sua creazione; nell’implementazione C# è in realtà un oggetto che conserva come stato interno un timestamp, e permette di ricavare da questo una rappresenta- zione stringa nel formato yyyyMMdd-hhmmss dove “y” sono le quattro cifre corrispondenti all’anno, “M” quelle corrispondenti al mese, “d” al giorno, “h” all’ora, “m” ai minuti e “s” ai secondi. Per creare un JobId valido (avendo certezza della sua univocità per un determinato file system) ed associarlo ad una richiesta si effettua la seguente procedura: • si acquisisce il lock ; • si crea a partire da data e ora correnti la stringa yyyyMMdd-hhmmss; • si usa la stringa come nome file, considerando che l’estensione per una richiesta dev’essere .IN;
  • 30. 24 3. SyncUtils • se tale nome file esiste già, si incrementa di uno il numero indi- viduato graficamente da yyyyMMddhhmmss e si torna al punto precedente (senza preoccuparsi del fatto che il numero corrisponda ancora ad una data-ora valida; es: 800419170261 non corrisponde ad una data-ora valida, ma è comunque valido come base per creare un JobId); • si crea il file; • si scrive una richiesta valida nel file; • si rilascia il lock. Una risposta ad una richiesta ha il suo stesso nome file ma con estensione .OUT; i file di richiesta e di risposta, contengono dati in formato che vedremo in seguito (vedi 3.3.6 nella pagina 28). Spesso una risposta fornisce anche un certo quantitativo di dati— nel nostro caso, ad esempio le immagini catturate: formato e ubicazione di questi dati sono indipendenti dal sistema di comunicazione, e deter- minati dai singoli plug in che gestiscono l’archiviazione (vedi 5.2 nella pagina 76), ma vengono comunque specificati in apposite sezioni nel file .OUT. 3.3.4 Protocollo Di seguito vengono riportate in pseudo codice alcune delle procedure che costituiscono il protocollo di comunicazione3 . Le procedure con prefisso GEC sono eseguite su iniziativa di GEC sulla macchina ove questo è in esecuzione, mentre quelle con prefisso SCAN si riferiscono al software di scansione GEC_Scan. FS sta per file system. L’indice i riferisce il prefisso al file system i-esimo. “Lavoro” o “Job” è il termine generico per indicare una richiesta, solitamente coincidente con la richiesta di inizio sessione di acquisizione. 3 Protocollo studiato dal prof. Alberto Bartoli con l’aiuto della documentazione prodotta dall’ing. Giorgio Davanzo; implementazione pratica in C#, sostituzione dell’active poll con sistemi di notifica e cura di dettagli tecnici pratici a cura di Giancarlo Todone.
  • 31. Dettagli implementativi e tecnologie 25 Algorithm 3.1 Lock-CleanUp: Da eseguire all’avvio di GEC_Scan. 1: if EXISTS(lockfile-i) then 2: TIMEOUT = 10sec 3: BeginWait = now() 4: while now() BeginWait + TIMEOUT do 5: if NOT EXISTS(lockfile-i) then 6: break; 7: end if 8: end while 9: DELETE lockfile-i 10: end if Algorithm 3.2 GEC-RequestJob: Da eseguire per richiedere un lavoro. 1: GET lock-i 2: GET NEW JobId-i 3: RELEASE lock-i Algorithm 3.3 GEC-Abort: Da eseguire per annullare una richiesta di lavoro pendente su iniziativa di GEC, dato il suo JobId. 1: GET lock-i 2: DELETE request-file (filename = JobId.IN) in FS-i 3: RELEASE lock-i Algorithm 3.4 SCAN-CleanUp: Da eseguire all’avvio del programma di scansione; FS-i viene riportato nello stato iniziale. Per semplicità, non si cerca di recuperare eventuali lavori effettuati nella incarnazione precedente ma non completati. 1: EXEC Lock-CleanUp 2: GET lock-i 3: DELETE ALL response, data, request files (in quest’ordine) 4: RELEASE lock-i
  • 32. 26 3. SyncUtils Algorithm 3.5 SCAN-Abort: Da eseguire per annullare (su iniziativa del software di acquisizione) una richiesta di lavoro pendente, dato il suo JobId. 1: GET lock-i 2: GENERATE EMPTY response-file (name = JobId.OUT) in FS-i 3: RELEASE lock-i Algorithm 3.6 SCAN-CompleteJob Da usarsi per segnalare il completamento (andato a buon fine o meno) di una richiesta di lavoro. 1: GET lock-i 2: if EXISTS(Input) then 3: CREATE data-files in FS-i 4: CREATE Output-file in FS-i 5: else 6: DISMISS data 7: end if 8: RELEASE lock-i In pratica: • Per effettuare una richiesta, il GEC deve: acquisire il lock; calcolare un JobId valido; scrivere un file {JobId}.IN contenente la richiesta nel corretto formato; rilasciare il lock; restare in attesa che venga scritto nella stessa posizione un file con lo stesso nome ma estensione .OUT. • Per recepire la richiesta ed effettuare una risposta, il GEC_Scan deve: restare in attesa finché sul file system predefinito non viene creato un file con nome corrispondente ad un JobId valido ed estensione .IN;
  • 33. Dettagli implementativi e tecnologie 27 acquisire il lock; leggere il contenuto del file di richiesta; rilasciare il lock ; elaborare la richiesta; acquisire il lock ; scrivere il file .OUT; rilasciare il lock. Come si può notare dall’ultima esemplificazione, l’elaborazione viene fatta da GEC_Scan mentre il lock non è mantenuto, per permette- re che altre comunicazioni avvengano mentre è in atto un processo di archiviazione molto lungo. Inoltre è visibile che se GEC_Scan notasse la presenza del file di richiesta e tentasse di leggerlo prima che il GEC abbia finito di scriverlo, non vi riuscirebbe semplicemente perché prima dovrebbe acquisire il lock ancora detenuto dalla controparte. Un analogo ragionamento si può fare per il file di risposta. Se questo tipo di meccanismo da un lato permette una corretta evolu- zione delle dinamiche di comunicazione, dall’altro introduce anche delle situazioni in cui i processi comunicanti si intralciano a vicenda, spre- cando delle risorse; per questo motivo nell’implementazione reale degli algoritmi di comunicazione si sono previsti dei piccoli ritardi program- mabili, impostati poi a valori dedotti in modo sperimentale. Questi non alterano in alcun modo la logica della comunicazione, ma minimizzano i tempi di attesa attiva di ciascuna parte. 3.3.5 Problematiche delle notifiche Inizialmente si erano concepite ulteriori due procedure: SCAN-CheckForRequests con la quale il software di acquisizione controllava l’eventuale arrivo di nuove richieste; GEC-CheckJobCompleted che si occupava di controllare—dal lato di GEC—se una richiesta fatta in precedenza non fosse stata soddisfatta.
  • 34. 28 3. SyncUtils Le due funzioni utilizzavano la tecnica dell’active poll, interrogando di continuo il file system sulla presenza o meno di determinati file. Consi- derato che questo caricava notevolmente i file system (e in minor parte anche la rete, in caso di sistema acceduto da remoto) si è provveduto a modificare il meccanismo in modo da utilizzare strumenti chiamati FileSystemWatcher [9]. Questi consistono fondamentalmente in hook 4 di sistema alle funzioni di base di accesso al disco, che sollevano un evento quando si presentano determinate condizioni, come il tentativo da parte di un programma di scrivere un nuovo file in una cartella. Purtroppo, come rilevato anche da una nutrita schiera di utenti5 , il codice che implementa questa tecnica a volte ha dei comportamenti inattesi quando eseguito in ambiente Microsoft Windows 2003 Server. All’epoca della prima stesura del programma non erano disponibili dei work around efficaci o soluzioni pubbliche: si è stati costretti a svi- luppare una soluzione alternativa poi segnalata sulla pagina ufficiale di bug report6 . La soluzione consiste nel sopperire ai comportamenti inattesi con de- gli snapshot della cartella ove avvengono gli scambi dei file: se tutto funziona come da specifiche Microsoft, l’esecuzione procede normalmen- te e le operazioni sul file system generano le notifiche attese; se invece qualcosa dovesse andare male, viene richiamato un gestore d’errore con del codice d’emergenza che confrontando il sotto albero della cartella al momento dell’errore con quello stimato durante le esecuzioni corrette, lo aggiorna e genera le notifiche di conseguenza. 3.3.6 Formati dei file di comunicazione Il formato interno dei file di comunicazione si basa su XML. Una richiesta tipo, contenuto di un file .IN si presenta come nel listato 3.1. 4 Tecnica di intercettazione e modifica al volo di dati comunicati tra funzioni di sistema; può essere “installato” in una catena di messaggi o in mezzo ad una serie di chiamate a routine [10, 13]. 5 https://connect.microsoft.com/VisualStudio/feedback/ ViewFeedback.aspx?FeedbackID=337917 6 https://connect.microsoft.com/VisualStudio/feedback/ Workaround.aspx?FeedbackID=337917
  • 35. Dettagli implementativi e tecnologie 29 Listing 3.1: Esempio di XML generato da SyncUtils per effettuare una richiesta. 1 Request 2 ActionRequest xmlns:xsi=http://www.w3.org/2001/ XMLSchema-instance xmlns:xsd=http://www.w3.org /2001/XMLSchema xsi:type=SaveToFileActionRequest ARQID=0 3 Performer name=SaveToFileActionPerformer / 4 RequiredFileFormatpng/RequiredFileFormat 5 Pathc:lockpath/Path 6 /ActionRequest 7 AdditionalData xmlns:xsi=http://www.w3.org/2001/ XMLSchema-instance xmlns:xsd=http://www.w3.org /2001/XMLSchema 8 OwnerID64/OwnerID 9 CustomerIDmyCustomerID/CustomerID 10 /AdditionalData 11 Timestamp2009-02-25T16:59:48.375+01:00/Timestamp 12 /Request Il codice XML viene generato semi automaticamente per serializza- zione di oggetti (vedi 3.3.7 nella pagina 32), quindi in questo frangente, con un nome ci si potrà riferire indistintamente al tag o alla classe che lo ha generato. In 3.2 nella pagina 16 parlando della struttura del sistema di comu- nicazione, è stato detto che Request e Response reali contengono solo tipi specializzati di ActionRequest, ActionResponse ecc. . . Nel listato di esempio è immediato però notare che i nomi dei tag di alcune entità derivabili sono dati da quelli delle loro classi base; questo fa parte del meccanismo di serializzazione: il nome della classe specializzata è contenuto in questi casi dall’attributo xsi:type. Non si fa affidamen- to a xsi:type per la corretta serializzazione del campo Performer che contiene semplicemente il nome della classe preposta a gestire la ActionRequest che lo contiene. In 3.2 nella pagina seguente si può osservare un esempio di risposta, contenuto nel file .OUT corrispondente ad un file .IN di richiesta.
  • 36. 30 3. SyncUtils Listing 3.2: Esempio di XML generato da SyncUtils per effettuare una risposta. 1 Response xmlns:xsi=http://www.w3.org/2001/XMLSchema- instance xmlns:xsd=http://www.w3.org/2001/XMLSchema 2 Documents 3 Document GID=0 4 Pages 5 Page PID=0 / 6 Page PID=1 / 7 Page PID=2 / 8 /Pages 9 ActionResponses 10 ActionResponse xsi:type= SaveToFileActionResponse ARSID=0 Request= 0 11 Errors / 12 Pages 13 ResponsePage xsi:type=FSPage Page=0 Format=png FileName=fileName1 / 14 ResponsePage xsi:type=FSPage Page=1 Format=png FileName=fileName2 / 15 ResponsePage xsi:type=FSPage Page=2 Format=png FileName=fileName3 / 16 /Pages 17 Pathc:lockpath/Path 18 /ActionResponse 19 /ActionResponses 20 /Document 21 /Documents 22 Errors 23 Error IsCrytical=true EID=0 24 Test error message 2 ! 25 /Error 26 /Errors 27 Timestamp2009-02-27T23:14:52.640625+01:00/Timestamp 28 /Response Si possono notare gli attributi PID, GID, EID ecc. . . che fungono
  • 37. Dettagli implementativi e tecnologie 31 da identificatori univoci per l’entità cui appartengono all’interno del loro contenitore; in figura 3.2 nella pagina 17 le frecce indicano che l’oggetto da cui partono conserva un identificativo dell’oggetto punta- to, cui si riferiscono logicamente, come una ActionResponse indica l’ActionRequest da cui è originata. Il meccanismo di distribuzione degli identificativi è tale che un identificativo sia univoco tra quelli degli oggetti contenuti nello stes- so contenitore (ad esempio: non ci sono ripetizioni tra gli id del- le ActionResponse in un medesimo Document, ma due id di ActionResponse in due Document distinti possono essere uguali poiché non è comunque possibile equivocare tra loro). Dal punto di vista dell’implementazione, ogni oggetto che può funge- re da contenitore per altri oggetti mantiene internamente un oggetto di tipo IdFactory per la generazione consistente e la distribuzio- ne degli identificativi; tutti gli oggetti che possono venire identificati per qualche motivo implementano l’interfaccia IHasId; tutti gli oggetti che possono fare riferimento ad un altro oggetto implementante IHasId implementano a loro volta l’interfaccia IIdPointer. È forse doveroso ribadire che normalmente per individuare precisa- mente un oggetto manterremmo semplicemente una managed reference a quest’ultimo; ma questo tipo di riferimento, nella situazione proposta è di difficile espressione durante la serializzazione XML. Listing 3.3: Riassunto dei meccanismi di distribuzione consistente degli identificativi. 1 public interface IHasId 2 { 3 int Id { get; set; } 4 } 5 6 public interface IIdPointer 7 { 8 int PointedId { get; set; } 9 void PointTo(IHasId item); 10 } 11 12 public class IdFactory 13 {
  • 38. 32 3. SyncUtils 14 int _count = 0; 15 ... 16 public virtual IHasId SetID(IHasId item) 17 { 18 item.Id = _count++; 19 return item; 20 } 21 ... 22 } 23 24 public class IdFactoryT : IdFactory where T : IHasId, new() 25 { 26 ... 27 public override IHasId SetID(IHasId item) 28 { 29 ... 30 return base.SetID(item); 31 } 32 } 3.3.7 Serializzazione XML Le tecniche di serializzazione XML in generale, e quelle utilizzate secon- do le usanze del framework dotNet in particolare, sono estremamente note in letteratura [12], ma è bene soffermarsi su certi loro aspetti per gli interessanti risvolti scaturiti durante lo sviluppo di alcune parti del software di interscambio dati. La serializzabilità di un tipo in ambito dotNet è cosa diversa dalla sua serializzabilità XML: ai nostri scopi tutti i tipi primitivi sono XM- L-serializzabili e in aggiunta—grazie all’uso della reflection—anche molti tipi complessi non espressamente pensati in ottica di serializzazione XML sono comunque XML-serializzabili. Nel package System.Xml.Serialization si trovano gli strumen- ti per effettuare serializzazione e deserializzazione di oggetti secondo due modalità che potremmo definire “esplicita” ed “implicita”:
  • 39. Dettagli implementativi e tecnologie 33 • nella modalità esplicita, gli oggetti candidati alla serializ- zazione devono implementare esplicitamente l’interfaccia IXmlSerializable, che prescrive l’implementazione di tre metodi per la serializzazione, la deserializzazione e la definizione di uno schema; • nella modalità implicita, il framework ispeziona tramite reflection le classi degli oggetti da serializzare e considerando solo campi e proprietà pubbliche genera al volo un oggetto serializzatore adatto. Nella maggior parte dei casi la modalità implicita è più che sufficiente, se si considera che è possibile istruire in certa misura il serializzatore su alcuni dettagli come nomi dei tag, tipo dei nodi ecc. . . mentre con la mo- dalità esplicita—che pur permette di risolvere problemi più complessi—è necessario scrivere molto codice, introducendo problemi di leggibilità e manutenibilità del sorgente. Solitamente si fa uso di una sola tecnica per volta, ma accade anche che le due vengano combinate, ad esempio quando si serializza un ogget- to implicitamente serializzabile che però serba in alcuni dei suoi campi oggetti esplicitamente serializzabili; ciò che accade è esemplificato nel seguente algoritmo: • se l’oggetto da serializzare è un tipo primitivo, allora è ben conosciuto: si richiama una procedura standard per la sua serializzazione e si termina la procedura; • se l’oggetto da serializzare implementa IXmlSerializable, al- lora si chiama il metodo IXmlSerializable.WriteXml() e si termina la procedura; • se l’oggetto non appartiene alle precedenti due categorie ma è comunque XML-serializzabile, allora si itera l’algoritmo su ogni campo. Analogamente per la deserializzazione. È ovvio che nel caso di un og- getto complesso con campi complessi tutti implicitamente serializzabili,
  • 40. 34 3. SyncUtils l’algoritmo itera finché non è stato analizzato l’intero albero7 ; è altresì visibile che qualora venga incontrato un oggetto IXmlSerializable, i suoi metodi WriteXml/ReadXml si occuperanno della sua intera serializzazione/deserializzazione, fermando la ricorsione dell’algoritmo summenzionato. Nello sviluppo del progetto si sono affrontati dei casi in cui ciò rappre- senta un problema: gli oggetti che gestiscono richieste e risposte utilizza- no meccanismi di serializzazione complessi, poichè gli oggetti scambiati durante una comunicazione non sempre sono ben conosciuti da entram- bi gli interlocutori; quindi questi oggetti implementano esplicitamente i meccanismi con IXmlSerializable. Nonostante ciò, per semplificare lo sviluppo futuro di ulteriori oggetti contenuti in richieste e risposte, si desidera che tali oggetti non debbano necessariamente implementare essi stessi le loro procedure di serializzazione in maniera esplicita. È stato quindi adottato un espediente: nel codice di serializzazione personalizzato di Request e Response, ogni loro campo viene serializ- zato/deserializzato istanziando di volta in volta un nuovo serializzatore, che inizia nuovamente per ogni loro campo l’algoritmo descritto in pre- cedenza; i flussi di codice XML prodotto nelle singole serializzazioni di questi oggetti vengono poi fusi col flusso principale dell’oggetto padre a posteriori (analogamente, durante la deserializzazione avviene l’estrazio- ne di porzioni di XML dal flusso principale che generano oggetti reinseriti negli appositi campi dell’oggetto padre a posteriori). Tutti i tipi conosciuti da un’esecuzione della libreria di comunicazio- ne, vengono mantenuti in un registro statico e pubblico, accessibile da ogni serializzatore; l’insieme di queste tecniche permette la serializzazio- ne/deserializzazione di tipi non noti a compile time, e la corretta gestio- ne della loro ereditarietà, mantenendo comunque semplice lo sviluppo di funzionalità aggiuntive. 7 Per semplicità e compattezza vengono taciute le problematiche di visita come ad esempio riferimenti incrociati e similari, pur esistenti ed affrontati dall’implementazione reale dell’algoritmo.
  • 41. Dettagli implementativi e tecnologie 35 3.3.8 COM COM è acronimo di Component Object Model, un’architettura che permette l’interfaccia di componenti software di varie parti senza che queste siano ricompilate in un progetto, al fine di promuoverne l’interoperabilità. Esso non è dipendente da un particolare linguaggio—ogni linguaggio che sia in grado di chiamare funzioni tramite puntatori può accedere alle sue funzionalità—e si basa sui concetti di componente ed interfaccia. Tali componenti ed interfacce sono conservati in delle DLL struttu- rate secondo un metodo prestabilito, e riferiti durante il loro utilizzo secondo un peculiare meccanismo di doppia indirezione: si mantiene il riferimento ad un componente tramite l’indice di una tabella—chiamata “vtable”—che a sua volta conserva un’indirizzo reale alla struttura dati desiderata: in questo modo le vtable possono essere condivise da più istanze di un oggetto riducendo l’utilizzo di memoria. Un componente COM somiglia in struttura a ciò che è una classe per la programmazione ad oggetti. In una gerarchia di classi, in qualsiasi contesto di programmazione esiste un ancestor, ovvero il modello di un’entità di base con un insieme minimo di caratteristiche e funzionalità di base che qualsiasi altro oggetto deve possedere; in ambito COM, si dice che tale oggetto implementa almeno l’interfaccia IUnknown. Listing 3.4: Interfaccia IUnknown come appare in C++. 1 class IUnknown 2 { 3 virtual HRESULT QueryInterface(IID iid, void** ppvObj) = 0; 4 virtual ULONG AddRef() = 0; 5 virtual ULONG Release() = 0; 6 } Questa interfaccia prescrive l’implementazione di tre metodi:
  • 42. 36 3. SyncUtils QueryInterface permette di interrogare il componente imple- mentante circa il supporto o meno di un’altra specifica interfaccia; AddRef viene chiamato per aumentare il conteggio interno degli uti- lizzatori (insieme a Release implementa un primitivo Garbage Collector); Release decrementa il conteggio interno degli utilizzatori e libera la memoria quando questo raggiunge lo 0. Un componente COM può supportare un numero qualsiasi di interfacce a partire da un minimo di una (IUnknown); le interfacce possono essere prese dal programmatore tra alcune predefinite, derivate da esse o create ex novo. Per permettere la risoluzione degli identificativi univoci che contrad- distinguono componenti ed interfacce COM a partire da nomi, tali ele- menti devono necessariamente essere registrati, cioè iscritti ad elenchi siti in determinate aree del registro di configurazione di Windows8 . La tecnologia dotNet, con il suo proprio concetto di riusabilità sta soppiantando di fatto il Component Object Model, nonostante que- st’ultimo sia stato forse una delle tecnologie più usate dal 1993 ad oggi9 . Il passaggio da una tecnologia all’altra viene reso più facile dalla prevista possibilità di interazione tra le due: questa opportunità si espli- cita con il Runtime Callable Wrapper (RCW) necessario per eseguire una chiamata a un server COM da un client dotNet, e il COM Callable Wrapper (CCW) per eseguire viceversa una chiamata a un server dotNet da client COM10 . Come suggerito dai nomi, queste due entità sono del 8 In realtà COM fu portato anche su sistemi operativi diversi da Windows e addi- rittura su macchine diverse dai PC compatibili; in questi sistemi la risoluzione degli identificativi avviene in modo analogo ma implementativamente diverso; l’uso più esteso di COM rimane quello su piattaforme Windows, dal 3.x fino alle più moderne XP, Vista e Seven. 9 Nata nel 1993, questa tecnologia è stata menzionata con enfasi da Microsoft solo a partire dal 1997. 10 Chiamiamo “client COM” una porzione di un programma in grado di utilizzare un servizio esposto da un oggetto COM; chiamiamo altresì “server COM” il componente che espone tale funzionalità.
  • 43. Dettagli implementativi e tecnologie 37 codice di contorno aggiunto automaticamente ai componenti di una del- le due metodologie di sviluppo per essere interpretati ed utilizzati anche dalla controparte tecnologica. Component RCW Consumer Unmanaged Managed Consumer CCW Class Figura 3.3: Schema di funzionamento di RCW e CCW; nella prima riga un componente dotNet richiama funzionalità da un provider COM; nella seconda, del codice capace di richiamare funzionalità COM chiama codice dotNet tramite il CCW. Nonostante ogni CCW sia generato automaticamente dal runtime dotNet, le classi da esporre come componenti COM devono venire ade- guatamente preparate; l’ambiente integrato di sviluppo Visual Studio 2008 offre degli automatismi per assolvere a questo compito, ma resta preoccupazione del programmatore decorare le classi dotNet con attributi atti ad istruire il runtime nella creazione dei CCW ad esse dedicati. Fondamentali ComVisible che abilita il processo di wrapping e ProgId che assegna il nome al componente. Eventuali altri attributi da applicare possono essere Guid, che specifica un identificativo univoco altrimenti assegnato automaticamente e DispId che specifica in maniera esplicita l’ordine in cui i metodi devono comparire in un’interfaccia11 . 11 Per la corretta compilazione del codice, se almeno un metodo di una classe è stato decorato con DispId, allora lo devono essere tutti all’interno della stessa classe.
  • 44. 38 3. SyncUtils Listing 3.5: Esempio della decorazione minima di un componente da esporre tramite COM. 1 [InterfaceTypeAttribute(ComInterfaceType. InterfaceIsIDispatch)] 2 public interface _JobId 3 { 4 string ToString(); 5 bool Equals(object value); 6 void Increment(); 7 JobId Clone(); 8 } 9 10 [ClassInterface(ClassInterfaceType.None)] 11 [ProgId(SyncUtils.JobID)] 12 [ComVisible(true)] 13 public class JobId : _JobId 14 { 15 ... 16 } Una particolare menzione meritano la gestione degli eventi e quella degli errori; mentre i secondi sono propagati automaticamente dal siste- ma semplicemente assegnando un codice d’errore ad ogni eccezione non gestita, l’utilizzo dei primi richiede del codice aggiuntivo. Proprietà di un’interfaccia C# come potrebbe essere 1 event JobCompletedDelegate OnJobCompleted; vengono viste in realtà dai client COM come una coppia di metodi per l’aggiunta e la rimozione di gestori d’evento 1 AddJobCompletedDelegate(); 2 RemoveJobCompleteDelegate(): ma per permettere ad un COM client di venire notificato da un componente, è necessario assegnare esplicitamente a quest’ultimo an- che un’interfaccia in cui si specifica il metodo da chiamare al verificarsi dell’evento; del tipo
  • 45. Dettagli implementativi e tecnologie 39 1 [InterfaceTypeAttribute(ComInterfaceType. InterfaceIsIDispatch)] 2 public interface UserEvents 3 { 4 void OnJobCompleted(JobId job, Response response); 5 ... 6 } Dal punto di vista dell’utilizzo con Visual Basic 6, l’utilizzo di un oggetto COM richiede un file che ne specifichi le funzioni presenti: tale file—di estensione .tlb—viene chiamato “type library”, ed è generato automaticamente all’atto della registrazione di un componente. Impor- tando la type library, è poi possibile cominciare ad usare qualsiasi dei tipi ivi definiti, curandosi di dichiarare con la clausola WithEvents quelli dei quali si voglia usare la capacità di sollevare eventi. Nel progetto del sistema di archiviazione proposto, le classi ad essere predisposte per l’utilizzo come componenti COM sono essenzialmente quelle riguardanti la libreria della comunicazione, e in maggior dettaglio quelle che permettono a GEC di richiedere un servizio a GEC_Scan: ClientSideFileSync; Request; Response; ActionRequest; ActionResponse; Document; DocInfo; Page; ResponsePage; Error
  • 46. 40 3. SyncUtils e classi da queste derivate. Lo sviluppatore che intendesse creare ulteriori plug in aggiuntivi dovrà curarsi che le sue classi siano accessibili a client COM per permetterne l’uso da parte di GEC. 3.4 Installazione e preparazione dell’ambiente di esecuzione Il software in tutte le sue parti è in fase di test, e non viene quindi ancora distribuito al di fuori del contesto di sviluppo. Per questo motivo non è fornito di un programma di installazione e di istruzioni user friendly, ma solo di note tecniche, la maggior parte delle quali messe insieme durante la soluzione di reali problematiche di set up, o collezione di alcuni brani rilevanti dalla documentazione e dai commenti al codice sorgente. I tre tipi di software prodotti eseguono in due ambienti eventualmente coincidenti: • il calcolatore che esegue GEC • il personal computer dove viene eseguito il software di acquisizione e i suoi plug in Per quanto riguarda il lato controllore, devono essere distribuiti assieme a GEC tutti gli assembly inerenti la libreria di comunicazione. Le seguenti DLL contenenti codice dotNet racchiuso in oggetti COM vanno copiate in una cartella apposita su un volume non rimovibile del PC e registrate nell’ordine: • CommonUtils.dll • SyncUtils.dll • SerializationSetupHelper.dll • BasicPlugins.dll • ClientSync.dll che in buona parte dipendono da (e quindi richiedono anche) SimpleLogger.dll Per la registrazione, è possibile utilizzare il comando
  • 47. Installazione e preparazione dell’ambiente di esecuzione 41 1 RegAsm.exe nomeDll residente nella cartella %WINDIR%Microsoft.NETFrameworkv2.X Come si può notare, la cartella è parte integrante del framework dotNet 2.x (dove “x” sta per qualsiasi numero), palesando che l’installazione del runtime dotNet 2.0 o superiore è un prerequisito. Da osservare anche il fatto che gli assembly preparati per essere utiliz- zati come oggetti COM hanno bisogno di un trattamento particolare, uti- lizzando per la registrazione l’apposito regasm.exe al posto dell’usuale regsvr32.exe Molte di queste librerie sono utilizzate anche dal lato del software di acquisizione: anche se questo dovesse essere installato sulla stessa macchina di GEC, le librerie non possono essere condivise. Andranno quindi replicate nella cartella dedicata solo al programma di scansione.
  • 48. 42 3. SyncUtils
  • 49. Capitolo 4 GEC_Scan 4.1 Requisiti e progetto dell’interfaccia utente Il software di acquisizione GEC_Scan dev’essere funzionalmente inte- grato con GEC. L’utente, una volta installato il sistema, non deve avere coscienza che GEC_Scan è un programma diverso da GEC ma deve essere portato a considerarlo come una sua estensione: per ottenere que- sto risultato GEC_Scan deve essere eseguito all’avvio della macchina su cui è installato e rimanere nascosto finchè non si presenti un determinato evento (come l’arrivo di una comunicazione da GEC) nel qual caso dovrà essere mostrata una schermata adatta a gestire l’evento. In questo modo, la finestra di GEC_Scan si comporterà come se fos- se un form dell’applicazione principale, lasciando trasparente all’utente tutta la gestione delle comunicazioni tra un software e l’altro. GEC_Scan deve utilizzare SyncUtils o essere compatibile con il suo metodo di comunicazione a file system condiviso: deve quindi avere ac- cesso in lettura e scrittura alla porzione del file system sul suo elaboratore che viene acceduta da GEC tramite SyncUtils. GEC_Scan deve poter accettare da GEC un numero qualsiasi di richieste di inizio sessione di acquisizione a prescindere dal suo stato di occupazione: se arrivano ulteriori richieste mentre l’utente sta operando il programma per soddisfarne una, tali richieste vanno inserite in una 43
  • 50. 44 4. GEC_Scan coda di tipo First In First Out, e vanno presentate all’utente in ordine una ogni volta che la precedente sia terminata. L’utente deve essere posto in grado di valutare la lunghezza della coda e di annullare una o tutte le richieste senza interrompere il suo lavoro corrente. A tale scopo deve essere presente un form separato da quello principale che permette di osservare in tempo reale l’occupazione della coda. GEC_Scan deve poter comunicare con il maggior numero possibile di periferiche di acquisizione come scanner, fotocamere e basi di dati; tale connettività deve però essere assolutamente trasparente, cioè: il com- portamento e l’apparenza grafica del programma devono essere sempre uguali e garantire un’esperienza di utilizzo consistente qualsiasi sia la sorgente di dati scelta. Le immagini acquisite singolarmente o in gruppi, devono essere presentate tramite piccole anteprime che permettano quantomeno di identificare in linea di massima ogni documento. Non ci deve essere un limite—se non quello fisico della macchina di esecuzione—al numero di immagini acquisibili e gestibili: allo sco- po di facilitare la gestione delle immagini (operazioni di ispezione, se- lezione, riordino, rotazione) il programma deve essere provvisto di un visualizzatore integrato, che permetta di ingrandire le piccole anteprime e presentare le immagini a più alta risoluzione a vari livelli di zoom. 4.1.1 Interfaccia grafica e usabilità Normalmente il programma di acquisizione documenti viene eseguito al- l’avvio del sistema dell’utente, ma la maggior parte delle sue funziona- lità è preclusa finché GEC—a seguito di un’operazione dell’utente—non inizia una sessione; per l’utente è tuttavia sempre possibile accedere tra- mite icona nella barra dell’orologio ad un menu di opzioni che permette di impostare: • il dispositivo da utilizzare tra una lista di scanner, fotocamere ed altre sorgenti TWAIN disponibili sul sistema;
  • 51. Requisiti e progetto dell’interfaccia utente 45 Figura 4.1: Finestra di opzioni del programma di acquisizione. • la risoluzione (impostata alla prima esecuzione sulla risoluzio- ne disponibile più vicina—possibilmente per eccesso—a 300 dpi, risoluzione richiesta dalla maggior parte dei software OCR); • modalità di colore (impostata alla prima esecuzione sulla modalità più semplice che si avvicini a RGB); • orientamento pagine (impostato alla prima esecuzione a 0º); • utilizzo dell’alimentatore automatico fogli (se disponibile, imposta- to a vero alla prima esecuzione); • utilizzo della scansione automatica fronte e retro (inizialmente falso); • utilizzo dell’eliminazione automatica pagine vuote (inizialmente falso); • utilizzo della rotazione automatica pagine (inizialmente falso);
  • 52. 46 4. GEC_Scan • utilizzo del rilevamento automatico delle dimensioni di una pagina (se disponibile inizialmente vero); Ogni controllo di impostazione risulta operabile se pertinente, e non presente o disegnato in grigio se non disponibile o non applicabile. Ogni impostazione si riferisce al dispositivo correntemente seleziona- to: scegliere un’altra periferica causerà l’adattamento dei parametri alle capacità della nuova sorgente scelta. Alla chiusura della finestra delle preferenze, queste vengono rese ufficiali e salvate su disco. Figura 4.2: Schermata principale del programma di acquisizione. Quando l’utente effettua in GEC un’operazione che causa l’inizio di una sessione di acquisizione, la schermata principale del programma di scansione compare in primo piano. Tramite il tasto “Acquisisci” si inizia la scansione dalla periferica sele- zionata di una o più pagine dipendentemente dalle preferenze impostate: eventuali operazioni lunghe comporteranno la comparsa di un indicato- re di avanzamento che consente anche di interrompere le operazioni in corso. Ad esempio, un’operazione di acquisizione molto lunga potrebbe pre- sentarsi nel caso in cui si sia scelto di scansionare molti documenti con
  • 53. Requisiti e progetto dell’interfaccia utente 47 un trascinatore automatico, oppure nel caso si sia scelto di utilizzare una risoluzione molto alta. Una volta raccolte delle immagini, queste compaiono sotto forma di icone sullo sfondo grigio della finestra principale: passandoci sopra con il puntatore esse si ingrandiscono per permettere di comprendere meglio di che pagina si tratta e per consentire all’operatore di capire qual è il foglio correntemente puntato. Aumentando le dimensioni della finestra, aumentano anche quelle delle icone delle pagine. Facendo doppio click su un’immagine, questa viene mostrata in una finestra di anteprima, nella quale è possibile effettuare zoom (operando la rotella del mouse o i tasti + e -) sulle sue varie parti a fini di ispezione. Tenendo premuto il tasto sinistro del mouse e trascinando, l’imma- gine puntata viene rimossa dalla sua sede per consentire di posizionarla in altra locazione: rilasciando il tasto sinistro, essa verrà inserita su- bito prima dell’immagine correntemente sotto il puntatore (locazione evidenziata da una barra nera sfumata). Una barra di posizionamento compare al di sotto delle immagi- ni quando queste sono troppe per essere contenute in una sola scher- mata: sia quando si scorrono semplicemente le immagini, sia duran- te le operazioni di trascinamento, avvicinandosi al bordo sinistro o de- stro il programma effettua automaticamente una carrellata—tanto più velocemente quanto più si è vicini al bordo. Tenendo premuto il tasto sinistro del mouse sull’area recante la di- citura “inserisci separatore” e trascinando, viene creato un elemento se- paratore (delle sembianze di una barra nera verticale) che è possibile rilasciare tra due immagini secondo le modalità già viste: anche una volta rilasciato un separatore, è sempre possibile riprenderlo e spostarlo come una immagine qualsiasi. Verrà considerato “documento” o “gruppo” l’insieme delle pagine con- tenute fra due separatori (o tra un separatore e l’inizio/fine della lista): il programma può essere forzato da GEC a richiedere un numero mini- mo e un numero massimo di gruppi di pagine: è possibile sapere quali sono i vincoli lasciando il puntatore sull’area di inserzione separatore e aspettando la comparsa di un fumetto contenente tali informazioni. Facendo click destro su un’immagine o un separatore, appare un menu contestuale con diverse opzioni auto esplicative:
  • 54. 48 4. GEC_Scan • ruota in senso orario; • ruota in senso antiorario; • elimina. La pressione del tasto “cancella immagini” causa la cancellazione di tutte le immagini acquisite. Una volta catturate, riordinate e divise le pagine è possibile annullare tutto il lavoro o proseguire con l’archiviazione dei dati; la differenza tra “cancella immagini” e “scarta” consiste proprio nel fatto che il primo co- mando lascia la finestra aperta per effettuare ulteriori operazioni, mentre il secondo chiude e manda contestualmente a GEC un messaggio di er- rore comunicandogli che non è stato possibile completare correttamente il lavoro per annullamento da parte dell’utente. Se nel frattempo erano pervenute altre richieste di inizio sessione (es: l’utente ha effettuato altre operazioni su GEC che hanno originato altre richieste), il programma lo palesa restando in attesa di istruzioni, altrimenti torna nel suo stato quiescente. In ogni momento è possibile controllare e gestire lo stato della coda di richieste tramite l’apposita finestra, richiamabile dalla tray icon. Figura 4.3: Finestra di gestione della coda in caso di richieste multiple.
  • 55. Composizione di GEC_Scan 49 Infine, chiudendo semplicemente la finestra principale (con la classi- ca “x” in alto a destra) o tramite il tasto “Nascondi” senza scegliere di memorizzare o scartare il materiale raccolto, si sospende la sessione di lavoro nascondendo la finestra, recuperabile (senza perdere alcun dato) tramite icona nella barra dell’orologio. 4.2 Composizione di GEC_Scan Plug in Servizi Plug in manager esterni Plug in codice principale SyncUtils File System GEC dotNetTwain TWAIN Periferiche VisualSlideShow WinForms e interfaccia Utente GDI grafica GEC_Scan Figura 4.4: Composizione di GEC_Scan e sue relazioni con tecnologie ed altre parti del progetto. In figura 4.4, si può osservare l’architettura di GEC_Scan e le sue