Ai miei sponsor ufficiali

Transcript

Ai miei sponsor ufficiali
Ai miei sponsor ufficiali . . .
Il Talento non va sprecato
(Robert De Niro in “Bronx”)
Indice
Introduzione
1
1 Documentazione automatica
1.1
13
L’importanza della documentazione automatica . . . . . . . . 13
1.1.1
Documentare: più una croce che delizia . . . . . . . . . 14
1.1.2
Separazione della forma dal contenuto: una chiave di
svolta . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.2
Javadoc e la documentazione automatica su Java . . . . . . . 25
1.3
Generatori automatici di documentazione su altri linguaggi:
cosa è stato realizzato
1.3.1
. . . . . . . . . . . . . . . . . . . . . . 29
Literate programming, accenni di programmazione letteraria . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
1.3.2
DDoc . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
1.3.3
Doxygen . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1.3.4
HeaderDoc . . . . . . . . . . . . . . . . . . . . . . . . . 32
1.3.5
NaturalDocs . . . . . . . . . . . . . . . . . . . . . . . . 33
1.3.6
PHPDoc e phpDocumentor . . . . . . . . . . . . . . . 34
1.3.7
ROBODoc: un documentatore universale . . . . . . . . 35
2 Documentazione e i linguaggi di validazione XML
2.1
37
XML e alcuni linguaggi di validazione . . . . . . . . . . . . . . 37
2.1.1
DTD . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.1.2
XML Schema . . . . . . . . . . . . . . . . . . . . . . . 40
2.1.3
RELAX NG . . . . . . . . . . . . . . . . . . . . . . . . 41
i
INDICE
2.2
INDICE
2.1.4
Schematron . . . . . . . . . . . . . . . . . . . . . . . . 42
2.1.5
DTD++ . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Documentare un linguaggio di validazione XML: verso un nuovo approccio . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
2.2.1
Un approccio XSL per documentare XML Schema . . . 44
2.2.2
Un buon compromesso sulla validazione XML . . . . . 47
2.2.3
Un’estensione javadoc per DTD++ . . . . . . . . . . . 49
3 Una sintassi per documentare DTD++
3.1
3.2
3.3
51
Il convertitore DTD++: il PreValidator . . . . . . . . . . . . . 51
3.1.1
Introduzione . . . . . . . . . . . . . . . . . . . . . . . . 51
3.1.2
Caratteristiche principali . . . . . . . . . . . . . . . . . 52
3.1.3
Novità con la nuova versione . . . . . . . . . . . . . . . 54
Sintassi di DTD++ . . . . . . . . . . . . . . . . . . . . . . . . 54
3.2.1
I tipi . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.2.2
Derivazione dei tipi semplici . . . . . . . . . . . . . . . 57
3.2.3
Derivazione dei tipi complessi . . . . . . . . . . . . . . 61
3.2.4
Componenti locali e globali . . . . . . . . . . . . . . . 62
3.2.5
Elemento radice . . . . . . . . . . . . . . . . . . . . . . 64
3.2.6
Element e Attribute Groups . . . . . . . . . . . . . . . 65
3.2.7
Substitution Group . . . . . . . . . . . . . . . . . . . . 67
DppDoc: Una sintassi Javadoc-style . . . . . . . . . . . . . . . 68
3.3.1
Contesto e contenuto: i parametri dppDoc . . . . . . . 69
4 Dettagli implementativi
75
4.1
Flusso del programma . . . . . . . . . . . . . . . . . . . . . . 75
4.2
Tecnologie utilizzate . . . . . . . . . . . . . . . . . . . . . . . 76
4.3
Il programma . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
4.3.1
Il default package: preValidator . . . . . . . . . . . . . 79
4.3.2
preValidator.documents . . . . . . . . . . . . . . . . . 80
4.3.3
preValidator.types . . . . . . . . . . . . . . . . . . . . 81
4.3.4
preValidator.errors . . . . . . . . . . . . . . . . . . . . 82
INDICE
4.4
4.5
iii
4.3.5
preValidator.parsers
. . . . . . . . . . . . . . . . . . . 83
4.3.6
preValidator.utils . . . . . . . . . . . . . . . . . . . . . 84
Il package “motore”: preValidator.parseStruct . . . . . . . . . 85
4.4.1
Caratteristiche delle classi . . . . . . . . . . . . . . . . 85
4.4.2
Gestione dei whitespace e dei componenti astratti . . . 93
4.4.3
La classe DppDoc . . . . . . . . . . . . . . . . . . . . . 94
4.4.4
Caratteristiche principali . . . . . . . . . . . . . . . . . 95
4.4.5
Fasi di elaborazione di un header DppDoc . . . . . . . 97
Utilizzo e installazione . . . . . . . . . . . . . . . . . . . . . . 98
4.5.1
Utilizzo . . . . . . . . . . . . . . . . . . . . . . . . . . 98
4.5.2
Installazione . . . . . . . . . . . . . . . . . . . . . . . . 102
Conclusioni
103
A “ROBODoc per Dppdoc”:Il gregario di DppDoc
107
A.1 Caratteristiche principali . . . . . . . . . . . . . . . . . . . . . 108
A.2 Tre concetti chiave: header, blocco e sezione . . . . . . . . . . 109
A.2.1 Headers e blocchi . . . . . . . . . . . . . . . . . . . . . 109
A.2.2 Sezioni e headertype . . . . . . . . . . . . . . . . . . . 111
A.3 Estrarre la documentazione con ROBODoc . . . . . . . . . . . 112
A.3.1 Documentazione online: multidoc . . . . . . . . . . . . 113
A.3.2 Documentazione standalone: singledoc . . . . . . . . . 113
A.3.3 I formati d’output
. . . . . . . . . . . . . . . . . . . . 113
A.4 Un header per DppDoc . . . . . . . . . . . . . . . . . . . . . . 114
Bibliografia
123
Elenco delle figure
1.1
Un esempio di template PDL . . . . . . . . . . . . . . . . . . 16
1.2
Esempio di inserimento interattivo dei commenti tramite RNDOC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.3
Il risultato dato in output da RNDOC . . . . . . . . . . . . . 18
1.4
Report generato dal PSA che mostra le interrelazioni tra i dati
e i processi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.5
Report generato dal TG/TF2 secondo le specifiche dello standard Navy Procurement . . . . . . . . . . . . . . . . . . . . . 22
1.6
Diagramma che illustra l’idea del framework teorizzato da
Jeffrey Kurn e Scott McGregor . . . . . . . . . . . . . . . . . 23
1.7
API Specification Java 1.4.2 generate con Javadoc e le Doclets
standard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.8
Esempio di commento Javadoc . . . . . . . . . . . . . . . . . . 29
1.9
Esempio di commento DDoc . . . . . . . . . . . . . . . . . . . 31
1.10 Esempio di commento Doxygen . . . . . . . . . . . . . . . . . 32
1.11 Esempio di commento NaturalDocs . . . . . . . . . . . . . . . 33
1.12 Esempio di commento DocBlock . . . . . . . . . . . . . . . . . 34
2.1
Sistema di trasformazione di documenti XML tramite i fogli
di stile XSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
2.2
Sistema di generazione automatica della documentazione in
html di un documento XML-Schema tramite Xnsdoc . . . . . 47
2.3
Un esempio di documentazione generata con xnsdoc . . . . . . 48
v
vi
ELENCO DELLE FIGURE
3.1
Esempio di commento DppDoc su DTD++ e la relativa proiezione in HTML . . . . . . . . . . . . . . . . . . . . . . . . . 71
3.2
Due esempi di documentazione DppDoc in formato HTML . . 73
Elenco delle tabelle
1.1
Alcune variabili utilizzabili nei commenti Javadoc . . . . . . . 28
3.1
Tipo semplice . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.2
Tipo complesso . . . . . . . . . . . . . . . . . . . . . . . . . . 57
3.3
Derivazione per restrizione . . . . . . . . . . . . . . . . . . . . 58
3.4
Derivazione per lista . . . . . . . . . . . . . . . . . . . . . . . 59
3.5
Derivazione per unione . . . . . . . . . . . . . . . . . . . . . . 60
3.6
Derivazione per restrizione . . . . . . . . . . . . . . . . . . . . 61
3.7
Derivazione per estensione . . . . . . . . . . . . . . . . . . . . 62
3.8
Componenti locali . . . . . . . . . . . . . . . . . . . . . . . . . 63
3.9
Componenti globali . . . . . . . . . . . . . . . . . . . . . . . . 64
3.10 Elemento radice . . . . . . . . . . . . . . . . . . . . . . . . . . 65
3.11 Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
3.12 Attribute group . . . . . . . . . . . . . . . . . . . . . . . . . . 66
3.13 Substitution Group . . . . . . . . . . . . . . . . . . . . . . . . 67
3.14 Struttura sintattica del commento dppdoc . . . . . . . . . . . 70
3.15 i parametri informativi . . . . . . . . . . . . . . . . . . . . . . 72
3.16 i parametri sul tag . . . . . . . . . . . . . . . . . . . . . . . . 72
A.1 Headertype predefiniti riconosciuti da ROBODoc . . . . . . . 112
vii
Introduzione
Lo scopo di questa tesi è valutare l’utilità nell’applicare tecniche di literate programming all’interno del linguaggio di validazione DTD++ al fine di
automatizzare la produzione di documentazione su vocabolari XML.
Literate programming è una metodologia di programmazione che combina un linguaggio di programmazione con un linguaggio di documentazione.
L’intento è quello di realizzare programmi che abbiano un supporto documentativo tale che sia consultabile e facilmente comprensibile per qualsiasi
tipo di utente. In particolare, l’obiettivo di questa tesi, è quello di valutare
l’utilità nell’applicare opportune tecniche di programmazione letteraria per
definire un insieme di regole sintattiche affinchè sia possibile documentare un
vocabolario XML tramite il linguaggio di validazione DTD++.
XML è un metalinguaggio di markup, cioè un linguaggio che permette di
definire altri linguaggi di markup. A differenza di HTML, XML non ha tag
predefiniti e non serve per definire pagine Web nè per programmare. Esso
serve esclusivamente per definire altri linguaggi. In realtà, XML di per sè
non è altro che un insieme di regole sintattiche standard per modellare la
struttura di documenti e dati. Questo insieme di regole, dette più propriamente specifiche, definiscono le modalità secondo cui è possibile crearsi un
proprio linguaggio di markup.
XML richiede un certo rigore sugli aspetti sintattici: tutti i documenti XML
devono essere ben formati (well formed). Questo concetto è assimilabile in
qualche modo alla correttezza ortografica di una lingua ed è un principio a
1
2
INTRODUZIONE
cui i documenti XML non possono sottrarsi.
Un documento XML affinchè sia ben formato deve rispettare le seguenti
regole [CA06]:
• Ogni documento XML deve contenere un unico elemento di massimo livello (root) che contenga tutti gli altri elementi del documento. Le sole parti di XML che possono stare all’esterno di questo elemento sono i commenti e le direttive di elaborazione (per esempio, la
dichiarazione della versione di XML)
• Ogni elemento deve avere un tag di chiusura o, se vuoti, possono
prevedere la forma abbreviata (/>)
• Gli elementi devono essere opportunamente nidificati, cioè i tag di
chiusura devono seguire l’ordine inverso dei rispettivi tag di apertura
• XML fa distinzione tra maiuscole e minuscole, per cui i nomi dei
tag e degli attributi devono coincidere nei tag di apertura e chiusura
anche in relazione a questo aspetto.
• I valori degli attributi devono sempre essere racchiusi tra singoli o doppi
apici
La violazione di una qualsiasi di queste regole fa in modo che il documento
risultante non venga considerato ben formato. Anche se queste regole possono sembrare semplici, occorre prestarvi molta attenzione.
Per quanto riguarda il contenuto, un documento XML può contenere potenzialmente qualsiasi carattere dell’alfabeto latino, cifre e punteggiatura.
Normalmente vengono accettati come caratteri validi in un documento XML
i primi 128 caratteri della codifica ASCII (lettere dell’alfabeto latino minuscole maiuscole, cifre, segni di punteggiatura ecc. . . ).
Se un documento contiene caratteri che non rientrano tra questi (es. lettere accentate, simboli di valuta, ecc. . . ) è necessario specificare lo schema
di codifica utilizzato. Lo schema di codifica ed altre informazioni dirette
INTRODUZIONE
al software incaricato di elaborare il documento XML sono indicate tramite
elementi speciali detti direttive di elaborazione o processing instruction:
<?xml version=’’1.0’’ encoding=’’iso-8859-1’’ ?>
abilita l’uso del set di caratteri noto come Latin 1 contenente le lettere accentate e altri simboli.
Le specifiche di XML prevedono esplicitamente la possibilità di utilizzare
Unicode per rappresentare anche caratteri non latini come ad esempio i caratteri greci, cirillici, gli ideogrammi cinesi e giapponesi.
Oltre alle direttive di elaborazione, in un documento XML possiamo trovare i commenti, cioè informazioni rivolte agli esseri umani ed ignorate dai
software che lo elaborano. I commenti XML seguono la stessa sintassi dell’HTML, sono cioè racchiusi tra le sequenze di caratteri <!-- ... --> e
possono trovarsi in un qualsiasi punto del documento.
XML offre quindi la libertà di definire i tag a seconda delle necessità, ma
perchè non si generi confusione è necessario un meccanismo che ne vincoli
l’utilizzo all’interno dei documenti. Questo meccanismo è definito da una
grammatica per il linguaggio di markup che si è ideato. Una grammatica
è un insieme di regole che indica quali vocaboli (elementi) possono essere
utilizzati e con che struttura è possibile comporre frasi (documenti). Se un
documento XML rispetta le regole definite da una grammatica è detto valido per un particolare linguaggio.
La caratteristica di un documento valido si affianca a quella di un documento
ben formato per costruire documenti XML adatti ad essere elaborati automaticamente.
C’è da sottolineare che un documento ben formato può non essere valido
rispetto ad una grammatica, mentre un documento valido è necessariamente
ben formato. Tra l’altro, un documento valido per una grammatica può non
essere valido per un’altra grammatica.
Un documento XML può essere all’origine di diversi tipi di elaborazione:
generazione di altri documenti, eventualmente in formati diversi, controllo
3
4
INTRODUZIONE
delle impostazioni di programmi, rappresentazione di immagini, ecc. . .
Tutti i possibili impieghi di XML, però, si fondano su due tipi di elaborazione
preliminare: la verifica che un documento sia ben formato e la sua validità
rispetto ad una grammatica.
I software che si occupano di queste elaborazioni sono detti parser e sono degli strumenti standard disponibili per diverse piattaforme. Si possono
suddividere i parser in due categorie:
• parser non validante è un parser che verifica soltanto se un documento è ben formato
• parser validante è un parser che, oltre a verificare che un documento
è ben formato, verifica se è corretto rispetto ad una data grammatica
Per la validazione di un documento XML tramite codice è possibile utilizzare diverse librerie. Tra le più note sono MSXML (componente di internet
explorer, quindi presente su tutte le macchine che hanno installato questo
browser), Xerces [Xerces06] e XML4J [XML4J98]. Attualmente esistono due
approcci standard per la creazione di grammatiche per documenti XML:
DTD (Document Type Definition) e XML Schema.
Da un punto di vista cronologico, il primo approccio per la definizione
di grammatiche per documenti XML è rappresentato dai Document Type
Definition (DTD). Un DTD è un documento che descrive i tag utilizzabili in
un documento XML, la loro reciproca relazione nei confronti della struttura
del documento e altre informazioni sugli attributi di ciascun tag.
La sintassi DTD si basa principalmente sulla presenza di due dichiarazioni:
<!ELEMENT> e <!ATTLIST>. La prima definisce gli elementi utilizzabili nel
documento e la struttura del documento stesso, la seconda definisce la lista
di attributi per ciascun elemento.
Ad esempio
<!ELEMENT articolo(paragrafo+)>
INTRODUZIONE
indica che l’elemento articolo ha come sottoelemento uno o più elementi di
paragrafo. Il carattere “+” indica il relativo numero di occorrenze.
Un insieme di caratteri speciali ha lo scopo di indicare il numero di occorrenze di un elemento:
• “+” indica che l’elemento è presente una o più volte
• “*” indica che l’elemento è presente zero o più volte
• “?” indica che l’elemento è presente zero o una sola volta
Ci sono inoltre altri identificatori per distinguere il caso di tag vuoti (EMPTY) da quelli che racchiudono testo (#PCDATA) oppure da quelli su cui
non è definito a priori il tipo di contenuto (ANY).
Per la definizione degli attributi di ciascun tag si fa uso della dichiarazione
<!ATTLIST>:
<!ATTLIST articolo titolo CDATA #REQUIRED>
Il valore CDATA indica una qualsiasi combinazione di caratteri. Inoltre le
indicazioni #REQUIRED, #IMPLIED e #FIXED segnalano se l’attributo
è obbligatorio, opzionale o fisso al valore specificato nel tag.
Tuttavia l’uso dei DTD per definire la grammatica di un linguaggio di markup non sempre è del tutto soddisfacente. Ad esempio i DTD non consentono
di specificare un tipo di dato per il valore degli attributi, né di specificare
il numero minimo o massimo di occorrenze di un tag in un documento o
altre caratteristiche che in determinati contesti consentirebbero di ottenere
un controllo ancora più accurato sulla validità di un documento XML.
Queste limitazioni hanno spinto alla definizione di approcci alternativi per
definire grammatiche per documenti XML. Il più noto è XML Schema.
Analogamente ad un DTD, un XML Schema è una descrizione formale di
una grammatica per un linguaggio di markup basato su XML, che utilizza la
5
6
INTRODUZIONE
stessa sintassi XML. Per quanto possa sembrare paradossale, questo approccio fornisce un’estrema flessibilità.
Un XML Schema ha un root element che contiene tutte le regole di definizione della grammatica ed è rappresentato dal tag <xs:schema>, che indica al
parser l’utilizzo dei tag definiti dal namespace standard del W3C [W3C04].
Un namespace rappresenta un meccanismo per identificare tag appartenenti
ad una specifica grammatica, in questo caso sono caratterizzati dal prefisso
xs:.
XML Schema prevede il tag <xs:element> per la definizione degli elementi
utilizzabili in un documento XML. All’interno di ciascun tag element è possibile indicare il tipo di dato dell’elemento che possono essere di due tipi:
semplici e complessi.
I tipi di dato semplice possono essere predefiniti (es: xs:string, xs:integer,
xs:decimal, ecc. . . ) oppure personalizzati come derivazione di quelli predefiniti, mentre i tipi di dato complessi si riferiscono ad elementi che possono
contenere altri elementi. Definire un elemento di tipo complesso corrisponde
a definire la relativa struttura utilizzando dei particolari costruttori di tipi
complessi:
• <xs:sequence> – sequenza ordinata di sottoelementi
• <xs:choice> – elenco di sottoelementi alternativi
• <xs:all> – sequenza non ordinata di sottoelementi
Per ciascuno di questi costruttori e per ciascun elemento è possibile definire
il numero di occorrenze previste utilizzando gli attributi minOccurs e maxOccurs.
La definizione della struttura di un elemento è ricorsiva, cioè contiene la
definizione di ciascun elemento che può stare all’interno della struttura stessa. Un elemento vuoto è considerato un elemento di tipo complesso il cui
contenuto non si basa su nessun tipo predefinito.
INTRODUZIONE
La definizione degli attributi è basata sull’uso del tag <xs:attribute>
come ad esempio
<xs:attribute name=’’titolo’’ type=’’xs:string’’
use=’’required’’ />
L’attributo use consente di specificare alcune caratteristiche come la presenza obbligatoria (required) o un valore predefinito (default) in combinazione
con l’attributo value.
Se una grammatica DTD può risultare poco soddisfacente nelle situazioni
in cui è necessaria un’elevata flessibilità nel definire particolari vincoli semantici, un documento XML Schema ha portato però ad un peggioramento in
termini di leggibilità a causa della eccessiva verbosità della sua grammatica.
Un equivalente documento DTD scritto in XML Schema può essere due o tre
volte più lungo e sopratutto più difficile da leggere e capire.
D’altra parte una grammatica basata su XML facilita la realizzazione di
tool che trattano, trasformano e utilizzano specifiche sotto forma di schema,
mentre far ricorso a DTD porta inevitabilmente ad essere legati ad un parser
DTD senza poter utilizzare tool più sofisticati per le applicazioni aggiuntive
dello schema.
Un buon compromesso che cerchi di racchiudere in sè sia le caratteristiche
di una sintassi d’uso intuitiva e facile da gestire, sia la possibilità di definire
vincoli semantici molto specifici è il DTD++, il quale si pone come una
possibile soluzione al problema fornendo il potere espressivo di XML Schema
combinato con la semplicità del paradigma di validazione del DTD.
Sviluppato all’Università di Bologna [VAG03], DTD++ è un’estensione
sintattica dei DTD, che permette una maggiore leggibilità dovuta ad una
sintassi non XML-based, consentendo al tempo stesso l’utilizzo della grande
maggioranza di strutture e concetti di XML Schema. É essenziale, compatto
e facile da imparare.
7
8
INTRODUZIONE
In particolare viene ripreso il concetto di tipo sia per gli elementi che per
gli attributi ed il meccanismo di derivazione che consente di generare una
gerarchia di tipi semplici o complessi.
Ed è su questo linguaggio di validazione che è stato integrato il sistema per la
generazione automatica della documentazione oggetto di questa tesi. Prendendo spunto dalle regole sintattiche del Javadoc, il famoso documentatore
automatico per il linguaggio Java, si è realizzata la sintassi DppDoc che,
tramite l’uso di commenti ben strutturati, è possibile produrre una documentazione chiara, portabile e facilmente consultabile per qualsiasi vocabolario
XML definito dalle specifiche di validazione del DTD++.
É lecito a questo punto porsi una domanda: perchè è utile documentare?
Nella storia dell’informatica un importante dovere per un programmatore è
sempre stato quello di dedicare il massimo impegno per la corretta implementazione dei propri codici sorgenti , al contrario però lo stesso impegno
non sempre è equivalente nel momento in cui si deve “documentare” ciò che si
“realizza”. Le motivazioni per “rimandare” o addirittura “non fare” questo
importante compito si potrebbero relegare alle “solite scuse”:
“Lo farò più tardi”
Sfortunatamente è raro che veramente possa essere fatto “più tardi”. La natura stessa dei compiti tipici di un programmatore è cosi caotica che in molti
casi è impossibile “rinviare”. Ancora peggio, più si aspetta, e più facilmente si dimentica, creando cosi una documentazione non molto dettagliata e
quindi non solo inutile, ma addirittura fuorviante per chi dovrà un giorno
ereditare il progetto.
“Perchè documentare tutto? É più semplice ricordare”
Sicuramente è più semplice ricordare per quei pochissimi individui che hanno
il dono della memoria fotografica, ma sicuramente è impossibile per chiunque
ricordare tutto. O peggio ancora, è molto probabile che si ricordi solo una
parte, senza sapere di aver perso l’intero filo logico. Ciò ne scaturisce una
INTRODUZIONE
perdita di tempo nel cercare di ricordare quello che si è dimenticato o di
correggere ciò che è stato scritto.
“Se lo terrò nella mia mente, nessuno mi licenzierà!”
Questo tipo di strategia potrebbe essere valida anche per molto tempo, ma
non risulta essere però molto sicura. Si può pensare cosa potrebbe succedere
se dovesse sopraggiungere un’emergenza proprio nel momento in cui non si è
reperibili. La documentazione potrebbe risultare molto importante, permettendo ad un’altra persona di risolvere il problema durante la propria assenza.
In questi casi, è molto più conveniente avere una documentazione scritta in
modo chiaro e facilmente comprensibile per risolvere il problema, che individuare la propria assenza come una delle sue cause.
Ancora peggio, se la scusante dell’impossibilità di un licenziamento può garantire stabilità lavorativa, il tenere tutto in mente, necessita sempre la propria presenza, si diventa “indispensabili” con il rischio di intaccare pesantemente le aspirazioni della propria carriera.
In realtà uno dei maggiori problemi per un informatico è la mancanza di
un metodo veloce, dinamico e scalabile per generare automaticamente una
documentazione chiara e facilmente comprensibile. Ad ogni avanzamento
implementativo è applicata una sottotraccia documentativa inadeguata per
tenere tutto facilmente sotto controllo. Conseguenza naturale è una marcata difficoltà di comprensione ogni volta che si deve mettere mano ai codici sorgenti. A queste condizioni è comprensibile come la poca motivazione
a documentare sia il pensiero dominante. Per quanto si possa definire un
metodo rigoroso, risulta molto difficoltoso, quasi snervante, realizzare una
documentazione esente da errori e adeguata in ogni situazione se effettuata
manualmente.
É proprio la consapevolezza di quanto sia importante documentare un “prodotto” informatico che sia un semplice programma o un complesso progetto,
che ha stimolato molti studiosi a ricercare tecniche di automatismo in grado
di semplificare questo dovere tanto “noioso” quanto cruciale. La chiave di
9
10
INTRODUZIONE
svolta avverrà nel momento in cui si comprenderà l’importanza di separare
la forma dal contenuto, dove la forma in questo caso è la sintassi e il contenuto il dato semantico espresso da questa sintassi. L’intuizione di questa
separazione concettuale ha fornito non solo l’approccio ideale per strutturare
un valido automatismo per produrre documentazione, ma anche per la definizione di nuove regole in grado di manipolare piu efficacemente qualsiasi
tipo di dato espresso da una particolare sintassi.
Un attento lettore potrebbe ora chiedersi: cosa è precisamente DppDoc?
e come è stato realizzato?
Il più importante esempio di documentazione automatica, come già accennato, è il Javadoc. Questo tool fu realizzato dai ragazzi della Sun MicroSystem,
durante lo sviluppo del linguaggio Java. Javadoc è una fedele applicazione
delle più raffinate tecniche di literate programming per la produzione di una
documentazione in grado di rispecchiare in linguaggio naturale il significato sintattico e semantico espresso dal linguaggio Java. Il tool permette di
estrarre automaticamente documentazione HTML da programmi Java opportunamente commentati, inoltre alcune informazioni possono essere generate semplicemente analizzando il codice (es: la struttura gerarchica delle
classi, riferimenti a package, override dei metodi e altro ancora). Il risultato di questa analisi è uno “scheletro” documentativo delle dichiarazioni
interne al codice sorgente in formato facilmente consultabile, privato delle
complicazioni dell’implementazione. L’ausilio di speciali commenti consente
al programmatore di arricchire ulteriormente tale scheletro con chiarimenti,
precisazioni ed esempi d’uso, seguendo alcune semplici regole sintattiche.
Con il Javadoc si fornisce un valido strumento di programmazione letteraria
per produrre facilmente e con professionalità una documentazione utile su
qualsiasi programma Java.
Su DTD++ si è quindi voluto integrare un generatore di documentazione automatica ispirandosi alle logiche implementative adottate da Javadoc.
L’intento è quello di proporre DppDoc come una vera e propria estensione
INTRODUZIONE
javadoc sul linguaggio di validazione DTD++, con il quale poter produrre
una documentazione chiara e professionale su qualsiasi vocabolario XML definito con questa grammatica di validazione XML. Anche DppDoc infatti si
basa sulla generazione di uno “scheletro” documentativo delle dichiarazioni
interne al DTD++, il quale è possibile arricchirlo con addizionali informazioni tramite l’uso di speciali commenti e una sintassi dedicata.
Documentare DTD++ significa fornire un supporto di documentazione per
un cospicuo insieme di vocabolari XML compresi quelli validati secondo la
grammatica XML Schema approvata dal W3C [W3C04].
Inoltre l’approccio scelto per la realizzazione software assicura un’ottima scalabilità d’applicazione, in quanto è stato integrato nel convertitore dedicato
per DTD++ in modo da richiedere un quantitativo di risorse decisamente
contenuto e soddisfacente per l’elaborazione di documentazione anche per
vocabolari XML particolarmente complessi ed estesi. La realizzazione di
DppDoc infatti si è basata su un riadattamento implementativo del codice
sorgente del PreValidator.
Scritto interamente in Java il PreValidator for DTD++ [FD03] è un parser in grado di analizzare un documento DTD++, elaborarne le dichiarazioni
interne e fornire in output un documento valido secondo la grammatica XML
Schema o DTD.
Con la versione attuale si è arrivati ad un livello di implementazione tale da
colmare alcune lacune procedurali, consolidare l’intero flusso di elaborazione
dei dati, aumentare la già elevata flessibilità d’uso e fornire la predisposizione
all’integrazione di nuove estensioni e funzionalità. Ed è grazie a queste migliorie apportate al codice che è stato possibile definire una base solida per
“immergere” con pochi passi implementativi il sistema di documentazione
automatico DppDoc. Inoltre è stato possibile realizzare anche altre funzionalità accessorie in grado non solo di rendere più elegante le diverse fasi di
conversione, ma anche di estendere il potere sintattico del DTD++ con il
supporto per la dichiarazione di componenti di tipo astratto.
L’argomentazione di questa dissertazione si snoderà nei capitoli successivi
11
12
INTRODUZIONE
focalizzando, all’inizio, il modo in cui è stato affrontato e risolto il problema
della documentazione negli anni, facendo riferimento ad alcuni importanti articoli dei primi anni ottanta; si prosegue presentando Javadoc: si sottolineano
le caratteristiche che lo hanno reso il “faro” d’ispirazione per la realizzazione
di molti altri documentatori automatici.
Il secondo capitolo espone la descrizione di alcuni linguaggi di validazione
XML, presentando due approcci concreti per la documentazione automatica
di documenti XML.
Il terzo capitolo, oltre a presentare la sintassi DTD++ e il PreValidator, fornisce la descrizione sulla sintassi DppDoc.
Si conclude con il quarto capitolo fornendo i dettagli implementativi di
realizzazione.
Capitolo 1
Documentazione automatica
In questo capitolo si vuole presentare il modo in cui il problema della
documentazione automatica è stato affrontato e gradualmente risolto. Si inizierà con l’argomentazione di diversi articoli pubblicati nei primi anni ottanta
in cui vengono esposte le prime idee d’approccio e alcuni concreti tentativi
di soluzione, si prosegue con la presentazione di Javadoc, il sistema di documentazione automatica per il linguaggio Java, per poi concludere con una
sintetica descrizione su alcuni sistemi di documentazione automatica per altri
linguaggi di programmazione.
1.1
L’importanza della documentazione automatica
E’ stato nei primi anni ottanta, periodo in cui la computerizzazione stava
attirando oltre che gli interessi militari anche quelli industriali, che il problema venne messo per la prima volta in risalto con la pubblicazione di diversi
articoli.
Il primo a evidenziare le principali motivazioni fu Scott L. McGregor [SM82],
il quale stilò, per conto della Hewlett-Packard, un rapporto sulle procedure
di documentazione di diversi progetti sviluppati in quegli anni dai ricercatori dell’Università di Carnegie-Mellon. Già dall’astratto si evidenzia come
13
14
Documentazione automatica
la mancanza di impegno a documentare ricada sulla poca motivazione dei
programmatori. Si rende vana l’idea di semplificare e uniformare il tutto con
automatiche procedure standard.
I problemi principali si possono sintetizzare in tre precisi punti:
• forte disapprovazione degli addetti ai lavori a documentare il codice
con tediose e ripetitive operazioni da effettuare manualmente.
• mancanza di uno standard che potesse delineare le linee guida su come
generarla.
• difficoltà nel renderla comprensibile a qualsiasi livello di programmazione.
McGregor continua presentando una serie di raccomandazioni guida per
la realizzazione di un sistema computerizzato dedicato alla gestione automatica della documentazione.
L’uso di etichette per il reference avrebbe facilitato l’adeguamento lessicale
in base al livello di utenza a cui era indirizzato.
Articoli e studi di ricerca convergono sulla comune idea che un buona documentazione è caratterizzata dai seguenti fattori:
1. adeguata al particolare target di utenti che deve consultarla, in questo
caso uno sviluppatore software.
2. fornire un’intuitiva descrizione sulla logica di funzionamento del programma tramite una struttura ben formata del codice, una descrizione
dei dati di input e output e un buon sistema di analisi del flusso dei
dati.
1.1.1
Documentare: più una croce che delizia
Richard H. Smith [SR86] individua quattro periodi temporali in cui la
visione sull’importanza della documentazione ha vissuto la sua evoluzione. Il
1.1 L’importanza della documentazione automatica
periodo idilliaco, quando i pionieri dell’informatica non consideravano l’importanza di documentare i loro lavori, sicuri di ricordare il significato di
ogni singola riga di codice. Questa idea sbagliata sopravvisse fino a quando
si scontrarono con l’angosciante realtà di dover adeguare le esigenze di sviluppo su progetti software sempre più complessi, dove spesso era necessario
apportare modifiche. Si scoprı̀ che su molte aree di codice se ne conosceva
solo qualche nozione e che era conveniente cominciare a documentare i propri
programmi con sforzi manuali notevoli. Dall’altra parte i supervisori premevano per favorire questa sana abitudine, ma senza imposizioni. Il risultato fu
una marcata pigrizia dei programmatori a documentare, perché troppo occupati. Siamo nel periodo permissivo che non favorı̀ alcun beneficio al punto
da costringere l’imposizione di veri e propri ordini dall’alto affinché venisse
praticata una metodica e razionale attività di documentazione del proprio
codice. Il pragmatismo sembrava l’unica soluzione, ma il malcontento persisteva: i programmatori si trovarono costretti a lavorare su più progetti, con
in più l’obbligo della documentazione con risultati disastrosi.
Smith prosegue che solo esplorando la frontiera della generazione automatica
della documentazione si poteva arrivare ad una chiave risolutiva del problema.
In passato ci furono diversi esempi di generatori automatici. Si potrebbe
ricordare il Documentation Support System [JAHL82] sviluppato dalla General Elettric scritto in PDL, uno pseudocodice basato sulla combinazione
tra frasi in inglese e costruzioni logiche come IF-ELSE-ENDIF. Offrı̀ molti
benefici al programmatore tale da rendere il codice sorgente più leggibile e
supportato da una valida documentazione.
Si annullarono i tempi di attesa tra l’uscita di una versione nuova del
programma e l’aggiornamento della documentazione. Per la General Elettric
fu un risultato straordinario. Tuttavia l’uso del PDL costringeva il programmatore a inserire ancora molte informazioni manualmente.
Il problema risiedeva nella mancanza di un framework valido su cui definire
un design strutturato per l’implementazione di un algoritmo dedicato alla
15
16
Documentazione automatica
Figura 1.1: Un esempio di template PDL
generazione automatica della documentazione del codice sorgente.
Si andava cercando un metodo più accurato, basato sulle informazioni di
analisi del codice che già i compilatori erano in grado di fornire (come ad
esempio la tabella dei nomi dei simboli), con il quale sarebbe stato possibile
“commentare” in modo interattivo tutti i riferimenti di costanti, variabili,
funzioni e qualsiasi altro tipo di informazione.
Nei laboratori della NASA fu sviluppato RNDOC [ET82] che proponeva un
sistema di documentazione automatica su programmi scritti in Fortran basato su interfacce d’interazione grazie alle quali era possibile commentare tutte
le componenti chiavi del codice.
RNDOC è basilarmente un parser che decompone il codice sorgente del programma dato in input identificando i moduli e i simboli di cui è composto.
L’utente ha cosi la possibilità di applicare i commenti con l’ausilio di opportune interazioni d’inserimento e salvare in un nuovo file il codice sorgente
correttamente commentato. La figura 1.2 e 1.3 illustrano il modo in cui tutto
questo avviene e il risultato finale.
Un’altro studio interessante venne presentato nel 1984 ad una conferenza tenutasi a Città del Messico [LCPH84]. Si analizzarono le metodologie di svi-
1.1 L’importanza della documentazione automatica
Figura 1.2:
Esempio di inserimento interattivo dei commenti tramite
RNDOC
luppo delle applicazioni scritte in Cobol per conto del Ministero del Bilancio
messicano. Si evidenziava come la maggior parte dei programmi utilizzati
dal governo non avevano alcuna documentazione. E’ anche vero che nelle
prime fasi di sviluppo questi programmi erano ben documentati, ma questa
costanza non veniva rispettata durante le successive modifiche. Il risultato
era una documentazione poco utile e nella maggior parte dei casi addirittura
fuorviante.
Anche in questo caso si arriva ad una conclusione molto simile a quella osservata da McGregor: non esisteva un generale consenso sulla documentazione
del codice per la mancanza sia di uno standard che di un automatismo adeguato alla sua gestione.
L’architettura del sistema che fu presentato era composto da tre moduli: il
dictionary module, il program document processor module, il file description
module.
17
18
Documentazione automatica
Figura 1.3: Il risultato dato in output da RNDOC
Il dictionary module definiva una corrispondenza biunivoca tra tutte le parole chiavi del Cobol con un equivalente pseudo linguaggio Spanish-Cobol
dedicato alla documentazione.
Il program documentation processor analizzava il codice sorgente dato in input e in base al dictionary definito generare la documentazione vera e propria.
Il file description module scriveva su un file la documentazione ricevuta dal
program documentation processor applicandone una formattazione adeguata
alla lettura dell’utente.
I benefici rilevanti sarebbero stati un concreto strumento per i programmatori
nel documentare i loro programmi, una maggiore facilitazione nel comprendere quelli realizzati da terzi e la possibilità di poter istruire rapidamente
nuovi utenti ad un loro corretto uso.
Sebbene era chiaro che la definizione di regole procedurali per la documentazione automatica era fondamentale per massimizzare la resa produttiva finale,
non c’era ancora uno standard comune a garantirne un’universale compatibilità d’uso.
Un’analisi più approfondita su come doveva essere organizzata l’informazio-
1.1 L’importanza della documentazione automatica
ne della documentazione interna di un software fu presentata da Enrique
Arce Medica [MEA84], il quale affermava che doveva essere completa, sintetica, priva di ambiguità e ben organizzata. Ad ogni procedura (che sia un
programma o subroutine) doveva essere definita un’intestazione tramite commenti che riassumeva schematicamente tutte le sue caratteristiche. L’utente
o un’altra applicazione avrebbe potuto comprendere tutte le funzionalità della procedura leggendo semplici sezioni di commenti ben formati, senza dover
analizzare l’intero codice manualmente o tramite complesse decomposizioni
delle parole chiavi del linguaggio utilizzato.
L’intestazione avrebbe dovuto descrivere i seguenti tipi d’informazione:
• Nome della procedura.
• Il nome dell’autore e la data in cui è stata realizzata.
• Lo scopo della procedura; sintetica descrizione sul suo utilizzo.
• Che tipo di strategia algoritmica è stata implementata.
• La lista degli argomenti, una definizione per ciascuna variabile utilizzata e il loro ruolo (input, output o entrambi).
• I vincoli di utilizzo: regole e limitazioni sul tipo di dati che la procedura
deve elaborare.
• L’elenco delle condizioni di errore.
• L’elenco delle sottoprocedure a cui si appoggia.
• Il formato dei dati in input e dei risultati ritornati.
L’intestazione inoltre potrebbe essere ulteriormente arricchita con addizionali informazioni come l’elenco delle dimensioni delle locazioni di memoria per
i dati temporanei o uno schematico esempio d’uso.
Inoltre un programma ben strutturato è composto da più procedure e ognuna
di esse da moduli eseguiti sequenzialmente in modo verticale (top to bottom).
19
20
Documentazione automatica
Medica consigliava l’uso di una opportuna indentazione di tutti gli statement
annidati nel modulo con un uso appropriato di spaziature e tabulazioni.
L’apporto incrociato delle intestazioni e di una corretta identazione avrebbe
notevolmente migliorato la visione d’insieme di tutta l’architettura del software.
1.1.2
Separazione della forma dal contenuto: una chiave di svolta
Sempre ai laboratori della NASA, si stava teorizzando un nuovo concetto
procedurale per la generazione automatica della documentazione: la separazione delle strutture dei contenuti, del design e del sistema di formattazione.
L’articolo [CYE82] pubblicato nel 1982 da Christopher Hartsough, Yuzo
Yamamoto e Ernest A. Hershey spiegava le funzionalità di un prototipo,
TG/TF2, in grado di generare documenti ben strutturati su informazioni
prelevati da un database. TG/TF2 doveva soddisfare una specifica esigenza: generare automaticamente documentazione ben formata seguendo delle
specifiche standard di formattazione di leggibilità su delle informazioni memorizzate in un database sviluppato con tecnologia PSL/PSA [GD06]. Il
solo supporto del database non era sufficiente per rispettare queste specifiche: l’output finale era inaccettabile per essere compreso facilmente da chi
non conosceva il linguaggio PSL/PSA.
La soluzione fu quella di partizionare concettualmente il problema in due
parti, ciascuno gestito da un componente dedicato. Il primo componente,
il Text Generator (TG), avrebbe generato stringhe di testo prelevate dal
database PSL per poi essere formattate con opportune regole dal secondo
componente, il Text Formatter (TF2). L’intento fu quello di produrre una
documentazione che rispettasse le specifiche dello “standard Navy Procurement specification”.
Il modello è caratterizzato da due fondamentali concetti:
1.1 L’importanza della documentazione automatica
Figura 1.4: Report generato dal PSA che mostra le interrelazioni tra i dati e
i processi
1. Separazione del prodotto finale d’output da tutte le informazioni che
la compongono;
2. Separazione della forma e del contenuto (sintassi e semantica).
L’applicazione di questi due concetti avrebbe migliorato e portato ad un più
alto livello di astrazione la visione d’insieme di tutta l’architettura del sistema.
Il primo punto individua una differenziazione tra la totalità delle informazioni che definiscono un preciso “target object” e i singoli componenti che ne
descrivono le sue caratteristiche. Il target object è l’informazione elaborata dal sistema tramite l’analisi di tutti i suoi sottocomponenti, seguendo la
stessa logica utilizzata nell’ingegneria architettonica per la costruzione di un
edificio.
Il secondo punto evidenzia come un dato processato da un sistema informatico può essere scomposto in due parti: parte sintattica e parte semantica.
21
22
Documentazione automatica
Figura 1.5: Report generato dal TG/TF2 secondo le specifiche dello standard
Navy Procurement
La sintassi rappresenta la forma di rappresentazione del significato vero e
proprio del dato, la semantica. Nel linguaggio naturale la sintassi di una
frase definisce le relazioni logiche di ogni singola parola per rappresentare il
suo significato semantico.
Ed è in questi due punti cruciali che viene in aiuto la potenzialità del prototipo TG/TF2, tramite il quale è possibile generare documenti rispondenti
alle esigenze qualitative richieste.
Tra i primi ad intuire con entusiasmo le potenzialità dell’idea di Hartsough furono Jeffrey Kurn e Scott McGregor [KM84]. Proposero una nuova
strategia per la realizzazione di un sistema in grado di:
• facilitare la realizzazione di complessi progetti software
• generare un’appropriata documentazione
• verificarne le funzionalità con una solida piattaforma per il testing.
Si sottolinea l’importanza di individuare l’accuratezza del design del codice
sorgente, della documentazione che la descrive e la stabilità di verifica dell’intero sistema. Nella realtà queste osservazioni venivano superficialmente
1.1 L’importanza della documentazione automatica
prese in considerazione dagli addetti ai lavori: molti progetti non avevano
una elegante struttura del codice e la documentazione non veniva aggiornata
durante le modifiche. Tradizionalmente la soluzione è stata quella di generare
la documentazione con l’innesto di commenti ben formati senza tenere conto
delle evoluzioni del progetto.
La nuova strategia propone un approccio con il quale la documentazione è
generata in funzione di appropriati moduli, sincronizzandosi con l’evolversi
del progetto: si voleva migliorare contemporaneamente la qualità della documentazione e la struttura logica del codice sorgente, soprattutto in progetti
complessi la cui buona riuscita dipendeva essenzialmente dalla coordinazione
tra gli sviluppatori che vi partecipavano.
Figura 1.6: Diagramma che illustra l’idea del framework teorizzato da Jeffrey
Kurn e Scott McGregor
23
24
Documentazione automatica
La strategia si basa su diversi punti:
1. L’idea astratta del progetto che si vuole realizzare
2. Un’interfaccia ad un generico database
3. Un sistema per la generazione di:
• documentazione
• template di codice
• programmi per il testing
La realizzazione di un progetto necessita di una piattaforma su cui i progettisti possano tracciare le direttive per soddisfare ogni aspetto minimizzando
i casi di ambiguità.
Hartsough usa un linguaggio object-oriented, il PSL/PSA, che consiste di
oggetti, attributi, relazioni tra i diversi oggetti, ciascuno definito da una personale struttura dati: le tipiche regole di un linguaggio di programmazione
object-oriented come può essere l’odierno Java.
Come nel prototipo di Hartsough si definiscono delle “proiezioni” che sono
rappresentati dagli oggetti definiti dalla sintassi del linguaggio usato.
Sia la documentazione che il codice sorgente rappresentano un particolare set
di proiezioni, entrambi impliciti nel design generale del progetto: modificare le proiezioni della documentazione, significa ridefinire automaticamente le
caratteristiche del codice sorgente.
Seguendo l’intuizione dei due autori si evince come un importante obiettivo
potrebbe essere la creazione di un generatore di moduli scritti in un linguaggio dedicato su cui memorizzare le informazioni necessarie per la realizzazione
dei componenti del progetto: dichiarazioni di variabili, i valori che vengono
passati tra i diversi componenti, descrizione delle operazioni del componente
e altre informazioni utili.
In questo modo è possibile generare il codice sorgente avendo già definito l’input, l’output e le funzioni fondamentali del componente descritto dal modulo:
1.2 Javadoc e la documentazione automatica su Java
si provvede alla realizzazione di una piattaforma di lavoro su cui delineare le
linee guida per la programmazione di estesi sistemi software.
La molteplicità dei moduli e delle intercorrelazioni che potrebbero coesistere
in un esteso progetto, richiede un valido sistema per un’analisi di correttezza
dell’implementazione vera e propria di ciascun modulo: un sistema che generi
dei programmi di testing che verifichino precisi aspetti di un modulo. Questi
tests potrebbero ad esempio, verificare la correttezza della sintassi del codice o della semantica dei dati elaborati. Inoltre le verifiche sulla semantica
potrebbero assicurare che ogni variabile sia utilizzata come ci si attende, che
i componenti si passino i corretti valori, ma anche evitare che si verifichino
effetti secondari imprevisti al momento dell’elaborazione e molto altro.
L’esigenza di un metodo simile alla soluzione di Hartsough evidenzia che il
miglioramento della produttività di un programmatore è strettamente legata
alla necessita di definire delle regole che possano garantire un “buon” automatismo che separi la forma (sintassi) dal contenuto (semantica).
1.2
Javadoc e la documentazione automatica
su Java
Ma è nel 1994 che si vede un primo risultato concreto con la distribuzione di un applicativo chiamato Javadoc realizzato dai ricercatori della Sun
Microsystem, mentre stavano lavorando allo sviluppo del linguaggio Java e
le sue librerie. Il tool genera una documentazione automatica in HTML del
codice Java, che consente una navigazione molto efficace e veloce. La creazione e manutenzione di una tale mole di informazioni (ereditarietà fra classi,
firme dei metodi, riferimenti a package, override di metodi e altro ancora)
non sarebbe stata pensabile senza l’aiuto di un efficace sistema automatico
soprattutto per gli inevitabili errori di battitura a cui si va incontro scrivendo
manualmente documentazione.
Javadoc ebbe un notevole successo e questo fu dovuto sopratutto alla possibi-
25
26
Documentazione automatica
lità di poter creare con facilità una documentazione dall’aspetto professionale
anche per chi non è un esperto programmatore, il quale impara a valorizzare
un aspetto spesso sottovalutato.
Javadoc è un tool che elabora le dichiarazioni e i commenti doc presenti
in uno o più file sorgenti Java, producendo un set corrispondente di pagine
HTML che descrivono classi, interfacce, costruttori, metodi e campi con indicatori di visibilità public o protected. Javadoc è in grado di riproporre, in
Figura 1.7: API Specification Java 1.4.2 generate con Javadoc e le Doclets
standard
un formato facilmente consultabile, lo “scheletro” delle dichiarazioni interne
al codice sorgente, completamente spogliato delle complicazioni, in questo
caso superflue, dell’implementazione.
Al fine di rendere l’implementazione davvero inutile per l’utilizzatore che
intende interfacciarsi con l’insieme di classi in questione, il programmatore
è tenuto ad arricchire tale scheletro con chiarimenti, precisazioni ed esempi
d’uso. Le informazioni di base su package, classi, metodi e campi generate
1.2 Javadoc e la documentazione automatica su Java
automaticamente sono quindi arricchite da ulteriori dettagli per mezzo dei
“commenti doc”: questi sono racchiusi fra le sequenze di caratteri “/**” e
“*/”. Tali commenti sono riconosciuti e processati da javadoc solo se immediatamente precedenti la dichiarazione di una qualunque entità (classe,
interfaccia, metodo, costruttore, campo). Ogni commento doc è formato da
due sezioni:
• la descrizione, che inizia dopo il delimitatore iniziale /** e prosegue
fino alla sezione dei tag;
• la sezione dei tag, la quale inizia con il primo carattere @ che si trova
in testa ad una riga (escludendo asterischi e spazi).
La prima frase di ogni descrizione deve essere una rappresentazione concisa
ma completa dell’entità dichiarata. Essa viene infatti pensata e scritta per
figurare anche da sola, in quanto usata come definizione generale ed inserita
da javadoc nella sezione dal titolo “Summary”. L’insieme dei tag speciali,
se inseriti all’interno di un commento doc, vengono riconosciuti ed elaborati
dal javadoc. Alcuni di questi marcatori sono descritti nella tabella 1.1.
L’output del Javadoc è possibile personalizzarlo tramite delle specifiche librerie: le doclets API.
Un doclet è un programma scritto con le doclets API e la sua funzionalità è
proprio quella di definire il contenuto e il formato dell’output che deve essere
generato dal Javadoc. E’ possibile scrivere un doclet per qualsiasi tipo di
formato di testo, ad esempio HTML, SGML, XML, RTF o MIF. Inoltre la
Sun ha reso pubblico un doclet “standard” per la generazione di documentazione in formato HTML per qualsiasi tipo di applicativo scritto in Java: i
file HTML che vengono generati dalla doclet standard hanno infatti la stessa
organizzazione grafica e logica della documentazione che Sun fornisce per le
API che essa stessa distribuisce.
Le Doclet in particolare permettono ad altre case produttrici di soft-
27
28
Documentazione automatica
Tag
Descrizione
@author
Nome dell’autore
@deprecated
Identifica un metodo deprecato, ossia un metodo che non sarà
ossia un metodo che non sarà più presente nelle versioni successive del software
@exception
Descrive il tipo di eccezione di un metodo - vedere anche @throws
@param
Definisce i parametri del metodo. E’ necessario un tag per ogni parametro
@return
Descrive il valore di ritorno del metodo. Questo tag non dovrebbe essere utilizzato per i
costruttori o i metodi che ritornano un valore di tipo “void”
@see
Indica un riferimento ad un altro metodo o classe
@since
Indica il momento in cui il metodo è stato aggiunto alla classe
@throws
Descrive l’eccezione gettata dal metodo.
E’ un sinonimo del tag @exception introdotto nel Javadoc 1.2
@version
Indica il numero di versione della classe o del metodo
Tabella 1.1: Alcune variabili utilizzabili nei commenti Javadoc
ware e ad altri sviluppatori (soprattutto open source) di creare tool molto
diversificati:
• Generazione di schemi UML, grafi di dipendenze fra classi e package, analizzatori di codice (molto utilizzati nell’ingegneria del software)
[ZEJP06].
• Generazione di documentazione in formato PDF, Word, RTF, Microsoft
Help, Latex, ecc. [GHDT06]
1.3 Generatori automatici di documentazione su altri linguaggi: cosa
è stato realizzato
29
Figura 1.8: Esempio di commento Javadoc
1.3
Generatori automatici di documentazione su altri linguaggi: cosa è stato realizzato
Il meccanismo di documentazione automatica introdotto dal Javadoc ha
fornito lo spunto per la realizzazione di sistemi automatizzati anche su linguaggi di programmazione diversi dal Java.
La prima parte presenta alcuni accenni sulle tecniche di “literate programming”, utilizzate per la realizzazione di Javadoc e per molti altri documentatori automatici. Con le sezioni successive viene proposta un’ampia panoramica sui più famosi documentatori automatici.
1.3.1
Literate programming, accenni di programmazione letteraria
Il Literate programming (o programmazione letteraria) è la tecnica per
scrivere programmi affinchè siano compresi dall’uomo, e si basa su approcci simili a quelli per realizzare un lavoro di letteratura. Si contrappone alla
classica visione secondo cui un programmatore principalmente realizza codici
sorgenti per essere letti e interpretati esclusivamente da un computer.
30
Documentazione automatica
La documentazione e il codice sorgente sono scritti in un unico file. Sia il
codice sorgente che la documentazione possono essere estratti da questo file
tramite specifiche applicazioni. Le informazioni sono redatte e presentate
in modo tale che l’uomo possa comprenderne il significato con l’ausilio di
spiegazioni dettagliate. Il codice è automaticamente riadattato per essere
elaborato da uno specifico compilatore o interprete.
Il primo esempio di programmazione letteraria fu WEB [KD06], realizzato
da Donald Knuth nel 1981: l’idea consiste nel poter creare un’applicazione
in grado di manipolare documenti letterari, con l’innesto di opportuni codici
sorgenti all’interno del testo. WEB consiste di due programmi principali:
TANGLE, che genera compilati scritti in Pascal estrapolati dal documento,
e WEAVE, che genera in output una documentazione ben formata pronta
per essere stampata utilizzando TeX.
Lo stesso Javadoc è un esempio di literate programming, tramite il quale è
possibile produrre automaticamente documentazione facilmente comprensibile all’uomo con l’ausilio di opportune tecniche di programmazione letteraria.
1.3.2
DDoc
Ddoc è un generatore automatico di documentazione per il linguaggio di
programmazione object-oriented “D” sviluppato nel 1999 da Walter Bright
[WB06]. DDoc permette di scrivere documentazione tramite commenti speciali, usando uno stile sintattico naturale per migliorarne la leggibilità. I
commenti speciali riconosciuti da DDoc possono essere di tre forme:
1. /** */ Due asterischi dopo la slash di apertura;
2. /++ +/ Due più dopo la slash di apertura;
3. /// Tre slash consecutive.
Utilizzando una logica parametrica molto simile a quella di Javadoc è possibile elaborare automaticamente le informazioni semantiche e sintattiche fornite
1.3 Generatori automatici di documentazione su altri linguaggi: cosa
è stato realizzato
31
dal compilatore D come ad esempio i parametri di input o i valori di ritorno
delle funzioni.
Queste strutture a commento sono elaborate dal Ddoc con l’ausilio di opportune macro in modo tale da generare in output dei documenti che di default
sono impostati in HTML, è possibile inoltre definire formati d’output differenti come XML o XHTML.
Figura 1.9: Esempio di commento DDoc
1.3.3
Doxygen
Doxygen è sviluppato su ambiente Linux e Mac OSX sotto licenza GPL.
Realizzato da Dimitri Van Heesch [DVH] genera documentazione automatica
per i linguaggi C++, C, Java, Objective-C, Python, IDL, PHP, C# e D.
Doxygen prende in input il codice sorgente producendo in output una documentazione formattata in HTML, ma può anche essere strutturata in formato
CHM, RTF, PDF, LaTex, PostScript o man pages.
Il sistema di generazione è basata sull’analisi della struttura del codice del
32
Documentazione automatica
programma e su addizionali informazioni fornite manualmente tramite commenti simili a quelli del Javadoc.
Tra i tanti progetti che si basano su questo tipo di generatore spicca KDE
[KDEHP06], il famoso ambiente grafico Windows-style per Linux, il quale
usa Doxygen per la generazione delle sue API documentation.
Figura 1.10: Esempio di commento di Doxygen
1.3.4
HeaderDoc
HeaderDoc [AC06] è sviluppato e finanziato dalla Apple Computer basato
anch’esso sull’innesto di commenti speciali nel codice sorgente dato in input.
Il risultato finale può essere in HTML o XML.
Anche HeaderDoc abbraccia una logica di funzionamento molto simile al Javadoc.
I linguaggi supportati sono il C, C++, Java, Javascript, Objective-C, Pascal,
Perl, PHP e i tre linguaggi di scripting utilizzati in ambiente Unix (Bash,
Bourne Shell e Korn Shell).
HeaderDoc è composto da due utility: quella principale, headerdoc2html,
che genera la documentazione vera e propria e gatherheaderdoc che crea il
1.3 Generatori automatici di documentazione su altri linguaggi: cosa
è stato realizzato
33
table of contents.
1.3.5
NaturalDocs
NaturalDocs [VG06] è un generatore sviluppato da Greg Valure, è distribuito sotto licenza GPL ed è scritto in Perl.
Teoricamente potrebbe supportare qualsiasi linguaggio di programmazione
che supporta i commenti, ma solo sui linguaggi ActionScript 2.0, C# e Perl
è in grado di analizzare e generare automaticamente la documentazione di
funzioni, variabili e classi senza la necessità di inserire esplicitamente i commenti manualmente. La documentazione prodotta in output è in formato
HTML.
Natural Docs, a differenza di molti altri generatori automatici, non è molto
utilizzato dall’industria software eccezion fatta per alcune piccole compagnie
come ad esempio la Iron Realms Entertainment, piccola software house di
videogiochi. E’ invece molto popolare tra gli sviluppatori che utilizzano ActionScript 2.0 in quanto è l’unico a fornirne un pieno supporto automatizzato.
Figura 1.11: Esempio di commento NaturalDocs
34
Documentazione automatica
1.3.6
PHPDoc e phpDocumentor
PPHDoc
PHPDoc [PDoc00] è una vera e propria adozione del Javadoc per il linguaggio PHP. Il PHPDoc vuole essere un modo per stabilire un solido standard di regole per commentare il codice PHP con l’intento di offrire tre
importanti vantaggi:
• creare commenti seguendo regole standard incoraggiando i programmatori a documentare aspetti del codice che comunemente verrebbero
ignorati;
• predisporre la generazione automatica di documentazione ben strutturata e facilmente comprensibile tramite l’uso di parser come PhpDocumentor;
• favorire la realizzazione di ambienti di sviluppo integrati (Integrated
Development Environment) come il software Zend Studio con lo scopo
di assistere gli sviluppatori alla realizzazione dei loro progetti.
I componenti base del PHPDoc sono:
1. DocBlock: commenti javadoc-style definiti dalla struttura “/** */” che
precedono l’elemento da documentare;
2. Tags: parametri con prefisso “@” che informano il parser che tipo di
informazioni devono essere elaborate.
Figura 1.12: Esempio di commento DocBlock
PHPDoc supporta codice PHP sia di tipo object-oriented che procedurale.
1.3 Generatori automatici di documentazione su altri linguaggi: cosa
è stato realizzato
35
PhpDocumentor
PhpDocumentor [EB05] è un tool per generare documentazione su progetti realizzati in PHP distribuito con licenza GPL.
PhpDocumentor analizza il codice sorgente integrando le informazioni definite da commenti strutturati secondo le specifiche del PHPDoc. Il formato d’output finale può essere impostato in HTML, PDF o CHM. Altre
funzionalità interessanti sono:
• il supporto per il riferimento incrociato con documentazioni di altri
progetti o alla documentazione ufficiale del PHP;
• la possibilità di impostare tipi di documentazione dedicati in base al
tipo di utente finale come ad esempio tutorial passo passo personalizzati.
1.3.7
ROBODoc: un documentatore universale
ROBODoc è un tool di documentazione automatica simile al Javadoc distribuito sotto licenza GPL scritto da Jacco Van Weert nel 1995 [FS06]. In
apparenza potrebbe presentarsi come uno dei tanti sistemi di documentazione automatica fin’ora descritti, ma in realtà propone una particolarità che lo
distingue sensibilmente dagli altri: può essere applicato a qualsiasi linguaggio che supporti un marcatore di commenti e la sua principale funzione è
quella di estrarre e interpretare le informazioni in esse contenute in base ad
un template opportunamente definito in fase di inizializzazione. Il risultato
in output può essere in HTML, DocBook, Latex o RTF.
L’intento di ROBODoc è quello di risolvere le difficoltà di sincronizzazione
automatica del codice sorgente di un programma con la sua documentazione: adeguando in modo opportuno la struttura dei commenti del codice da
documentare è possibile definire una specifica “etichetta” d’interfaccia riconosciuta da ROBODoc tramite il quale estrarre tutte le informazioni dal
codice sorgente necessarie per generare in automatico documentazione in uno
specifico formato d’output, ad esempio HTML.
36
Documentazione automatica
ROBODoc si propone a tutti gli effetti come un documentatore universale in
grado di generare documentazione ben formattata su codici sorgenti a cui è
stata preventivamente applicata un’analisi delle dichiarazioni interne creando uno “scheletro” documentativo tramite tag commenti opportunamente
strutturati.
ROBODoc è stato utilizzato come parser di supporto ai fini dell’oggetto di
questa tesi: ne viene fornita una maggior descrizione di funzionamento in
Appendice A.
Capitolo 2
Documentazione e i linguaggi
di validazione XML
Introduciamo in questo capitolo il contesto principale su cui ruota l’intera
argomentazione di questa dissertazione.
La prima sezione presenta le principali caratteristiche del linguaggio di markup XML e di alcuni suoi linguaggi di validazione fornendo per ciascuno una
sintetica descrizione su alcune interessanti particolarità funzionali e loro limiti.
L’ultima espone invece due approcci concreti per la documentazione automatica di documenti XML validati con XML Schema il primo, DTD++ il
secondo.
2.1
XML e alcuni linguaggi di validazione
XML (eXtended Markup Language) è un meta-linguaggio per descrivere
linguaggi di markup. L’obiettivo principale di XML è quello di andare oltre i
limiti dell’HTML mantenendo allo stesso tempo un livello basso di complessità.
Si possono utilizzare in un documento XML tag a proprio piacimento e le
informazioni contenute possono essere rappresentate in maniera completa37
38
Documentazione e i linguaggi di validazione XML
mente indipendente dal come saranno successivamente processate. Con i
fogli di stile, poi, è possibile scegliere il modo più appropriato per rappresentare all’utente o ad un’applicazione il documento XML.
XML di per sé non è altro che un insieme standard di regole sintattiche per
modellare la struttura di documenti e dati. Questo insieme di regole, dette propriamente specifiche, definiscono le modalità secondo cui è possibile
crearsi un proprio linguaggio di markup. Le specifiche ufficiali sono state
definite dal W3C (World Wide Web Consortium)[W3C04]. Concretamente,
un documento XML è un file di testo che contiene una serie di tag, attributi
e testo secondo regole sintattiche ben definite caratterizzato da una struttura
gerarchica ad albero, generalmente noto come document tree. Non esistono
regole universali per l’organizzazione logica di un documento.
Per essere corretto un documento XML deve essere ben formato e valido. E’
detto ben formato quando è conforme ad ogni regola sintattica. Un documento che non è ben formato non viene considerato un XML e sarà rifiutato dal
parser che lo processa. Si parla di documento valido quando è ben formato
e rispetta l’insieme di regole che descrivono i valori consentiti e la posizione
delle varie componenti. Validare un documento XML significa quindi verificare l’aderenza a determinate regole. E’ possibile individuare [AL82] almeno
quattro livelli di validazione:
• validazione del markup ovvero il controllo sulle strutture del documento;
• validazione del contenuto dei singoli nodi;
• validazione dell’integrity ovvero dei collegamenti dei nodi all’interno
di un documento o dei collegamenti tra documenti;
• ogni altro test spesso chiamati business rules .
E’ in questo ambito che si inseriscono i linguaggi schema. Un XML Schema
è la descrizione di un tipo di documento XML.
Tipicamente esprime vincoli sulle strutture e sul contenuto del documento.
2.1 XML e alcuni linguaggi di validazione
Per esprimere in maniera formale tali schema sono nati numerosi XML Schema, standard e proprietari.
Utilizzare i linguaggi di validazione porta numerosi vantaggi. Primo tra tutti
la possibilità di esprimere regole attraverso speciali costrutti e di rendere il
processo di validazione indipendente dalla piattaforma. Inoltre i linguaggi
schema possono essere utilizzati in diversi scenari: ad esempio una community di utenti può accordarsi su uno schema comune e sulla produzione di
documenti XML che saranno validi rispetto allo schema in questione. Prima
dell’avvento di SGML o DTD i software designer erano costretti a definire
speciali formati file o linguaggi per poter condividere dati tra programmi.
Un altro settore in cui l’utilizzo di XML può portare benefici, è quello delle
applicazioni che, usando una definizione schema, possono guidare un autore
nello sviluppo dei documenti e verificare che i dati inseriti siano validi.
A seconda delle proprie caratteristiche i linguaggi schema si dividono in due
categorie:
• grammar-based languages: descrivono la struttura di un documento formalizzando le regole di produzione che devono essere seguite. Le
espressioni che vincolano gli elementi vengono chiamate tipi e corrispondono ai non terminali della teoria degli automi. Di questo gruppo
fanno parte DTD, XML Schema, Relax NG.
• rule-based languages: forniscono l’insieme delle regole che un documento XML deve seguire dando una specifica aperta (tutto ciò che
non è vietato è consentito) o chiusa (tutto ciò che non è consentito è
vietato). A questo gruppo appartengono Schematron e Xlinkit.
I linguaggi grammar-based offrono particolari vantaggi nelle interrogazioni
XML, in quanto la definizione e la conoscenza dello schema aiuta gli utilizzatori a scrivere le query ottimizzate e facilita le operazioni di debugging.
I linguaggi rule-based permettono di formalizzare in maniera semplice i coconstraints (constraint incrociati sull’esistenza o inesistenza contemporanea
39
40
Documentazione e i linguaggi di validazione XML
di elementi e attributi) ma non permettono di imporre dei vincoli complessi
ai datavalues e appaiono cosi limitati nella definizione dei vincoli strutturali.
2.1.1
DTD
Tra i vari linguaggi il primo è il DTD (Document Type Definition). Introdotto e standardizzato dall’XML 1.0 Recommendation, il DTD nasce come
versione semplicificata dei DTD SGML. Il principale vantaggio dei DTD è
l’essere supportati da ogni parser che valida XML 1.0. DTD permette di scrivere documenti compatti e facilmente comprensibili. L’utilizzo delle entità
parametriche permette di raggiungere un buon grado di modularità e riuso.
Tuttavia si scorgono importanti limitazioni:
• mancata gestione dei namespace che rende difficile la qualifica degli
elementi;
• limitata espressività che non consente di catturare alcuni aspetti formali
di XML;
• sebbene sia possibile un ragionevole controllo degli elementi strutturati,
si ha poca flessibilità sui content model misti, non permettendo vincoli
sugli elementi di testo (#PCDATA e CDATA) a parte le liste di valori
negli attributi;
• per allegare documentazione è necessario inserire commenti XML dentro al DTD che tuttavia vengono eliminati dal parser;
2.1.2
XML Schema
XML Schema, o più informalmente XSD, è considerato il successore del
DTD. Un XML Schema è un documento XML che utilizza un insieme di tag
speciali per definire la struttura di un documento XML. Da questa definizione emerge una novità interessante: viene utilizzato un documento XML per
validare un altro documento XML.
2.1 XML e alcuni linguaggi di validazione
Pubblicato come W3C Recommandation nel 2001, utilizza un ampio datatyping system grazie al quale la struttura logica del documento XML può
essere vincolata in maniera dettagliata. Il primo miglioramento rispetto ai
DTD è la sintassi basata su XML che, se da un lato diminuisce la leggibilità e
la chiarezza, dall’altro aumenta la flessibilità e la processabilità automatica.
La validazione XML Schema-based permette di esprimere la struttura e il
contenuto di un documento XML in termini di data model (modello che descrive in maniera astratta il modo in cui vengono rappresentati i dati in un
sistema informatico) che è implicito durante la validazione. Il data model di
XML Schema include:
• Il vocabolario (nomi di elementi e attributi);
• Il content model (relazioni / strutture);
• I datatypes.
La novità di XML Schema rispetto agli altri linguaggi generativi è rappresentata dal concetto di tipo di dato che descrive il contenuto degli elementi
e degli attributi. I tipi riconosciuti da XML Schema sono suddivisi in due
categorie: i tipi semplici (utilizzati per elementi e per attributi) e i tipi complessi (utilizzati solo per gli elementi). In XML Schema un elemento o un
attributo deve sempre essere associato ad un tipo.
2.1.3
RELAX NG
RELAX NG è un linguaggio schema pubblicato dall’ISO come International Standard nel 2003. Si basa su due linguaggi precedenti, TREX (Tree
Regular Expression for XML) [Cla01], sviluppato da James Clark e RELAX
(Regular Language description for XML) [Mur00] sviluppato da Murata Makoto. In uno schema RELAX NG la struttura e il contenuto di un documento
XML vengono specificati tramite pattern che vanno a identificare una classe di documenti che fanno match con tali pattern. Il maggior vantaggio di
41
42
Documentazione e i linguaggi di validazione XML
RELAX NG rispetto ai DTD e a XML Schema è costituito dagli attributeelement constraints , ovvero l’inclusione degli elementi e degli attributi in
singole espressioni regolari. In questo modo, pur se in maniera limitata, è
possibile definire co-constraint.
RELAX NG offre due sintassi: la prima è XML-based e permette di scrivere degli schema strutturati secondo la logica XML. La seconda risulta più
compatta e consente di definire pattern senza ambiguità. Rispetto a XML
Schema, RELAX NG fornisce solo due datatype: string e token. Tuttavia è
possibile far riferimento a datatypes definiti esternamente.
Potrebbe essere difficile esprimere un’occorrenza minima e massima in maniera analoga ai minOccurs e maxOccurs di XML Schema. Inoltre non è
possibile specificare valori di default: ciò può portare a delle situazioni in cui
non è possibile stabilire se un pattern viene soddisfatto oppure no.
2.1.4
Schematron
Sviluppato da Rick Jelliffe [JR02] all’Academia Sinica Computing Center
(ASCC), Schematron si inserisce nella categoria dei linguaggio schema rulebased. Infatti a differenza dei linguaggio grammar-based, non viene generata
una grammatica per un documento XML, ma vengono fatte delle asserzioni su ciò che il documento XML può o non può contenere. Schematron è
basato su una semplice azione: prima vengono ricercati determinati nodi
context (tipicamente elementi) all’interno del documento tramite i meccanismi di XPath, successivamente per ognuno di essi viene verificato che le
altre espressioni XPath siano vere.
Grazie a questo approccio è possibile definire strutture che difficilmente possono essere scritte in un linguaggio grammar-based. Inoltre una frase espressa
nel linguaggio naturale può essere tradotta facilmente in una regola Schematron.
Il limite di Schematron è la mancanza di un costrutto esplicito per dichiarare
il contenuto di elementi o attributi in quanto tutto è formalizzato tramite
espressioni XPath, rendendo difficile la definizione di alcuni vincoli. Inoltre,
2.1 XML e alcuni linguaggi di validazione
essendo l’obiettivo di Schematron la validazione delle strutture XML, non
viene fornito di alcun datatypes.
2.1.5
DTD++
DTD++ [VAG03] è un’estensione sintattica del DTD, che, oltre a permettere una maggiore leggibilità sintattica, offre la possibilità di definire una
più vasta combinazione di vincoli semantici, fornendo una flessibilità d’utilizzo simile a XML Schema.
Sfruttando la semplicità e i costrutti del DTD, ne aumenta l’espressività cosi
da colmare quel divario funzionale che separa DTD da XML Schema. Le più
importanti caratteristiche funzionali del DTD++ possono essere raggruppate
nei seguenti punti:
• permette l’utilizzo delle entità parametriche assenti in XML Schema e
come quest’ultimo utilizza il concetto di tipo di dato sia per gli elementi
che per gli attributi;
• fornisce una serie di tipi predefiniti e i principali costrutti di XML
Schema, in particolare i meccanismi di derivazione;
• con la seconda versione [VFGM03] è inoltre possibile esprimere i coconstraints raggiungendo un potere espressivo pari a quello di Schematron;
• supporta un’estensione Object Oriented [GG005] che consente di specificare come locali o globali le componenti interne e permettere di
dichiarare gruppi di elementi e attributi e gruppi di sostituzione.
• quest’ultima versione infine, oltre a offrire un supporto documentativo,
introduce una sintassi per la definizione di componenti di tipo astratto, completando pienamente il supporto di derivazione e sostituzione
Object Oriented che XML Schema fornisce.
DTD++ vuole quindi essere un linguaggio di validazione che propone i
benefici sia dei linguaggi grammar-based che rule-based.
43
44
Documentazione e i linguaggi di validazione XML
2.2
Documentare un linguaggio di validazione XML: verso un nuovo approccio
Dalla panoramica di osservazioni sopra presentate risulta evidente che un
buon metodo di validazione XML tende a indirizzarsi verso una maggiore libertà nella definizione di vincoli semantici personalizzati e allo stesso tempo
mantenere il grado di complessità sintattica più semplice possibile. Ed e’ con
questo presupposto che si e’ voluto realizzare un sistema di documentazione
automatica sul linguaggio di validazione XML che più si identifica in questo
metodo: il DTD++.
La sezione è divisa in tre parti: la prima presenta un approccio concreto
di documentazione per XML Schema basato su XSL e Xalan [Xalan05], si
analizzano i metodi d’approccio, le funzionalità e i limiti; la sezione prosegue
con una veloce spiegazione sui motivi per cui si è scelto DTD++ come linguaggio di riferimento per la realizzazione del supporto di documentazione
automatica in oggetto e in ultima sezione presentata.
2.2.1
Un approccio XSL per documentare XML Schema
Il primo esempio concreto di sistema automatico orientato alla documentazione di un linguaggio di validazione XML fu presentato alla comunita’
opensource il 15 ottobre 2005 con un annuncio ufficiale del team xframe sul
loro sito ufficiale [XF05]:
“The xframe team is pleased to announce release 1.0-beta of the
sub project xsddoc.
The xsddoc subproject of xframe is an Open Source documentation tool for W3C XML Schema based on XSLT and XalanJ.
With xsddoc you can generate documentation of your XML Schema in a JavaDoc like visualisation.”
2.2 Documentare un linguaggio di validazione XML: verso un nuovo
approccio
45
la home ufficiale continua precisando che:
“Based on the experience in developing xsddoc and the problems
we had handling the highly recursive nature of XML Schema with
XSLT, we decided to start a new Java-based code stream with the
intention to develop an XML Schema documentation generator
that fully complies with the W3C XML Schema recommendation.
This new software is now available as xnsdoc thru our partner
company buldocs Ltd.”
Xnsdoc è quindi un generatore di documentazione automatica per il linguaggio XML Schema scritto in Java basato su tecnologia XSLT.
Dal sito ufficiale della buldocs.ltd [BDocs06], si apprendono le funzionalità:
• supporto di tutti gli stili di validazione Xml-Schema 1 ;
• riferimenti incrociati tra i vari elementi schema strutturati secondo la
logica seguita dal Javadoc per il linguaggio java;
• documentazione indipendente dal tipo di browser utilizzato;
• supporto per documenti xsd importati o inclusi;
• facilità di integrazione con molte piattaforme software di sviluppo come
StylusStudio, oXygen XML o XMLWriter;
• versioni per windows, linux e mac.
Il funzionamento di xnsdoc si poggia fondamentalmente sullo stesso sistema
adottato da Xsddoc, ossia sulle regole di stylesheet XSL [PD02] per la trasformazione di un documento xml in un altro documento xml con l’ausilio di
un engine xslt (ad esempio xsltproc o Xalan).
L’idea consiste in un’operazione di riadattamento in output di un albero schema, tramite accurate regole XSL, tali da generare documenti HTML
1
http://www.xfront.com/GlobalVersusLocal.html
46
Documentazione e i linguaggi di validazione XML
Figura 2.1: Sistema di trasformazione di documenti XML tramite i fogli di
stile XSL
strutturati similarmente a quelli creati con Javadoc.
Xnsdoc si propone quindi come un engine xslt ottimizzato per generare documentazione automatica su documenti XML schema rispettando tutte le
specifiche ufficiali approvate dal W3C.
Osservando l’idea e la logica di funzionamento si deduce che gran parte del
lavoro di sviluppo di xnsdoc si è focalizzato nella definizione di precise regole
xsl tali da:
• ricreare la stessa struttura grafica di un documento generato in Javadoc;
• presentare ciascun elemento del documento schema rispettando le regole di validazione XML-Schema approvate dal W3C;
• rendere estremamente facile la generazione della documentazione a
qualsiasi livello utente.
2.2 Documentare un linguaggio di validazione XML: verso un nuovo
approccio
47
Figura 2.2: Sistema di generazione automatica della documentazione in html
di un documento XML-Schema tramite Xnsdoc
Sicuramente il vantaggio più grande di xnsdoc è quello di proporsi, al momento, come unica alternativa per la generazione di documentazione automatica
su documenti scritti in linguaggio XML-Schema, ma non puo’ ritenersi esente
da limiti sopratutto per quanto riguarda le performance di analisi ed elaborazione causato per larga misura dalla eccessiva verbosita’ di XML Schema.
I limiti evidenziati su xnsdoc si possono riassumere nei seguenti punti:
• unico formato d’output possibile è l’HTML;
• per documenti schema molto grandi la generazione può richiedere molte
risorse sia in termini di tempo che di memoria;
• non è previsto alcun uso di commenti speciali tramite i quali arricchire
la documentazione ricavata dalla sola analisi dell’albero schema;
• l’utilizzo di xnsdoc necessita una licenza d’uso a pagamento.
2.2.2
Un buon compromesso sulla validazione XML
DTD++ nasce con il preciso obiettivo di colmare il divario tra l’eccessiva
verbosità sintattica di XML-Schema e la scarsa espressività semantica del
DTD.
48
Documentazione e i linguaggi di validazione XML
Figura 2.3: Un esempio di documentazione generata con xnsdoc
Si mantiene il paradigma di validazione del DTD, che si avvale di una sintassi
concisa e autodescrittiva, per offrire i benefici del potere espressivo di XMLSchema.
La prima versione di DTD++ [VAG03] vide l’introduzione delle principali
funzionalità di XML Schema fornendo importanti basi che il DTD non può
attualmente offrire:
• supporto per namespace multipli;
• integrazione di tipi semplici predefiniti;
• uso di facet per le derivazione di restrizione;
• definizione di tipi semplici e complessi a discrezione dell’utente;
• l’introduzione del content model ALL di XML Schema.
Inoltre con la seconda versione [VFGM03] si è soddisfatta un’altra importante necessità: l’adozione dei co-constraints.
Sia DTD che XML Schema non permettono di imporre i vincoli più semplici
e comuni [GG005]. Ad esempio si può volere la presenza non simultanea
degli attributi A e B oppure si può voler specificare che se esiste un attributo
2.2 Documentare un linguaggio di validazione XML: verso un nuovo
approccio
49
“gratis”, l’elemento “prezzo” non può esistere.
Il supporto dei co-contraints ha fornito la soluzione per specificare e verificare
specifici vincoli nei documenti XML.
DTD++ si presenta quindi come un linguaggio di validazione semanticamente equivalente ad un significativo sottoinsieme di XML Schema e allo stesso
tempo si è fornito il supporto per i co-contraints, colmando quel divario funzionale tra i linguaggi grammar-based e rule-based permettendo di esprimere
forti vincoli accostandosi molto a Schematron e Relax NG.
2.2.3
Un’estensione javadoc per DTD++
Abbiamo visto nel primo capitolo metodi di documentazione automatica
per diverse grammatiche procedurali e si è osservato che il comune denominatore ispiratore è rappresentato dallo standard proposto da Java con il
Javadoc: generazione di uno “scheletro” documentativo delle dichiarazioni
interne al codice sorgente cui il programmatore è tenuto ad arricchire con
chiarimenti e spiegazioni tramite l’uso di commenti speciali e una intuitiva
sintassi parametrica (Tabella 1.1). Anche su DTD++ si è scelto di fornire un
supporto di documentazione automatica che segue le medesime linee guida:
il tentativo è proporre una estensione javadoc su un linguaggio per definire
vocabolari XML.
Come il Javadoc infatti, il sistema realizzato si basa sulla generazione di uno
“scheletro” documentativo delle dichiarazioni interne al DTD++, il quale è
possibile arricchirlo con informazioni aggiuntive con speciali commenti.
L’interfaccia d’output è predisposta per adeguarsi a diversi metodi di formattazione che siano basati su fogli di stile XSL o template specifici per
convertitori generici (ad esempio ROBODoc): in questo modo si vuole garantire la compatibilità su tutti i più importanti metodi di formattazione
finale.
I vantaggi immediati sarebbero l’eliminazione di costose analisi ricorsive a
valle sull’intero albero Schema tipiche di xnsdoc. Questo significa minimiz-
50
Documentazione e i linguaggi di validazione XML
zare i requisiti in termini di risorse hardware e software con il beneficio di
un’elevata scalabilità d’applicazione anche su complessi sistemi informatici
XML based.
Capitolo 3
Una sintassi per documentare
DTD++
Il capitolo introduce le caratteristiche principali del PreValidator per
DTD++, prosegue con l’argomentazione della sintassi DTD++ vera e propria. Il capitolo si conclude con la spiegazione del DppDoc.
3.1
3.1.1
Il convertitore DTD++: il PreValidator
Introduzione
Nella prima versione di DTD++ ci si avvaleva di un parser validante
(DTD++ for Xerces) [AN01] basato sul parser Xerces Java 2.
Alcune modifiche apportate ai moduli di Xerces dedicati allo scanning del
DTD classico, hanno permesso di supportare le nuove dichiarazioni DTD++.
In questo modo si è potuto generare una grammatica DTD++ e, da questa,
lo schema per validare il documento XML istanza del DTD++.
La scelta di avvalersi di Xerces ha portato all’indiscutibile vantaggio di aver
utilizzato un’architettura testata e ben funzionante supportata dall’ambiente
open-source. Tale decisione ha lo svantaggio di dover sottostare alle limitazioni imposte da un’architettura preesistente.
51
52
Una sintassi per documentare DTD++
Nella versione successiva si è quindi preferito realizzare ex novo un preprocessore per la validazione di documenti scritti in XML o DTD tramite
DTD++ [FD03]. PreValidator for DTD++ effettua un parsing del documento DTD++ dato in input generando in output il corrispondente documento
in DTD o XML Schema.
Per ottenere una massima flessibilità di utilizzo, i controlli sulla validità dello
schema generato non sono stati effettuati dal preprocessore, ma delegati al
validatore esterno. In particolare sono utilizzati MSXML e il GTRI Validation Tool 1.1 che ha permesso di utilizzare Xerces Java come validatore.
3.1.2
Caratteristiche principali
Scritto interamente in Java per aumentarne la portabilità, PreValidator
ricorre a tecnologie esterne solo per le fasi di scanning e parsing consentendo cosi la massima flessibilità di utilizzo. In questo modo si è ottenuto
un controllo completo del flusso di esecuzione senza aver alcuna limitazione sull’implementazione delle funzionalità. É quindi possibile utilizzare il
preprocessore in maniera indipendente cosi da poter essere utilizzato come
strumento esterno in piattaforme di sviluppo software, ad esempio Oxygen.
In particolare si è fornito il supporto per la gestione dei namespace e per i
meccanismi di importazione ed inclusione dei file. Per ogni namespace viene
generato un file XML Schema che viene successivamente importato all’interno del documento convertito.
Se all’interno del documento DTD++ sono presenti delle entity SYSTEM,
il file indicato dal percorso dell’entità viene a sua volta convertito in XML
Schema e salvato secondo le scelte effettuate.
L’utente, in fase di conversione, può inoltre decidere se applicare uno stile di
progettazione XML Schema: Russian Doll, Salami Slice, Venetian Blinds e
Garder of Eden. A seconda dello stile scelto, lo schema generato avrà componenti locali o globali.
Se non viene selezionato alcuno stile, per default verrà applicato lo stile Sa-
3.1 Il convertitore DTD++: il PreValidator
lami Slice.
La possibilità di convertire un documento DTD++ in DTD inoltre fornisce un’ulteriore apertura allo standard attuale. Nella maggior parte dei casi si avrà una perdita di informazioni dovuta alla maggiore espressività di
DTD++. Analogalmente a quanto accade nella generazione dello schema, i
file richiamati tramite le entity SYSTEM e le entity PUBLIC, vengono processati e convertiti in DTD mantenendo le scelte dell’utente. Riguardo questa
particolare procedura algoritmica sono state effettuate sostanziali correzioni
al codice originale, in quanto erano stati riscontrati spiacevoli casi di perdita di informazione durante alcune fasi di importazione che comprometteva
la validità finale di un cospicuo sottoinsieme di documenti convertiti in DTD.
Le fasi di conversione
Le fasi di conversione del PreValidator da un documento DTD++ a uno
in XML Schema o DTD possono essere individuati in tre principali azioni:
1. Lettura del documento DTD++ in input tramite due parser: il Lexer
e lo Yacc.
2. Elaborazione di tutti i tag estratti durante il parsing: in questa fase
i tag vengono “impacchettati” in opportuni oggetti Java e “accodati”
in una speciale lista chiamata tagList.
3. Scorrendo l’intera tagList avviene la scrittura vera e propria su file
dei documenti finali in DTD o XML Schema.
Una maggiore descrizione sulle scelte implementative del PreValidator è presentata nel quarto capitolo.
53
54
Una sintassi per documentare DTD++
3.1.3
Novità con la nuova versione
Con la versione attuale del PreValidator si è arrivati ad un livello di implementazione che, come già accennato, ha subito sostanziali ristrutturazioni
in diversi punti cardini del codice. In questo modo si è riusciti a:
• colmare alcune lacune implementative;
• consolidare il flusso procedurale generale;
• aumentare la flessibilità d’uso;
• fornire maggior libertà d’integrazione per nuove estensioni e funzionalità.
Infatti oltre al sistema di documentazione automatica integrato sono state
implementate altre funzionalità, le quali hanno contribuito non solo a rendere più elegante le fasi di conversione, ma anche a integrare il supporto per
la dichiarazione dei componenti di tipo abstract presenti in XML Schema.
Il potere espressivo della sintassi DTD++ risulta notevolmente ampliato,
accostandosi sempre di più al meccanismo di polimorfismo tipico della programmazione Object Oriented, permettendo di raggiungere una maggiore
astrazione dello schema e quindi una maggiore flessibilità d’uso dei tipi.
3.2
3.2.1
Sintassi di DTD++
I tipi
In DTD++ è possibile definire due categorie di tipo: i tipi semplici e i tipi
complessi. Come in XML Schema, un elemento o un attributo deve sempre
essere associato ad un tipo.
3.2 Sintassi di DTD++
55
Tipi semplici
DTD++ permette di definire delle entità che hanno lo stesso valore delle
dichiarazioni dei tipi semplici in XML Schema. E’ cosi possibile utilizzare
una serie di tipi predefiniti equivalenti a quelli definiti nella recommendation
XML Schema Part 2 [BM01] o dichiarare dei nuovi tipi semplici.
Ad esempio
<!ENTITY # myString (#STRING)>
Sintassi:
<!ENTITY # nome ‘‘(tipobase)’’>
<!ELEMENT nomeElemento (tipobase)>
<!ATTLIST nomeElemento nomeAttributo (tipobase) default>
<!ATTLIST nomeElemento nomeAttrGroup >
oppure
<!ENTITY # nome ‘‘tipobase’’>
<!ELEMENT nomeElemento tipobase>
<!ATTLIST nomeElemento nomeAttributo tipobase default>
nome:
nome del nuovo tipo semplice
tipobase:
tipo semplice da cui l’elemento deriva
nomeElemento:
nome dell’elemento
nomeAttributo: nome dell’attributo
default:
#IMPLIED o #REQUIRED o #FIXED ‘‘ ’’ o ‘‘ ’’
nomeAttrGroup: sempre racchiuso tra ‘‘##’’ e ‘‘;’’
Tabella 3.1: Tipo semplice
Tipi complessi
La dichiarazione di un tipo complesso avviene tramite l’utilizzo di una
entità e il simbolo “@”. All’interno dei tipi complessi possono apparire sia
elementi che attributi.
Ad esempio
56
Una sintassi per documentare DTD++
<!ENTITY @ person ‘‘(name,surname)’’
‘‘age #INTEGER #REQUIRED’’>
3.2 Sintassi di DTD++
57
Sintassi:
<!ENTITY @ nome ‘‘contentModel’’ listaAttributi>
nome:
nome del tipo complesso
contentModel:
contentmodel del tipo complesso
listaAttributi:
‘‘lista di attributi’’
Tabella 3.2: Tipo complesso
É possibile derivare i tipi semplici e i tipi complessi creando una gerarchia
in maniera analoga alle classi di un sistema Object Oriented.
3.2.2
Derivazione dei tipi semplici
Restrizione
Nella derivazione per restrizione il nuovo tipo è creato a partire da un
tipo preesistente (predefinito o definito dall’utente), detto tipo base.
La componente derivata, invece, contiene un insieme di vincoli (facet) che
restringono il valore del datatype.
<!ENTITY # myInteger "(#INTEGER[0,101[)">
É possibile decidere di non utilizzare le parentesi ottenendo un tipo complesso
con l’identico significato.
<!ENTITY # myInteger "#INTEGER[0,101[">
Da un punto di vista semantico, si noti che non vanno inseriti spazi tra
tipobase e i vincoli nè tra i vari vincoli. É possibile, inoltre, applicare più
facet contemporaneamente ma la loro applicabilità è vincolata al tipo di dato
cui si riferiscono.
58
Una sintassi per documentare DTD++
Sintassi:
<!ENTITY # nome ‘‘(tipobase{}[]//()\\)’’>
<!ELEMENT nomeElemento (tipobase{}[]//()\\)>
<!ATTLIST nomeElemento nomeAttributo
(tipobase{}[]//()\\) default>
oppure
<!ENTITY # nome ‘‘tipobase{}[]//()\\’’>
<!ELEMENT nomeElemento tipobase{}[]//()\\>
<!ATTLIST nomeElemento nomeAttributo
tipobase{}[]//()\\ default>
{lunghezza }
[range]
/pattern /
(enumerazione )
\whitespace \:
vincoli di derivazione per restrizione
Tabella 3.3: Derivazione per restrizione
Lista
La derivazione per lista si ottiene aggiungendo al tipo base il simbolo
“+”. Tale derivazione permette di definire un insieme di valori leciti del tipo
atomico derivato. Ad esempio LotteryNumbers accetterà una lista di interi
non negativi con valore massimo 99.
<!ENTITY # LotteryNumbers ‘‘#NONNEGINTEGER+[,99]’’>
I tipi derivati per lista possono essere ulteriormente derivati per restrizione.
In questo caso il simbolo “+” deve essere il primo ad apparire dopo il tipo
semplice.
3.2 Sintassi di DTD++
Sintassi:
<!ENTITY # nome ‘‘(tipobase+{}[]//()\\)’’>
<!ELEMENT nomeElemento (tipobase+{}[]//()\\)>
<!ATTLIST nomeElemento nomeAttributo
(tipobase+{}[]//()\\) default>
oppure
<!ENTITY # nome ‘‘tipobase+{}[]//()\\’’>
<!ELEMENT nomeElemento tipobase+{}[]//()\\>
<!ATTLIST nomeElemento nomeAttributo
tipobase+{}[]//()\\ default>
+:
derivazione per lista
{} [] // () \\:
vincoli di derivazione per restrizione
Tabella 3.4: Derivazione per lista
Unione
Tramite questo processo si uniscono i valori leciti di due tipi semplici
ottenendo un nuovo tipo dato dall’unione dei tipi base derivati. Per esprimere
la derivazione per unione i tipi base coinvolti vengono separati dal simbolo
“|” e possono essere o meno posti tra parentesi.
<!ELEMENT simple ((#GDAY\c\)|(#HEXBINARY))>
è del tutto equivalente a
<!ELEMENT simple #GDAY\c\|#HEXBINARY>
59
60
Una sintassi per documentare DTD++
Sintassi:
<!ENTITY # nome ‘‘union’’>
<!ELEMENT nomeElemento (union)>
<!ATTLIST nomeElemento nomeAttributo union default>
oppure
<!ENTITY # nome ‘‘union’’>
<!ELEMENT nomeElemento union>
<!ATTLIST nomeElemento nomeAttributo union default>
union:
(tipobase+vincoli) |(tipobase+vincoli)|...
oppure
tipobase+vincoli | tipobase+vincoli |...
vincoli:
vincoli di derivazione per restrizione
Tabella 3.5: Derivazione per unione
3.2 Sintassi di DTD++
3.2.3
Derivazione dei tipi complessi
I tipi complessi possono contenere al loro interno sia elementi che attributi. Questi ultimi, se presenti, devono essere sempre racchiusi tra virgolette.
Altrimenti è possibile tralasciarle o inserirle. Ad esempio
<!ENTITY @ personType "(firstname|secondname)">
<!ENTITY @ indirizzo "(via,città)" "">
Restrizione
Con la derivazione per restrizione è possibile vincolare i tipi complessi definiti dall’utente. Si dichiara quindi un nuovo tipo complesso come restrizione
di uno preesistente. Ad esempio
<!ENTITY @ personType ‘‘(firstname,secondname?)’’
‘‘age #INTEGER #REQUIRED
year CDATA #REQUIRED’’>
<!ENTITY @ person @personType; ‘‘(firstname,secondname)’’
‘‘age #INTEGER #REQUIRED’’>
Sintassi:
<!ENTITY @ nome tipoBaseRestr ‘‘contentModel’’
listaAttributi>
tipoBaseRestr:
tipo complesso base da derivare per restrizione
contentModel:
contentmodel del tipo complesso
Tabella 3.6: Derivazione per restrizione
61
62
Una sintassi per documentare DTD++
Estensione
La derivazione per estensione permette di aggiungere valori al tipo base.
É possibile effettuare la derivazione per estensione anche aggiungendo solo
attributi
<!ENTITY @ personType ‘‘(firstname,secondname?)’’>
<!ENTITY @ person ‘‘@personType;’’
‘‘age #INTEGER #REQUIRED’’>
La nuova sintassi prevede anche la derivazione di un tipo complesso anonimo
associato ad un elemento.
<!ENTITY @ personType ‘‘(firstname)’’>
<!ELEMENT person (@personType;,(firstname,secondname?))>
Sintassi:
<!ENTITY @ ‘‘tipoBaseExt,contentModel’’ listaAttr>
<!ELEMENT nomeElemento (tipoBaseExt,contentModel)>
tipoBaseRestr:
tipo complesso base da derivare per estensione
contentModel:
contentmodel del tipo complesso
Tabella 3.7: Derivazione per estensione
3.2.4
Componenti locali e globali
Queste due notazioni permettono di definire elementi e tipi in maniera
locale o globale. In questo modo è possibile nascondere la definizione di una
componente o renderla riutilizzabile tramite il meccanismo di reference.
Componenti locali
In questo caso possono esistere in luoghi distinti elementi di tipo anonimo
con diversa definizione. Ad esempio gli elementi name e age sono dichiarati
3.2 Sintassi di DTD++
localmente al tipo person e sono, rispettivamente, di tipo string e di tipo
integer.
<!ENTITY @ person "(name,age)">
<!ELEMENT person.name #STRING>
<!ELEMENT person.age #INTEGER>
In un secondo tipo sarà quindi possibile associare sia a name che a age un
tipo differente
<!ENTITY @ personType "(name,age)">
<!ELEMENT personType.name #STRING>
<!ELEMENT personType.age #INTEGER>
In maniera analoga si può voler dichiarare un tipo anonimo e quindi localmente ad un elemento.
<!ELEMENT library "(book)">
<!ELEMENT book #STRING>
dichiara che library ha associato un tipo anonimo.
Sintassi:
<!ENTITY @ ‘‘(nomeElemento)’’ listaAttributi>
<!ELEMENT nome.nomeElemento tipoBase >
Tabella 3.8: Componenti locali
Componenti globali
Simmetricamente DTD++ consente di referenziare in maniera esplicita
gli elementi globali utilizzando il simbolo dollaro “$” come prefisso. Ad
esempio il tipo complesso person farà riferimento all’elemento globale age.
63
64
Una sintassi per documentare DTD++
<!ELEMENT age #INTEGER>
<!ENTITY @ person "($age)" >
Allo stesso modo è possibile definire tipi anonimi che fanno riferimento ad
elementi globali.
<!ELEMENT city #STRING>
<!ELEMENT people #INTEGER>
<!ELEMENT country ($city|$people)>
country avrà associato un tipo complesso anonimo che fa riferimento agli
elementi city E people entrambi globali.
Grazie a queste estensioni si sono potuti implementare i vari stili di progettazione di XML Schema permettendo di raggiungere, in DTD++, maggior
modularità e riuso dei componenti.
Sintassi:
<!ELEMENT nomeElemento tipoBase>
<!ENTITY @ nome ‘‘($nomeElemento)’’ listaAttributi>
<!ELEMENT nome ($nomeElemento)>
Tabella 3.9: Componenti globali
3.2.5
Elemento radice
Questo particolare componente permette di specificare che un elemento globale debba essere anche una radice. Come esempio viene riportato
il DTD++ equivalente al particolare stile di progettazione XML Schema
Russian Doll.
<!ROOT Recipe(ID,Ingredient*,Step*)>
<!ELEMENT Recipe.ID #cct:IDType;>
3.2 Sintassi di DTD++
<!ELEMENT Ingredient (ID,Amount,Name)>
<!ELEMENT Ingredient.ID #IDType;>
<!ELEMENT Amount #STRING>
<!ELEMENT Name #STRING>
<!ELEMENT Step (ID,Description)>
<!ELEMENT Step.ID #IDtype;>
<!ELEMENT Description #STRING>
Sintassi:
<!ROOT nomeElemento contentModel >
Tabella 3.10: Elemento radice
3.2.6
Element e Attribute Groups
Questi componenti permettono di dichiarare particolari entità, i gruppi di
elementi e di attributi i quali possono essere visti come dei contenitori globali
all’interno dei quali vengono dichiarati molteplici elementi o attributi.
Queste strutture vengono in aiuto nel momento in cui è necessario riutilizzare
più volte particolari sottoinsiemi di componenti.
I due costrutti sono entrambi dichiarati come entità e presentano una sintassi
simmetrica.
Group
I Group possono essere utilizzati nel content model di un tipo di un
elemento o di un altro Group. Ad esempio
65
66
Una sintassi per documentare DTD++
<!ENTITY @@ tuttiblocchi "div|p|img|table">
<!ELEMENT elem (@gerarchiabase;,(@@tuttiblocchi;)+)>
dichiara che l’element elem ha associato il tipo gerarchiabase che viene
esteso dal Group.
Sintassi:
<!ENTITY @@ nome ‘‘contentModel’’>
Tabella 3.11: Group
Attribute group
Sintassi:
<!ENTITY ## nome ‘‘listaAttr’’>
listaAttr:
attributeGroup sempre racchiuso tra ‘‘##’’ e ‘‘;’’
o nome Attributo (tipoBase) default
o nome Attributo tipoBase default
tipoBase:
predefinito o definito dall’utente
sempre racchiuso tra ‘‘#’’ e ‘‘;’’
Tabella 3.12: Attribute group
Gli attributeGroup possono essere associati ad un tipo complesso, ad un
element o ad un altro attributeGroup.
<!ENTITY @ hierarchy "(num?, title?)" "##corereq;">
<!ELEMENT noteref @markeropt; >
<!ATTLIST noteref num #STRING #REQUIRED ##link;>
In maniera simile ai Group, gli Attribute group contengono le definizioni di
gruppi di attributi come ad esempio l’attributGroup HTMLattrs contiene le
definizioni dei tre attribute class, style e title.
<!ENTITY ## HTMLattrs
"class #htmlclass; #IMPLIED
style #htmlstyle; #IMPLIED
title #STRING; #IMPLIED" >
3.2 Sintassi di DTD++
3.2.7
Substitution Group
I gruppi di sostituzione permettono di realizzare il polimorfismo, caratteristica tipica dei linguaggi Object Oriented.
Un elemento dichiarato substitution può essere usato, in maniera interscambiabile, al posto di un elemento globale detto head element. La sola
restrizione imposta è che i membri del gruppo di sostituzione e l’head element
siano dello stesso tipo o appartengano alla stessa gerarchia di derivazione.
Di seguito è presentato un DTD++ e l’istanza che lo valida.
<!TARGETNS ex "http://www.example.com">
<!ELEMENT book #STRING>
<!ELEMENT magazine ex:book>
<!ELEMENT library (ex:book)*>
<library xmlns="http://www.example.com">
<magazine>MSDN Magazine</magazine>
<book>Professional XML Databases</book>
</library>
Il content model dell’elemento library permette di dichiarare uno o più
elementi book, nell’istanza XML, laddove ci si aspetta magazine, si può
utilizzare l’elemento book.
Sintassi:
<!ELEMENT nomeSubstitutionGroup nomeElemento>
listaAttr:
<!ELEMENT nomeSubstitutionGroup nomeElemento tipo>
tipo:
stesso tipo o una valida derivazione
del tipo dell’head element
Tabella 3.13: Substitution Group
67
68
Una sintassi per documentare DTD++
3.3
DppDoc: Una sintassi Javadoc-style
DppDoc è un supporto di documentazione automatica per documenti
DTD++, che analizza le dichiarazioni interne creando in automatico un “albero documentativo” integrato in modo opportuno nel documento DTD o
XML Schema ottenuto in output.
In modo simile a Javadoc è in grado di riproporre lo “scheletro” del documento DTD++ completamente spogliato dell’implementazione vera e propria.
Inoltre è possibile arricchire questo scheletro con chiarimenti, precisazioni e
molti altri dettagli per mezzo di speciali commenti. L’interfaccia d’output
per la conversione in formato consultabile è predisposta per essere adattata con qualsiasi convertitore in grado di interpretare i tag commenti DTD e
XML. Un convertitore può essere un foglio di stile XSL che, con l’ausilio di un
engine xslt, intercetti i tag XML che compongono l’albero DppDoc per poterli trasformare ad esempio in un documento HTML con una struttura molto
simile a quella generata da Javadoc, ma anche un qualsiasi altro sistema
automatico che riesca a interpretare ed elaborare le informazioni contenute
all’interno di un marcatore commento per generare in output documenti opportunamente trasformati.
In questa prima versione l’albero documentativo generato in output da DppDoc è stato interfacciato per essere interpretato dal generatore di documentazione ROBODoc distribuito sotto licenza GPL introdotto nel primo capitolo.
Le principali caratteristiche di DppDoc sono:
• Generazione di un albero documentativo su cui sono definite le informazioni base di ciascuna dichiarazione DTD++ presente nel documento.
• Possibilità di arricchire con ulteriori informazioni la documentazione
tramite l’inserimento di commenti “dppdoc” e una semplice e intuitiva
sintassi.
• Trasformazione in output dell’albero documentativo con ROBODoc in
un set di documenti facilmente consultabili.
3.3 DppDoc: Una sintassi Javadoc-style
3.3.1
69
Contesto e contenuto: i parametri dppDoc
Come già è stato accennato DppDoc è in grado di fornire automaticamente le informazioni basi su ciascuna definizione e dichiarazione DTD++
tramite un analisi lessicale del documento. Queste informazioni possono essere arricchite da ulteriori dettagli a discrezione dello sviluppatore per mezzo
di speciali commenti “dppdoc”. Il tag dppdoc strutturalmente è identico a
quello dei commenti usati per i documenti XML “<!--- ...
-->”, con l’u-
nica differenza di avere tre trattini, invece di due, nella sequenza di apertura.
I commenti vengono riconosciuti e processati dal preValidator solo se immediatamente precedenti la dichiarazione di un qualunque componente DTD++.
La sintassi DppDoc si fonda principalmente sull’utilizzo di speciali parametri che possono essere di due tipi:
• parametro sul contesto o informativi;
• parametro sul tag.
L’obiettivo è fornire il massimo della flessibilità nel scegliere la forma e il
contenuto più idonei alla documentazione.
I parametri informativi
I parametri informativi sono preceduti dal simbolo “@” e “intitolano” il
paragrafo immediatamente successivo. La loro funzionalità si allinea a quella
offerta dai parametri usati in Javadoc. Fornire un riferimento al contesto:
lo scopo è poter “plasmare” la forma di rappresentazione in base al tipo di
argomento che si vuole documentare.
I parametri sul tag
La vera novità di DppDoc risiede però nell’adozione del parametro sul
tag, con il quale è possibile “arricchire” la semantica delle proposizioni vere e
70
Una sintassi per documentare DTD++
proprie: forniscono le informazioni più importanti del tag, ad esempio il tipo
(se è un attributo, un element o un entità), il nome, il content model o gli
attributi. L’ausilio di questi parametri semplifica notevolmente il riferimento
esplicito alle caratteristiche principali durante la stesura vera e propria della
documentazione.
I parametri sul tag sono preceduti dal simbolo “#” e possono essere utilizzati
in numero arbitrario all’interno di una frase. La documentazione, arricchita
con questi parametri addizionali, può essere vista come uno speciale content
model misto.
Sintassi:
...
<!--@parInf
(#PCDATA|#parTag|#parTag|...)*
@parInf
(#PCDATA|#parTag|#parTag|...)*
.
.
.
@parInf
(#PCDATA(#parTag|#parTag|...)*)
-->
<!ELEMENT name contentmodel
>
...
@parInf:
parametro informativo
#parTag:
parametro sul tag
#PCDATA:
frasi scritte in linguaggio naturale
(#PCDATA(#parTag|#parTag|...)*):
Documentazione
Tabella 3.14: Struttura sintattica del commento dppdoc
3.3 DppDoc: Una sintassi Javadoc-style
Figura 3.1:
Esempio di commento DppDoc su DTD++ e la relativa
proiezione in HTML
71
72
Una sintassi per documentare DTD++
Tag
Descrizione
@author
Nome dell’autore
@usage
Come utilizzare il componente
@description
Descrizione sulle caratteristiche principali
@purpose
Descrizione sugli scopi di funzionamento
@creationdate
La data in cui è stato definito
@history
Le modifiche che ha subito e chi le ha effettuate
@example
Esempio di utilizzo
@notes
Note aggiuntive
@warnings
Messaggi warning
@errors
Messaggi d’errore
@bugs
Bugs conosciuti
@seealso
Riferimenti ad altri componenti o a eventuale documentazione esterna
Tabella 3.15: i parametri informativi
Tag
Descrizione
#type
Il tipo del tag (Element, Entity Complex, Attlist ...)
#name
Il nome del tag
#instance
Rappresentazione schematica del tag in XML Schema
#content
Rappresentazione schematica del content model in XML Schema
#attribute
La lista degli attributi
#refelement
L’Element a cui si riferisce la lista di attributi
Tabella 3.16: i parametri sul tag
3.3 DppDoc: Una sintassi Javadoc-style
Figura 3.2: Due esempi di documentazione DppDoc in formato HTML
73
74
Una sintassi per documentare DTD++
Capitolo 4
Dettagli implementativi
In questo capitolo viene descritta l’implementazione del preprocessore per
la validazione di documenti XML tramite documenti DTD++.
Per permettere una maggiore portabilità, il preprocessore è stato sviluppato
in linguaggio Java.
La validazione è effettuata direttamente dal PreValidator richiamando un
validatore esterno. Come validatori sono stati utilizzati MSXML e Xerces,
ma con semplici modifiche è possibile utilizzare altri validatori.
La capacità del PreValidator di convertire un documento DTD++ in un documento XML Schema o DTD indica come le scelte di realizzazione sono
orientate per fornire la predisposizione al supporto di sistemi di conversione
anche per altri linguaggi quali ad esempio Relax NG o Schematron.
4.1
Flusso del programma
Il file DTD++ viene caricato dal disco e passato alla classe DppDocManager che indicizza il file per righe. Successivamente il lexer riceve il documento
e ne estrae le entità parametriche.
Nel caso in cui sia richiesta la conversione a XML Schema, le entità parametriche saranno sostituite. Al contrario, in una conversione a DTD le entità
75
76
Dettagli implementativi
parametriche verranno mantenute. Il lexer, inoltre, inserisce in liste separate
i nomi dei tipi semplici, dei tipi complessi, degli attributeGroup e dei Group
per poter controllare che componenti referenziate siano state dichiarate nello
stesso o in altri documenti DTD++. Se viene incontrata un’entità SYSTEM,
il lexer si blocca mantenendo settati i parametri, carica il file associato all’entity SYSTEM e lo processa. Stessa cosa se viene trovata un’entity PUBLIC
ed è richiesta una conversione a DTD. Una volta che il documento è stato
elaborato dal lexer, viene passato al parser. Al termine del parsing viene cosi
restituito un vettore contenente la lista dei tag. Da questa lista vengono poi
estratti i tipi, le attributeList, gli attributeGroup e i Group. AttributeGroup
e attributeList vengono successivamente associati agli elementi relativi.
A questo punto la struttura è pronta per emettere la trasformazione del documento in schema o in DTD. Nel passo successivo la lista dei tag viene scorsa
e ogni singolo tag emette il proprio schema o DTD. Se si vuole validare il
documento ed è stato generato uno schema. viene richiamato il validatore
esterno che valida il documento. Gli errori generati dal validatore vengono
intercettati dal preprocessore che, tramite il DppDocManager, risolve i numeri di linea e restituisce gli errori sullo standard output con numeri di riga
relativi al dpp.
4.2
Tecnologie utilizzate
Per la realizzazione del preprocessore sono state utilizzate diverse tecnologie esterne:
• due parser che si occupano della lettura e elaborazione dei tag DTD++:
JFlex
1
e Javacup 2 ;
• MSXML
3
e Xerces
4
per la validazione.
1
http://www.jflex.de/
http://www2.cs.tum.edu/projects/cup/
3
http://www.microsoft.com/downloads/details.aspx?familyid=993C0BCF-3BCF2
4009-BE21-27E85E1857B1&displaylang=en
4
http://xml.apache.org/xerces-c/
4.2 Tecnologie utilizzate
77
Leggere ed elaborare una sintassi: Lex e Yacc
Un interprete di linguaggio come il PreValidator è composto da due parti
che si occupano di:
1. leggere il codice sorgente analizzando la struttura sintattica;
2. elaborare questa struttura per generare il risultato finale in output.
Queste due fasi sono fondamentali per interpretare dei dati descritti in un
linguaggio e rappresentarli in un altro: si decompone la struttura sorgente
in token (Lex) per elaborare successivamente l’albero gerarchico risultante
(Yacc) avendo come base di analisi i token estrapolati.
Lex - A Lexical Analyzer Generator
Il Lex
5
è una grammatica utilizzata per implementare scanner (Lexer)
che analizzano un flusso dati in input. Si avvale delle regular expressions per
l’intepretazione: durante la lettura il Lexer effettua dei match sul documento
in base ad una tabella di regular expression definita in fase di inizializzazione; ciascun match equivale ad un token il quale viene dato in output per
l’elaborazione vera e propria, di solito effettuata da parser scritti in Yacc.
Ci sono diversi compilatori che convertono un sorgente Lex in compilati per
diversi linguaggi: il più famoso è il Flex
6
che genera scanner Lex in codice
C.
Esiste inoltre un altro compilatore equivalente al Flex, il JFlex, che ha come
differenza quella di generare scanner scritti in codice Java. Il JFlex è stato
utilizzato per compilare i sorgenti lexer utilizzati nel PreValidator.
Yacc: Yet Another Compiler Compiler
Lo Yacc
7
è un linguaggio utilizzato per interpretare ed elaborare i dati
ricevuti in input. A differenza del Lex, lo Yacc non si presuppone come uno
5
http://dinosaur.compilertools.net/lex/index.html
http://plan9.bell-labs.com/magic/man2html/1/lex
7
http://dinosaur.compilertools.net/yacc/index.html
6
78
Dettagli implementativi
scanner vero e proprio, ma come un interprete di informazioni che, ricevute
in modo opportuno da appositi componenti, ad esempio uno scanner Lex, è
in grado di elaborare i dati con specifiche funzioni e subroutine gerarchiche.
JavaCup è il compilatore utilizzato per la generazione del parser Yacc del
PreValidator.
Sistemi di validazione: MSXML e Xerces
MSXML
MSXML è una API di Microsoft basata su COM per parsare e processare
documenti XML. La versione utilizzata include il supporto per il DOM Level
2.0, SAX 2.0, XPath, XSLT e XSD Schema. Per utilizzare MSXML è stata realizzata un’applicazione in C# che effettua l’operazione di validazione.
Viene preso in input un file XML e un file XML Schema, si effettua la validazione utilizzando le classi XMLSchemaCollection e XMLValidatingReader
e vengono restituiti sullo standard error gli eventuali errori.
Xerces
Xerces Java è un progetto open-source che nasce come discendente diretto di XMLJ4 di IBM e si prefisse l’obiettivo di creare un parser validante
per documenti XML. Fa parte del progetto Apache. Per utilizzarlo come
validator è stato utilizzato il GTRI Validation Tool 1.1. Il tool è stato realizzato dalla Georgia Tech Research Corporation ed è scritto interamente in
java. Fondamentalmente è un programma che si limita a rendere Xerces un
validator XML standalone.
4.3 Il programma
4.3
Il programma
Il programma è strutturato all’interno del package preValidator che contiene le main class PreValidator.class e sei package:
• preValidator.documents: contiene le classi che gestiscono i file DTD++
e XML;
• preValidator.types: contiene le classi che gestiscono i tipi del documento DTD++;
• preValidator.errors: contiene le classi che gestiscono i messaggi di errore;
• preValidator.parsers: contiene le classi che effettuano lo scanning e il
parsing;
• preValidator.parserStruct: contiene le classi che gestiscono la strutturazione e la rappresentazione del documento da generare;
• preValidator.utils: contiene una serie di classi di varia utilità.
4.3.1
Il default package: preValidator
Il default package contiene la main class PreValidator. Tramite il metodo
pubblico Start viene presa in input la lista degli argomenti e si effettuano
le chiamate alle operazioni necessarie a trasformare e validare i documenti.
Dopo aver processato gli argomenti con il metodo getArgs, viene inizializzato
il DppDocManager e le strutture dati relative alla gestione degli errori. Successivamente viene richiamato il metodo Process che effettua l’operazione di
parsing e di generazione dello schema o del DTD. Se necessario, poi, prepara
una versione modificata del documento XML e grazie al metodo Validate il
documento viene validato. Al termine si eliminano i file temporanei e, se
richiesto, viene stampato sullo stdout la conversione generata. Vi sono poi
due code in cui vengono salvati i nomi dei file dichiarato con un’entity SYSTEM o PUBBLIC. Quando le operazioni sul file principale sono terminate,
79
80
Dettagli implementativi
Start richiama il metodo pubblico getInclude in cui si scorre la lista dei file
referenziati tramite un’entity SYSTEM. Questi, a loro volta, vengono processati e opportunamente convertiti. Se è richiesta una conversione a DTD,
allora lo stesso procedimento viene ripetuto anche per i file definiti con le
entity PUBLIC.
4.3.2
preValidator.documents
Nel package preValidator.documents sono contenute le classi che si occupano della gestione dei documenti.
DppDocManager
DppDocManager realizza la gestine del file dpp. Prende in input il documento e tramite il metodo process, lo separa per linee utilizzando un vettore
di LineItem. Terminate queste operazioni, il documento è pronto per essere
passato al parser che andrà a creare il DOM da cui si otterrà l’opportuna
conversione. getPostLineByLine è un metodo che permette di ottenere i riferimenti ai numeri di riga del documento originale utilizzati dal preprocessore
per poter elaborare gli errori restituiti dal validatore.
DppLineItem
Gestisce il riferimento tra i numeri di riga attraverso le fasi di trasformazione del documento.
XmlDocManager
Gestisce il file XML da validare. Il metodo setSchemaRef genera una versione modificata dell’XML inserendo gli attributi xmlsn:xi e xsi:noNameSpaceLocation
all’interno del primo tag XML.
4.3 Il programma
4.3.3
preValidator.types
Questo package contiene le classi che si occupano della gestione dei tipi
del documento DTD++.
TypeList
TypeList gestisce la lista dei tipi, degli AttList, degli AttributeGroup e
dei Group. Ad ogni tag estratto dal dpp corrisponde un tipo che viene inserito nella lista con il metodo addType. Se il tag corrisponde ad un AttList,
si utilizza il metodo addAttGroup. I tipi, gli AttList, gli AttributeGroup
e i Group vengono inseriti in una Hashtable. Una volta riempita la struttura dati, i metodi linkGroup e linkEntityGroup associano, rispettivamente,
gli AttList e gli attributeGroup ai relativi tipi. linkSubGroup, linkSubstitutionGroups e createEntitySubstitutionGroup intervengono quando ci sono dei
substitutionGroup per poter effettuare una corretta conversione a DTD. Vi
sono poi dei metodi che effettuano ricerche all’interno della struttura: getType permette di estrarre l’oggetto Type relativo, getStringType restitutisce
il nome da inserire nello schema o nel DTD, getBaseType restituisce il nome
del tipo da cui è derivato, getOriginalType restituisce il nome del tipo base.
Il metodo initPredefined, richiamato dal costruttore della classe, inizializza i
tipi predefiniti.
Type e classi derivate
Queste classi definiscono i tipi dei tag. Contengono il nome del tag, la
stringa da inserire nella generazione dello schema o del DTD.
ParametricList
Gestisce le entità parametriche. Il metodo put inserisce le entità parametriche nella lista specificandone la chiave, i valori, il tipo e la posizione
all’interno del file di origine. Si è resa ParametricList una classe Singleton
per permettere l’utilizzo delle entità parametriche in file diversi da quello in
81
82
Dettagli implementativi
cui sono dichiarate. Con il metodo adjustList si effettuano le sostituzioni
all’interno della lista stessa.
I metodi getValue e getKey permettono di estrarre rispettivamente il valore
e la chiave dell’entità parametrica e restituiscono nulla altrimenti. Tramite
il metodo getFileName è possibile ottenere il nome del file di appartenenza
dell’entità desiderata.
ScannerFileListCache
Classe Singleton che tiene traccia dei file da processare. Il metodo statico
getInstance permette di avere una sola istanza della classe. L’Hashtable hash
contiene la lista dei file. Tramite il metodo pubblico addFileName si inserisce
il nome di un file all’interno della HashTable e tramite exist si controlla se è
già presente un file con lo stesso nome. Con il metodo pubblico getFileName
vengono ritornate le chiavi della HashTable.
4.3.4
preValidator.errors
Contiene le classi per la gestione dei messaggi di errore.
ErrorValue
Definisce l’errore e contiene i metodi per la stampa dei messaggi d’errore.
Costruttori differenti permettono di costruire l’errore definendone il tipo, la
posizione di inizio e fine dell’errore, una serie di valori da visualizzare al
momento della stampa e un livello di criticità dell’errore. Con il metodo
toString si ricava la stringa d’errore con un preciso riferimento alla riga in
cui è avvenuto tale errore.
ErrorType
La classe ErrorType definisce le varie tipologie d’errore tramite una serie
di valori statici.
4.3 Il programma
ErrorList
Gestisce la lista degli errori. Il metodo addElement permette di aggiungere un ErrorValue. size ritorna il numero degli errori e clear azzera lo stato
della lista. Con il metodo toString si crea, invece, una stringa che contiene
lo stato d’errore degli ErrorValue contenuti nella lista.
ErrorConverter
Classe astratta che elabora i messaggi d’errore restituiti dal validatore. Le classi derivate implementano il metodo ElaborateError che esegue
l’operazione di trasformazione.
4.3.5
preValidator.parsers
Contiene le classi che effettuano lo scanning e il parsing.
JFlex e JavaCup generano automaticamente le classi partendo dai seguenti
file:
• parametric.flex: genera le classi per la gestione delle entità parametriche. Quando si incontra un’entity SYSTEM o PUBLIC lo scanning
del file corrente si interrompe e si processa il file riferito. Ogni entità
parametrica, tipo, group o attributeGroup incontrato viene inserito
in una propria coda per permettere che una componente possa essere
richiamata ed utilizzata in un file differente da quello in cui è dichiarata.
• parser.flex genera le classi del lexer incaricato alla lettura del documento DTD++ dato in input e alla creazione dei token necessari allo
Yacc.
• parser.par genera le classi del parser Yacc incaricato alla interpretazione
dei token lex per la creazione degli oggetti java dei tag.
83
84
Dettagli implementativi
4.3.6
preValidator.utils
Package contenente classi di vario tipo utilizzate dal programma per la
stampa e l’accesso al disco.
Debug
Classe per la stampa dei messaggi di debug del parser yacc e del lexer.
Disk
Classe che gestisce gli accessi al disco. Il metodo LoadFromFile carica
un file di testo dal disco e restituisce in una stringa il suo contenuto. I due
metodi, entrambi chiamati SaveToFile, salvano il contenuto di una stringa
sul disco e differiscono per il numero di parametri presi in input. Nel secondo
è infatti possibile specificare il nome della directory in cui salvare il file.
IndentSchema
IndentSchema gestisce l’indentazione nella generazione dello schema. Il
campo numTab tiene memoria del numero di indentazioni in un dato momento. Tale valore viene aumentato o diminuito grazie ai metodi addTab
e delTab. Con il metodo getTab si restituisce la stringa da anteporre alla
corrente riga dello schema.
PrintSchema
Classe di utility per la stampa dello schema. Il metodo statico countLine
conta le righe di una stringa.
TemporaryNames
Si occupa della generazione di elementi temporanei.
4.4 Il package “motore”: preValidator.parseStruct
85
Verbose
Classe utilizzata per la stampa della modalità verbose.
4.4
Il package “motore”: preValidator.parseStruct
In questo package sono contenute le classi che gestiscono la strutturazione
e la rappresentazione di un documento DTD++, affinchè possa essere convertito in un documento DTD o XML Schema. E’ l’area di codice su cui
è stata fatta la maggior parte del lavoro implementativo. Oltre al sistema
integrato della documentazione, infatti, sono state aggiunte delle classi per
permettere la corretta gestione dei whitespace (spazi bianchi, tabulatori) in
fase di formattazione finale e per fornire il supporto dei componenti schema
di tipo astratto.
La sezione è suddivisa in tre parti:
1. la prima descrive le caratteristiche generali di ciascuna classe;
2. si prosegue con una sintetica descrizione sulle classi per la gestione dei
whitespace e sul supporto dei componenti astratti;
3. per concludere infine con una esauriente descrizione della classe DppDoc.
4.4.1
Caratteristiche delle classi
Tags
Classe contenitore di tutti i tag. Il campo items contiene i tag generati
dal parser. Nella conversione a XML Schema l’ordine dei tag è quello in cui
sono stati trovati nel file d’origine. Invece nella conversione a DTD,l’ordine
può cambiare se un’entità è usata prima di essere stata dichiarata o se viene
creata per permettere un corretto DTD. Il campo declaration contiene ciò che
va posto all’inizio del documento generato. Il campo typeList contiene la lista
86
Dettagli implementativi
dei tipi, degli attribute, degli attributeGroup e dei Group e viene inizializzata
tramite il metodo iniTypeList. Se è richiesta una conversione schema secondo
lo stile Venetian Blind, Garden of Eden o Russian Doll vengono richiamati
rispettivamente i metodi initTypeListVB, iniTypeListGE, initTypeListRD.
getDocType e getNameSpace restituiscono il primo il valore da inserire all’interno del tag DOCTYPE dello schema, il secondo una stringa contenente il
namespace dello schema. CreateNewFile richiama altri metodi e va a creare
i file schema corrispondenti ai namespace dichiarati.
ContentModel
Classe astratta che definisce il content model. I seguenti campi definiscono
i facet del content model:
• cardinality, le occorrenze minime e massime;
• length, la lunghezza minima, massima o esatta dell’elemento, in caso
di numeri decimali definisce il numero di cifre intere e decimali;
• range, il valore minimo e massimo, inclusivo e non inclusivo, che il
valore può assumere;
• pattern, un’espressione regolare;
• enumeration, una lista di valori;
• whitespace, la gestione degli spazi bianchi.
Il vettore Childs permette di associare al content model altri content
model. In questo modo si crea una struttura ad albero. Se il vettore è
vuoto, è necessario specificare un valore nel campo value. Si identifica, cosı̀,
il content model corrente come foglia all’interno dell’albero. Il metodo add
aggiunge facet o altri child. Per ereditare i facet da un altro content model,
senza sovrascrivere facet già esistenti, si utilizza il metodo setCard. setItem
4.4 Il package “motore”: preValidator.parseStruct
87
permette di impostare direttamente il vettore dei childs ed è utilizzato in fase
di generazione del DOM del parser.
Il campo isAnonumous definisce se il content model è di tipo anonimo. In
caso affermativo la conversione a schema conterrà un <simpleType> se di tipo
semplice e un <complexType se di tipo complesso. Tramite i booleani isGlobal
e isLocal si specifica se il content model deve essere dichiarato globalmente o
localmente.
SimpleContentModel
Definisce il content model di un tipo semplice. Il campo simplebaseType
definisce il tipo da cui deriva e deve essere sempre definito. isList indica se il
content model debba comportarsi o meno come una lista. Il booleano empty
settato a true identifica il content model senza contenuto e genera un tag di
tipo empty.
ComplexContentModel
Definisce il content model di tipo complesso. In base al valore del campo type vengono gestiti i content model contenuti all’interno del vettore
childs. CM TYPE CHOICE realizza uno schema o un dtd di tipo choice,
CM TYPE SEQ di tipo sequence, CM TYPE ALL di tipo all. In caso di
conversione a DTD il tipo CM TYPE ALL realizza un DTD di tipo choice.
Ad esempio
<!ENTITY @ uno "a & b & c">
diventerà
<!ENTITY % uno "(a,b,c)|(a,c,b)|(b,a,c)|(b,c,a)|(c,a,b)|(c,b,a)" >
Se di tipo CM TYPE VALUE viene restituito un tag schema o DTD di tipo element che riferisce ad un tipo base definito nel campo value. CM TYPE ANY
88
Dettagli implementativi
realizza uno schema o un DTD di tipo any. Il tipo di any viene registrato
nel campo anyType e la lista dei namespace nel vettore anyNameSpaceList.
Il boolean isMixed, infine, indica se si tratta di un content model misto.
ComplexReferenceContentModel
Questa classe definisce un content model che ha come unico elemento un tipo complesso. Viene utilizzato nelle dichiarazioni di elementi che
contengono un’entità complessa
<!ELEMENT nomeElemento (@tipocomplesso;)>
ComplexContentModelProperty
Permette una derivazione per estensione anonima. Viene, quindi, usato
nelle dichiarazioni di elementi del tipo
<!ELEMENT a (@tipo;,b)>
Il campo derivedType identifica il nome del tipo da cui deriva, mentre il
booleano derivedType isMixed è posto a true se il tipo da cui deriva ha content
model misto.
Group
Definisce il content model di un Group.
In base al valore del cam-
po type vengono gestiti i content model contenuti all’interno del vettore
childs. CM TYPE CHOICE realizza uno schema o un dtd di tipo choice,
CM TYPE SEQ di tipo sequence.
Tag
Classe astratta da cui derivano tutte le classi relative ai tag del DTD++.
I campi left e right contengono la posizione iniziale e finale del tag all’interno del documento DTD++. Il metodo astratto getSchema permette, per
ciascuna delle classi derivate. di restituire una rappresentazione in XML
4.4 Il package “motore”: preValidator.parseStruct
Schema della propria struttura. getSchemaRD, getSchemaVB, getSchemaGE, getSchemaSS rendono possibile la conversione secondo gli stili Russian
Doll, Venetian Blind, Garden of Eden e Salami Slice. Analogamente il metodo astratto toDtd permette ad ogni classe derivata, una rappresentazione in
DTD. I booleani isLocal e isGlobal identificano, rispettivamente, il tag come
locale o globale. Il campo style memorizza lo stile XML Schema da utilizzare. current file, current prefix e namespaceList, invece, vengono utilizzati
quando si crea un XML Schema e vi sono differenti namespace.
AttList
Classe che definisce un’attlist. Genera degli attribute all’interno di un
tipo complesso. Il campo attributes è un vettore di classi Attribute, il campo
name è una stringa con il nome dell’attributeGroup.
Attribute
Definisce un attribute. Il campo name contiene il nome dell’attributo,
contentModel il Content Model e defaultValue il valore di default dell’attributo.
AttributeDefault
Classe che definisce il valore di default di un attribute. Il campo type
contiene il tipo di attributo e può assumere i valori REQUIRED, IMPLIED,
FIXED e DEFAULT. Il valore di default dell’attributo viene invece settato
nel campo value.
AttributeVector
Classe contenente un vettore di attribute. I metodi pubblici add e remove
permettono di aggiungere o rimuovere un attribute dalla lista. Con getAttributeByName si recupera la posizione dell’attribute all’interno della lista
altrimenti viene restituito -1.
89
90
Dettagli implementativi
EntityCharRef
Classe che definisce l’entità interna del DTD.
EntitySimple
Classe che definisce un’entity simple. Viene creata indicando il nome e il
content model. Se deriva da un’altra entity il metodo getParent restituisce
una stringa contenente il nome dell’entity da cui deriva. All’interno del campo simpleContentModel viene definito il content model. Il metodo isUnion
restituisce true se il content model è di tipo union.
EntityComplex
Classe che definisce un’entity complex. Il nome dell’entità è contenuto nel
campo name, mentre il vettore attlist contiene una lista di oggetti Attribute.
La gestione del content model è delegata interamente al campo property di
tipo EntityComplexProperty. Il booleano isCreated è settato a true se l’entità
è stata creata per poter gestire uno stile di rappresentazione XML Schema.
EntityComplexProperty
Classe che definisce le proprietà di un tipo complesso. Nel caso in cui
il tipo derivi per restrizione o estensione vengono settati rispettivamente a
true i campi isRestricted e isExtended e viene assegnato il nome del tipo da
cui si ereditano le proprietà nel campo derivedType. Il campo contentModel
contiene il riferimento al content model del tipo. I costruttori permettono
di creare un tipo non derivato o derivato per estensione. Per effettuare una
derivazione per restrizione è necessario chiamare il metodo setRestriction
dopo la creazione dell’oggetto. Il metodo getIsMixed ritorna true nel caso in
cui il content model sia di tipo mixed mentre il booleano derivedType isMixed
informa se il tipo da cui deriva ha content model mixed oppure no.
4.4 Il package “motore”: preValidator.parseStruct
EntityAttlist
Classe che definisce un attributeGroup. Il campo name contiene il nome
dell’attributeGroup mentre attlist è il vettore degli attributi.
EntityGroup
Classe che definisce un Group. La stringa name contiene il nome del
group mentre il campo contentModel contiene il riferimento al content model
del Group.
EntityGroupProperty
Definisce le proprietà di un Group. Il campo contentModel contiene il
riferimento al content model del Group.
EntityParametric
Classe che gestisce le entità parametriche. Utilizzata in conversione a
DTD. Il campo name contiene il nome dell’entità. Il booleano isCreated è
settato a true quando l’entità viene creata per gestire i substitutionGroup in
DTD. Il campo att contiene la lista degli attributi.
EntitySystem
Classe che gestisce le entità SYSTEM o PUBLIC. Viene utilizzata per la
conversione a DTD. La stringa name contiene il nome dell’entity e il campo isPublic, se settato a true, indica che si tratta di un’entity PUBLIC.
Altrimenti sarà di tipo SYSTEM.
FacetCardinality
Classe che definisce il numero di occorrenze del content model. Genera
la stringa maxOccurs=x minOccurs=y all’interno dei tag schema.
91
92
Dettagli implementativi
FacetEnumeration
Classe che definisce un facet di tipo Enumeration. Il campo items contiene
la lista dei valori di enumerazione.
FacetLength
Classe che definisce un facet per la lunghezza delle stringhe e le caratteristiche dei numeri decimali. Viene stampato, in maniera esclusiva, il facet
length o i facet minLength e maxLenght o i facet totalDigits e fractionDigits.
FacetPattern
Classe che definisce un facet per la definizione dei pattern.
FacetRange
Classe che definisce un facet per il range dei numeri. I valori possono
essere di tipo inclusivo o esclusivo.
FacetWhiteSpace
Classe che definisce un facet di tipo WhiteSpace.
Pair
Classe che rappresenta una coppia di valori separati da un punto o da
una virgola. Viene utilizzata dalle classi FacetRange, FacetCardinality e
FacetLength per assegnarne i rispettivi valori.
Element
Classe che definisce un element. Il campo name contiene il nome dell’elemento mentre il campo contentModel memorizza il content model. Se
il booleano attGroup è impostato a true allora l’element avrà associato degli attribute o farà riferimento ad attributeGroup. Il campo occurs di tipo
4.4 Il package “motore”: preValidator.parseStruct
FacetCardinality definisce le occorrenze. Il booleano root settato a true permette di identificare l’elemento come root. name1 è una stringa che viene
utilizzata per memorizzare il nome del tipo in cui l’elemento viene dichiarato
in maniera locale o il nome dell’element substitution. In quest’ultimo caso
il campo isSubstitution sarà settato a true a significare che si tratta di un
element substitution.
SchemaPathState
Classe che gestisce SchemaPath.
Comment
Classe che definisce il Tag commento. Il valore viene inserito comprensivo dei tag di inizio e fine commento dei DTD che vengono poi filtrati
direttamente dal costruttore.
TargetNS
Classe che definisce il Tag TARGETNS.
4.4.2
Gestione dei whitespace e dei componenti astratti
In questa nuova versione del preValidator oltre a essere stati risolti molti
bug in fase di formattazione finale, sono state aggiunte delle classi dedicate per la corretta gestione dei whitespace: in precedenza se nel documento
DTD++ l’utente aggiungeva dei tabulatori o degli spazi bianchi personalizzando l’indentazione con lo scopo di aumentarne la leggibilità, in conversione
DTD queste informazioni aggiuntive andavano perse nelle fasi di conversione.
Questo problema è stato risolto facendo alcune modifiche al lexer, al parser
e con l’aggiunta di due classi dedicate per i whitespace.
In fase di lettura è stata aggiunta una nuova regular expression affinchè il lexer possa creare un token dedicato; successivamente è stato adattato il parser
93
94
Dettagli implementativi
Yacc in modo che il token whitespace venisse riconosciuto e opportunamente
interpretato come un normale tag, “impacchettandolo” in un oggetto java.
Le classi whitespace sono di due tipi:
• la classe WhiteSpace gestisce quelli che separano i tag DTD esternamente l’uno all’altro, detti anche whitespace esterni;
• la classe WhiteSpaceInside gestisce i whitespace all’interno di un tag
DTD (“<” “>”) con l’ausilio di un vettore sul quale vengono accodati
in sequenza. Sono detti anche whitespace interni.
Un’altro importante supporto implementato in questa ultima versione
è stato quello sui componenti di tipo astratto.
Per fare questo è stato
necessario:
1. adattare il lexer affinchè interpretasse la nuova sintassi dedicata: individuata nel “$” (dollaro) per gli abstract element e nel “@$” (chiocciola
dollaro) per gli abstract entity complex;
2. apportare alcune modifiche nelle subroutine del parser yacc per l’interpretazione dei tag element ed entity complex;
3. adattare le classi java Element e EntityComplex in modo opportuno
con l’aggiunta della variabile booleana abstract.
4.4.3
La classe DppDoc
La classe DppDoc definisce gli header della documentazione.
Ci sono due tipi di costruttori:
• il primo costruisce l’oggetto ricevendo in input una stringa value. E’
chiamato dal parser Yacc quando è intercettato un commento Dppdoc;
• il secondo costruisce un oggetto DppDoc vuoto: chiamato dall’algoritmo per la creazione automatica degli header dppdoc base.
4.4 Il package “motore”: preValidator.parseStruct
Questa distinzione di costruttori è un punto cruciale ai fini della logica di
funzionamento. In questo modo si vuole distinguere concettualmente la definizione di header dichiarato manualmente nel documento, dall’header creato
automaticamente dal PreValidator (header base) ai fini della strutturazione
dell’albero base della documentazione.
Ci sono quindi due modalità di elaborazione: manuale e automatica.
In questa sezione si vogliono fornire i dettagli implementativi del sistema integrato DppDoc suddividendo l’argomentazione in due parti. La prima parte
fornisce le caratteristiche principali sulle variabili e i metodi utilizzati dalla
classe DppDoc; la seconda descrive le fasi di elaborazione dell’albero documentativo finale.
4.4.4
Caratteristiche principali
La creazione di un header DppDoc necessita di una serie di variabili per
garantire univocità tra l’header e il tag da documentare; per estrapolare i
dati riguardanti il tag e infine per distinguere se l’header è generato automaticamente o dichiarato sul documento DTD++. IDTAG crea un legame
biunivoco tra l’header DppDoc e il componente , nel campo tagToken risiede
l’oggetto del tag cui l’header è associato, mentre il booleano automatic se
è settato a false identifica un header generato a partire da un commento
dppdoc dichiarato nel documento.
Questi tre tipi di informazioni sono fondamentali per assicurare la massima
coerenza tra l’header dppdoc e il tag cui fa riferimento, garantendo una corretta estrapolazione delle informazioni della documentazione senza casi di
ambiguità.
Sui campi di tipo stringa valueManual, valueAuto e value avviene la creazione vera e propria dell’header seguendo l’approccio tipico di una catena di
montaggio: ad ogni fase di elaborazione si effettua un accodamento progressivo di stringa. Su valueManual vengono accodate le informazioni definite
95
96
Dettagli implementativi
manualmente su un commento DppDoc; su valueAuto le informazioni base
del tag estrapolate automaticamente. Questi due campi vengono infine concatenati e memorizzati in value, il risultato finale dell’elaborazione ritornato
in output in fase di scrittura.
Le fasi di concatenamento della stringa sono affidati a tre metodi pubblici:
• createDppTag() inizializza l’header analizzando il tag bersaglio memorizzato su tagToken;
• setParInput() inserisce le informazioni sui namespace dichiarati, setta le informazioni sul tipo e il nome del componente, infine setta il
tipo di sezione dell’header (informazione utilizzata da Robodoc per
l’indicizzazione della documentazione);
• setParOutput() chiama i metodi privati elaborateContentModel(), elaborateAttribute(), elaborateInstance() e setParInf() per inserire le informazioni riguardo il content model, la lista degli attributi, la struttura di rappresentazione schema del componente DTD++ e i paragrafi identificati dai parametri informativi contenuti in un commento
dppdoc.
setParInput() è chiamata in fase di inizializzazione da createDppTag(),
mentre setParOutput() è chiamata durante la fase finale di scrittura da
toDtd() o getSchema()).
Il booleano automatic segnala al preValidator il tipo di header che si sta
elaborando. Se è settato a true significa che non è stato dichiarato nel documento DTD++, quindi risulta un header base, altrimenti viene abilitata
l’elaborazione del “valore grezzo” estrapolato dal parser Yacc su un commento dppdoc.
A causa della struttura ad albero di XML Schema e per garantire la regola sintattica scelta secondo cui un header DppDoc deve essere una foglia
4.4 Il package “motore”: preValidator.parseStruct
97
del nodo componente a cui è riferita la documentazione, è stato necessario
implementare un metodo speciale nella classe Tag chiamato insertNodeDpp()
il quale è chiamato in modo opportuno da getSchema().
In conversione DTD, invece, l’header DppDoc è inserito nella posizione immediatamente precedente al tag bersaglio.
4.4.5
Fasi di elaborazione di un header DppDoc
Il tag dppdoc, come è già stato descritto, è definito dalla forma <!--- ... -->.
Il lexer è stato quindi adattato con una regular expression per distinguere
un commento normale da un tag dppdoc. Il token risultante viene passato
al parser Yacc il quale crea l’oggetto DppDoc con il costruttore opportuno.
Successivamente viene inserito nella tagList.
Il preValidator, quando ha attivata l’opzione per generare la documentazione, abilita il metodo della classe Tags initTypeList() a effettuare tre
operazioni:
1. inizializzare i tag DppDoc presenti nella tagList.
2. avviare l’algoritmo di generazione dei tag DppDoc per gli header base;
3. chiamare il metodo privato buildDppdoc(), il quale provvede alla elaborazione vera e propria degli header chiamando per ciascun tag DppDoc
il metodo pubblico createDppTag().
Il risultato finale è la generazione di un albero documentativo base, arricchito con le addizionali informazioni inserite dallo sviluppatore tramite i
commenti dppdoc.
Un’algoritmo per la generazione automatica dell’albero documentativo base
Il sistema di creazione automatica degli header base si basa sulle informazioni contenute nella tagList. L’algoritmo è avviato in fase di inizializzazione
98
Dettagli implementativi
dal metodo initTypeList() e consiste nelle seguenti operazioni:
1. creazione dell’oggetto DppDoc con le informazioni base estratte dal tag
bersaglio analizzato durante il ciclo for sul vettore items;
2. accodare sul vettore di supporto items dppdocAuto, oltre ai tag non
documentabili (i tag Whitespace, WhitespaceInside, Comment, TargetNS, DppDoc creati manualmente), il tag DppDoc e il tag bersaglio;
3. al termine del ciclo il vettore items è “svuotato” per essere poi “riempito” con la collezione dei tag memorizzati su items dppdocAuto.
Al termine di questo “riadattamento” della tagList viene chiamato il
metodo privato buildDppdoc() che genera l’albero documentativo risultante.
4.5
Utilizzo e installazione
4.5.1
Utilizzo
L’utilizzo del preValidator avviene tramite linea di comando. I file sono
passati in input dal file system e l’output può essere emesso sia su file che sullo
standard output. Gli eventuali errori verranno visualizzati sullo standard
error.
La sintassi per utilizzare PreValidator è la seguente:
java -jar PreValidator.jar [-v] [-nv] [-schema fileName -dtd fileName ] [-out] [-salamislice | -ss | -gardenofeden | -goe | -venetianblinds
| -vb | -russiandolls | -rd] [-no-validator-error] [-stdout-error] [xerces | -msxml | -validator fileName] [-no-force-schema] [-nodeletetemp]
[file.xml] <file.dpp>
-dtd fileName Save DTD to file
Viene salvata la trasformazione del documento DTD++ in DTD nel file
specificato.
4.5 Utilizzo e installazione
-schema fileName Save Schema to file
Viene salvata la trasformazione del documento DTD++ in XML Schema
nel file specificato
-dppdoc
Abilita l’elaborazione dei commenti DppDoc per la creazione automatica
degli header documentativi nel file d’output DTD o XML Schema.
-salamislice, -ss Salami Slice schema style
Lo schema sarà generato secondo lo stile Salami Slice. Se non viene specificato alcun stile, per default si utilizza Salami Slice.
-gardenofeden, -goe Garden Of Eden schema style
Lo schema sarà generato secondo lo stile Garden of Eden.
-venetianblinds, -vb Venetian Blinds schema style
Lo schema sarà generato secondo lo stile Venetian Blinds.
-russiandolls, -rd Russian Dolls schema style
Lo schema sarà generato secondo lo stile Russian Dolls.
99
100
Dettagli implementativi
-validator fileName Validator file name
Determina quale validatore utilizzare. Per Default si utilizza il validator.exe che deve trovarsi nella stessa directory del preprocessore.
-xerces Validate with Xerces
Abilita Xerces come validatore. Equivale a lanciare PreValidator con i
parametri -validator “java -jar validateXML-1.1-bin.jar-in”
-msxml Validate with MSXML
Abilita MSXML come validatore. Equivale ad eseguire il processo con i
parametri “-validator validator.exe”. Se non viene specificato un validatore,
per default si utilizzerà questa configurazione.
-v Verbose mode
Segnala sullo standard output lo stato in cui si trova il preprocessore durante l’esecuzione. Si possono specificare altri due livelli di verbose-mode
tramite le opzioni -v5 e -v6. Con la prima si stampano sullo standard output
le informazioni di debug del parser, con la seconda sia quelle relative al parser
sia quelle relative allo scanner.
-nv Do not validate
Disabilita l’operazione di validazione e il PreValidator si limita a trasformare il documento DTD+++ in XML Schema.
4.5 Utilizzo e installazione
101
-out Print Schema or DTD to stdout
Stampa la trasformazione del documento DTD++ sullo standard output.
Con questa opzione viene disabilitata l’operazione di validazione.
-stdout-error Error message on stdout
Imposta il preprocessore in modo da ricevere i messaggi di errore del validator sullo standard output invece che sullo standard error.
-no-validator-error Do not process validator error
Disabilita il processing degli errori restituiti dal validatore. L’errore viene
stampato sullo standard error cosi come ricevuto dal validatore. Utile se il
messaggio d’errore restituito dal validatore non è compatibile con il preprocessore.
-no-force-schema Do not specify schema
Non passa il nome dello schema come parametro al validatore ma lo inserisce direttamente nel file XML. Viene cosi creato un file XML temporaneo.
-nodelete-temp Do not delete temp file
Se abilitato non cancella i file temporanei creati durante l’esecuzione.
file.xml
Il file XML che si vuol validare. Se omesso, viene disabilitata l’operazione
di validazione.
102
Dettagli implementativi
file.dpp
Il file DTD++ che si vuole processare.
4.5.2
Installazione
Il preprocessore funziona senza particolari requisiti hardware e software.
É però necessario avere installato una JVM 1.4.1
8
http://java.sun.com/
8
o successiva.
Conclusioni
Si è visto come una buona documentazione risulti di fondamentale importanza per diversi motivi:
• Facilita i compiti di un programmatore durante le fasi di modifica dei
sorgenti sia che si tratti di debugging o una estensione delle funzionalità;
• Offre agli addetti ai lavori una migliorata visione d’insieme sulla logica
di funzionamento del programma grazie a sintetiche e intuitive descrizioni sui vari componenti che lo compongono, non solo per colui che
l’ha realizzato, ma anche per chi dovrà in futuro metterci mano;
• Permette agli utenti finali di comprendere facilmente il corretto utilizzo
degli strumenti che il programma mette a disposizione;
• In generale fornisce quei vantaggi che da sempre hanno reso un progetto
non solo soddisfacente ai fini funzionali ma anche di successo per la
comunità utilizzatrice.
É indubbio però che una buona documentazione è tale se si minimizzano
quelle tediose, ma ahimè obbligatorie, procedure manuali affinchè oltre che
esente da errori sia anche chiara e, più in generale, utile per chi deve consultarla.
Automatizzare questo processo significa quindi non solo alleviare questo “noioso” compito, ma anche fornire un ottimo strumento di consultazione per
qualsiasi target di utenti.
DppDoc, grazie ad una sintassi intuitiva e facile da usare, si presenta come
103
104
Conclusioni
un potente supporto per la documentazione, in grado di fornire la massima
flessibilità nel scegliere la forma e il contenuto più idonei con l’ausilio di due
tipi di parametri: quelli sul contesto con cui “intitolare” i vari paragrafi della
documentazione; e quelli sul tag con i quali è possibile “arricchire” la semantica delle proposizioni vere e proprie.
La separazione della forma e della semantica, in questo caso, diventa lo strumento ideale per miscelare, a discrezione dello sviluppatore, la struttura della
documentazione in base al target di utenti a cui è rivolta.
L’impegno nella realizzazione di DppDoc per il linguaggio di validazione
DTD++, ha dimostrato come sia possibile applicare tecniche raffinate di literate programming anche per realizzare una valida documentazione su un
vasto insieme di vocabolari XML.
Se si sottolineano i presupposti del DTD++, si può comprendere come risulta ancora più interessante l’integrazione di un metodo di documentazione su
una grammatica caratterizzata da una semplicità d’apprendimento e da una
leggibilità che si contrappone alla verbosità di altri linguaggi di validazione
come XML Schema.
A dimostrazione di questo DTD++ è attualmente impiegato per la realizzazione di importanti progetti di natura giuridica. Tra i più interessanti si
possono menzionare il progetto NIR (Norme In Rete) 9 ed Estrella (European
project for Standardized Transparant Representations in order to Extend Legal Accessibility)
10
, i quali si propongono come sistemi informatici in grado
di rendere accessibile sul web ogni tipo di informazione e documentazione di
interesse giuridico-normativo nell’ambito dello stato italiano il primo e della
comunità europea il secondo. Questi sistemi informatici non sono altro che
due vocabolari XML scritti in linguaggio DTD++.
9
10
http://www.normeinrete.it/index.htm
http://www.estrellaproject.org
4.5 Utilizzo e installazione
105
Le novità implementative introdotte nel PreValidator hanno inoltre aumentato il potere espressivo del DTD++,con l’introduzione dell’attributo
abstract presente in XML Schema, allo stesso modo potrebbe essere utile
introdurre l’attributo final, ripreso anch’esso dalla sintassi XML Schema, il
quale permetterebbe un maggior controllo sui meccanismi di derivazione e
di sostituzione impedendo agli elementi e ai tipi di poter essere sostituiti o
derivati all’interno dello schema.
Infine un possibile sviluppo futuro potrebbe essere l’introduzione di un sistema in grado di personalizzare l’interfaccia d’output dell’header DppDoc
seguendo lo stile adottato dal ROBODoc con l’ausilio di un file di configurazione: potrebbe essere utile nel momento in cui si volessero elaborare
sofisticate strutture documentative con l’ausilio dell’engine XSL-FO.
106
Conclusioni
Appendice A
“ROBODoc per Dppdoc”:Il
gregario di DppDoc
ROBODoc4dppdoc è una versione modificata di Robodoc configurato
per interpretare, estrarre e elaborare i tag dppDoc presenti all’interno di un
documento DTD o XML Schema opportunamente convertito dal PreValidator DTD++.
In questa dissertazione Robodoc è stato considerato un documentatore universale come afferma lo stesso realizzatore, Frans Slothouber, nella home
page ufficiale:
“ROBODoc can be used to document functions, methods, classes, variables, makefile entries, system tests, and anything else
you can think of.
ROBODoc works with C, C++, Fortran, Perl, shell scripts, Assembler, DCL, DB/C, Tcl/Tk, Forth, Lisp, COBOL, Occam,
Basic, HTML, Clarion, and any other language that supports
remarks.”
107
108
A “ROBODoc4dppdoc”:Il gregario di DppDoc
A.1
Caratteristiche principali
ROBODoc è un API documentation tool per C, C++, Java, Assembler,
Basic, Fortran, LaTeX, Postscript, Tcl/Tk, LISP, Forth, Perl, Shell Scripts, Makefiles, Occam, COBOL, DCL, Visual Basic, HTML, DB/C, XML e
molti altri linguaggi. Può supportare qualsiasi linguaggio che abbia il tag
commento, praticamente tutti.
Sostanzialmente il lavoro si basa sull’interpretazione, elaborazione e riformattazione di una speciale etichetta (header) ben formata innestata nel
codice sorgente che si vuole documentare. Questi file possono essere formattati in HTML, ASCII, XML DocBook o RTF e indirettamente in PDF e
HTML Help (CHM files).
Robodoc è simile al Javadoc: è in grado di generare la documentazione
estrapolando le informazioni necessarie da un unico file in cui oltre al codice
implementativo, è innestato il codice per la documentazione tramite tag commenti opportunamente modificati. Questo facilita le fasi di aggiornamento
tra le modifiche del codice sorgente e la relativa documentazione.
É possibile creare la documentazione per essere facilmente pubblicata online e consultata con un comune browser come Internet Exloper o Firefox
oppure su singoli file in formato LaTeX o RTF per facilitare la stampa in
formato cartaceo o la modifica con un Word processor.
L’idea di Robodoc è quindi quella di soddisfare la necessità di avere un
automatismo procedurale tale da generare la documentazione su qualsiasi
linguaggio di programmazione senza dover conoscere la sintassi, eccezion fatta per le sequenze di apertura e chiusura utilizzate per interpretare il tag
commento.
A.2 Tre concetti chiave: header, blocco e sezione
A.2
109
Tre concetti chiave: header, blocco e sezione
Per generare la documentazione, Robodoc si appoggia ad un particolare
schema applicato al tag commento. Tre componenti chiave definiscono la
struttura sintattica d’interfaccia:
• header
• blocco
• sezione
A.2.1
Headers e blocchi
Un header è un riadattamento ben formato del tag commento che identifica la documentazione di un particolare componente del codice sorgente.
Ad esempio
/****f* financial.library/StealMoney
*
*
*
*
*
NAME
StealMoney -- Steal money from the Federal Reserve Bank. (V77)
SYNOPSIS
error = StealMoney( userName, amount, destAccount, falseTrail )
FUNCTION
*
Transfer money from the Federal Reserve Bank into the
*
specified interest-earning checking account.
*
the transaction will be retained.
*
*
No records of
INPUTS
userName
- name to make the transaction under.
Popular
*
favorites include "Ronald Reagan" and
*
"Mohamar Quadaffi".
*
amount
- Number of dollars to transfer (in thousands).
*
destAccount - A filled-in AccountSpec structure detailing the
110
A “ROBODoc4dppdoc”:Il gregario di DppDoc
*
destination account (see financial/accounts.h).
*
If NULL, a second Great Depression will be
*
triggered.
*
falseTrail
- If the DA_FALSETRAIL bit is set in the
*
destAccount, a falseTrail structure must be
*
provided.
*
*
RESULT
error - zero for success, else an error code is returned
*
*
*
*
*
*
(see financial/errors.h).
EXAMPLE
Federal regulations prohibit a demonstration of this function.
NOTES
Do not run on Tuesdays!
BUGS
*
Before V88, this function would occasionally print the
*
address and home phone number of the caller on local police
*
976 terminals.
*
resolved.
*
We are confident that this problem has been
SEE ALSO
*
CreateAccountSpec(),security.device/SCMD_DESTROY_EVIDENCE,
*
financial/misc.h
******
* You can use this space for remarks that should not be included
* in the documentation.
*/
L’header è formato da tre elementi: un marcatore d’inizio, una sequenza
di blocchi e il marcatore di fine.
A.2 Tre concetti chiave: header, blocco e sezione
111
Il marcatore di inizio
****f* financial.library/StealMoney
• fornisce al Robodoc il nome del componente che si stà documentando,
StealMoney
• il modulo di cui fa parte, financial.library
• il tipo dell’elemento,f, che in questo caso è per una funzione
Robodoc si aspetta sempre che ci sia una “/” che separi il nome del modulo
dal nome dell’elemento. Questo separatore è fondamentale per generare l’indice rispettando la struttura gerarchica dei vari componenti.
Un blocco è composto da un titolo e il corpo del testo vero e proprio. Ad
esempio
*
FUNCTION
*
Transfer money from the Federal Reserve Bank into the
*
specified interest-earning checking account.
*
the transaction will be retained.
No records of
In questo caso il nome del blocco è FUNCTION.
A.2.2
Sezioni e headertype
Robodoc definisce un elenco predefinito di headertype (tabella B.1) che
possono essere utilizzati per migliorare l’indicizzazione dei componenti.
Gli headertype possono essere personalizzati per indicizzare anche altri
tipi di componenti come ad esempio quelli di un linguaggio di validazione
XML.
Anche per l’intitolazione dei blocchi Robodoc fornisce un nutrito elenco di
nomi predefiniti, anch’essi personalizzabili e adattabili per qualsiasi esigenza.
112
A “ROBODoc4dppdoc”:Il gregario di DppDoc
Headertype
componente
c
classe
d
costante
f
funzione
h
modulo in un progetto
m
metodo
s
struttura
t
tipo
u
unittest
v
variabile
*
etichetta generica per ogni tipo di oggetto
Tabella A.1: Headertype predefiniti riconosciuti da ROBODoc
A.3
Estrarre la documentazione con ROBODoc
Una volta che è stata impostata opportunamente l’interfaccia dell’header
e innestati correttamente nel codice sorgente, ROBODoc è pronto per estrarre la documentazione.
Ci possono essere molte scelte per modellare il formato finale.
Robodoc può essere utilizzato in tre modalità:
1. multidoc
2. singledoc
3. singlefile: non molto utile, eccezion fatta per le fasi di debugging.
A.3 Estrarre la documentazione con ROBODoc
A.3.1
113
Documentazione online: multidoc
In questa modalità ROBODoc analizza tutti i sources files contenuti all’interno della directory dei sorgenti e crea per ciascuno di essi un documentation
file all’interno della directory d’output.
Il risultato finale è una proiezione documentata del codice sorgente.
La modalità multidoc è utile per creare una documentazione facilmente consultabile tramite un browser.
Per attivarla è necessario inserire i seguenti argomenti:
robodoc --src source directory --doc document directory
--multidoc other options
Una ulteriore opzione utile è —index, che genera un index file per ciascun
tipo di header.
A.3.2
Documentazione standalone: singledoc
In questa modalità Robodoc analizza tutti i sources files e genera un singolo documentation file.
É utile per creare blocchi di documentazione da poter essere incorporati in
altri oppure per essere manipolati tramite un Word processor.
robodoc --src source directory --doc document file without
extension --singledoc other options
A.3.3
I formati d’output
La prossima scelta è il formato d’output. Robodoc può creare documentazione in diversi formati:
• HTML, —html
• RTF, —rtf
114
A “ROBODoc4dppdoc”:Il gregario di DppDoc
• LaTeX, —latex
• XML DocBook, —dbxml
Il tipo di formato può essere scelto in base alle proprie esigenze: LaTeX
o XML DocBook per documenti portabili; RTF per documenti che devono
essere inclusi in un documento Word; HTML per quelli da consultare con un
browser.
A.4
Un header per DppDoc
Robodoc può essere configurato tramite il file di configurazione robodoc.rc.
In questo modo è possibile personalizzare l’header d’interfaccia.
La configurazione di default di Robodoc è la seguente:
# Example robodoc.rc
#
items:
NAME
SYNOPSIS
INPUTS
OUTPUTS
SIDE EFFECTS
HISTORY
BUGS
ignore items:
HISTORY
BUGS
source items:
SYNOPSIS
options:
--src ./source
--doc ./doc
A.4 Un header per DppDoc
115
--html
--multidoc
--index
--tabsize 8
headertypes:
e
"Makefile Entries"
robo_mk_entries
x
"System Tests"
robo_syst_tests
q
Queries
robo_queries
ignore files:
README
CVS
*.bak
*~
"a test_*"
accept files:
*.c
*.h
*.pl
header markers:
/****
#****
remark markers:
*
#
end markers:
****
#****
remark begin markers:
/*
remark end markers:
*/
116
A “ROBODoc4dppdoc”:Il gregario di DppDoc
source line comments:
//
keywords:
if
do
while
for
Il file di configurazione consiste di un elenco di blocchi. Ciascun blocco inizia
con un nome seguito da “:” e in ognuno di essi è possibile definire un valore.
Grazie a questa versatilità di personalizzazione è stato possibile creare
un header dedicato per il tag DppDoc affinchè Robodoc possa estrapolare
ed elaborare l’albero documentativo innestato in un documento DTD++ indipendentemente dal tipo di formato ottenuto in fase di conversione con il
PreValidator.
L’obiettivo primario è stato quindi:
• strutturare l’header con le sequenze di apertura e chiusura uguali al
DppDoc: “<!---” e “-->” ;
• i nomi dei blocchi documentativi devono essere una proiezione funzionale sia dei parametri informativi definiti dalla sintassi DppDoc, sia
dalle informazioni standard prelevate dalla sola analisi sintattica dei
tag DTD++;
• ciascun tipo di tag DTD++ deve avere un riferimento headertype per
una corretta ed elegante indicizzazione;
• un insieme di opzioni per indicare il tipo di modalità: singledoc o
multidoc.
La soluzione è stata quella di creare due file di configurazione, uno per la
documentazione su singoli file, l’altro per documentazioni consultabili online:
DppDocsingle.rc, DppDocmulti.rc.
A.4 Un header per DppDoc
# DppDocsingle.rc
#
options:
--nogeneratedwith
--singledoc
--toc
--tabsize 8
--nopre
--cmode
items:
DECLARED NAMESPACES
SUMMARY
TYPE
NAME
HEAD SUBSTITUTION
REFERENCE ELEMENT
REFERENCE CONTENT
CONTENT MODEL
SCHEMA COMPONENT REPRESENTATION
ATTRIBUTES
USAGE
DESCRIPTION
PURPOSE
AUTHOR
"CREATION DATE"
HISTORY
EXAMPLE
NOTES
WARNINGS
ERRORS
117
118
A “ROBODoc4dppdoc”:Il gregario di DppDoc
BUGS
IDEAS
SEEALSO
RIEPILOGO
header markers:
<!--end markers:
-->
# DppDocmulti.rc
#
options:
--nogeneratedwith
--singledoc
--sections
--toc
--sectionnameonly
--tabsize 8
--nopre
--cmode
items:
DECLARED NAMESPACES
SUMMARY
TYPE
NAME
HEAD SUBSTITUTION
REFERENCE ELEMENT
REFERENCE CONTENT
CONTENT MODEL
A.4 Un header per DppDoc
119
SCHEMA COMPONENT REPRESENTATION
ATTRIBUTES
USAGE
DESCRIPTION
PURPOSE
AUTHOR
"CREATION DATE"
HISTORY
EXAMPLE
NOTES
WARNINGS
ERRORS
BUGS
IDEAS
SEEALSO
RIEPILOGO
headertypes:
a "Declared Namespaces"
b Element
dppdoc_n_index
dppdoc_a_index
c "Element substitution" dppdoc_s_index
d Attlist
dppdoc_b_index
e "Simple type"
dppdoc_c_index
f "Complex type"
dppdoc_d_index
g "Group" dppdoc_e_index
h "Attributegroup"
dppdoc_f_index
l "Entity System" dppdoc_g_index
m Tags
dppdoc_t_index
r "Riepilogo"
dppdoc_r_index
120
A “ROBODoc4dppdoc”:Il gregario di DppDoc
header markers:
<!--end markers:
-->
ROBODoc è ora pronto per generare la documentazione da un sorgente
DTD o XML Schema convertito dal PreValidator DTD++ con l’opzione dppdoc attivata.
Per ulteriori informazioni riguardo la sintassi dei comandi è possibile fare
riferimento al tutorial pubblicato online sul sito ufficiale di DTD++ [MM06]
Qui di seguito è proposto un esempio di tag DppDoc generato in output
dal PreValidator pronto per essere elaborato da Robodoc
<!---h* Definitions/e:nameopt
* TYPE
* EntityAttlist
* NAME
* e:nameopt
* ATTRIBUTES
*
*
<xsd:attribute ref="e:name" />
*
* SCHEMA COMPONENT REPRESENTATION
*
<xsd:attributeGroup name="nameopt">
*
<xsd:attribute name="name" type="xsd:NMTOKEN"/>
*
</xsd:attributeGroup>
*
*
*
DESCRIPTION
* e:nameopt: a semantically-charged name that identifies
* in a human-understandable way the purpose and meaning
A.4 Un header per DppDoc
* and role of the element.
-->
121
122
A “ROBODoc4dppdoc”:Il gregario di DppDoc
Bibliografia
[AC06] Apple
Computer
Company,
Open
Source
HeaderDoc,
http://developer.apple.com/opensource/tools/headerdoc.html, 2006
[AL82] Jonathan Arnon, Harry Lerhaupt, Software documentation ad automated approach, SIGDOC’82:Proceedings of the 1st annual international conference on Systems documentation, Carson, California, United
States, 22-23 gennaio 1982, ACM Press 1982.
[AN01] Nicola Amorosi, Un’estensione sintattica dei DTD per la validazione dei documenti XML, Tesi di Laurea discussa presso l’Università di
Bologna, marzo 2001
[BDocs06] Buldocs Ltd, xnsdoc - XML Schema Documentation Generator,
http://www.buldocs.com/xnsdoc/ , 2006
[BM01] P. V. Biron and A. Malhotra, XML Schema Part 2: Datatypes, W3C
Recommendation, http://www.w3.org/TR/xmlschema-2, May 2001.
[CA06] Andrea Chiarelli, Documenti ben formati, Guida XML di base,
HTML.it,
http://xml.html.it/guide/lezione/1843/documenti-ben-
formati/ , 2006
[Cla01] James Clark, TREX - Tree Regular Expressions for XML. Language
Specification, http://www.thaiopensource.com/trex/, 2001.
[CYE82] Christopher Hartsough, Yuzo Yamamoto, Ernest A. Hershey, Documentation production from a formal database, SIGDOC’82: Proceedings
123
124
BIBLIOGRAFIA
of the 1st annual international conference on Systems documentation,
Carson, California, United States, 22-23 gennaio 1982, ACM Press 1982.
[EB05] Joshua Eichorn, Greg Beaver, phpDocumentor, http://phpdoc.org/,
2005
[ET82] Timothy E. Erickson, An automated FORTRAN documenter, SIGDOC’82:Proceedings of the 1st annual international conference on Systems documentation, Carson, California, United States, 22-23 gennaio
1982, ACM Press 1982.
[FD03] Davide Fiorello, Un processore per la validazione di documenti XML:
DTD++, Tesi discussa presso l’Università di Bologna, marzo 2003.
[FS06] Frans
Slothouber,
ROBODoc,
http://www.xs4all.nl/
rf-
sber/Robo/robodoc.html, 2006
[GD06] Geoffrey Darnton, Problem Statement Language (PSL) and Problem
Statement Analyzer (PSA), http://www.pslpsa.com/, 2006.
[GG005] Giulia Gambini, Un’estensione Object Oriented di un linguaggio di
validazione per XML, Tesi discussa presso l’Università di Bologna, 2005
[GHDT06] getahead - doctree, http://getahead.ltd.uk/doctree/, ultima
visita: 20 ottobre 2006.
[JR02] Rick
tre,
Jelliffe,
The
Academia
Schematron
Sinica
Assertion
Computing
Cen-
Language
1.5.,
http://xml.ascc.net/schematron/1.3/Schematron2000.html,
01
Oct
2002.
[LCPH84] Vicente Lopez Trueba, Julio Cesar Leon Carrillo,Oscar Olvera
Posadas,Carlos Ortega Hurtado. A system for automatic Cobol program
documentation,SIGDOC’84:Proceedings of the 3rd annual international
conference on Systems documentation, Citta del Messico, Messico, 16-18
maggio 1984, ACM Press 1984.
BIBLIOGRAFIA
[KD06] Donald
125
Knuth,
Literate
Programming,
2006,
http://www.literateprogramming.com/
[KDEHP06] K-Desktop Environment, http://www.kde.org/, 2006
[KM84] Jeffrey Kurn, Scott L. McGregor, Toward an Electronic Programmer’s Assistant, SIGDOC’83:Proceedings of the 2nd annual international conference on Systems documentation, Seattle, Washington, United
States, 28-30 aprile 1983, ACM Press 1983.
[MM06] Alessandro Modica, Simone Monterubbiano, DTD++ Project,
2006, http://trac.cs.unibo.it/
[MEA84] Enrique Arce Medina, Some aspects of software documentation,SIGDOC’84:Proceedings of the 3rd annual international conference
on Systems documentation, Citta del Messico, Messico, 16-18 maggio
1984, ACM Press 1984.
[Mur00] Makoto Murata, RELAX (REgular LAnguage description for
XML), http://www.xml.gr.jp/relax/, 2000.
[PD02] Dave Pawson, O’REILLY, XSL-FO, Extensible Style LanguageFormatting Objects, 2002
[PDoc00] PHPDoc, http://www.phpdoc.de/, 2000
[SR86] Richard
H.
Smith,
A
Documentation
Language,
SIG-
DOC’85:Proceedings of the 4th annual international conference on
Systems documentation, Ithaca, New York, United States 18-21 giugno
1986, ACM Press 1986.
[SM82] Scott
L
McGregor,
Improving
Documentation,
SIG-
DOC’82:Proceedings of the 1st annual international conference on
Systems documentation, Carson, California, United States, 22-23
gennaio 1982, ACM Press 1982.
126
BIBLIOGRAFIA
[VAG03] Fabio Vitali, Nicola Amorosi, Nicola Gessa. Datatype- and
namespace-aware DTDs:
a minimal extension, in Proceedings of
Extreme Markup 2003, Montreal, Canada, August 2003.
[VFGM03] Fabio Vitali, Davide Fiorello, Nicola Gessa, Paolo Marinelli.
DTD++ 2.0: Adding support for co-constraints, in Extreme Markup
Languages 2003, August 2003.
[VG06] Greg Valure, Natural Docs, http://www.naturaldocs.org/, 2006
[W3C04] XML Schema Part 2: Datatypes Second Edition, W3C Recommendation 28 October 2004, http://www.w3.org/TR/xmlschema-2/
[WB06] Walter Bright,
D Programming Language ,
Digital Mars,
http://www.digitalmars.com/d/, 2006
[Xalan05] Apache XML project, Xalan-Java, http://xml.apache.org/xalan-j/
, 2005
[Xerces06] The Apache XML project, 2006, http://xml.apache.org/#xerces
[XF05] xframe team, xsddoc, http://xframe.sourceforge.net/, 2005.
[XML4J98] IBM,
XML
Parser
for
Java,
http://www.alphaworks.ibm.com/tech/xml4j, 1998.
[ZEJP06] Zentech - Enterprise Java Performance,
Doclet.com Java,
http://doclet.com/, Ultima visita: 28 settembre 2006
Ringraziamenti
In principio ci fu l’ignoto...che mi trascinò nelle oscure paludi di ingegneria civile, una pallida luce lontana mi rincuorò....ma passare al primo
colpo analisi non servı̀ a nulla.....l’ignoto incombeva e soffocava ogni ispirazione.....lesto come un bradipo capii che l’unica scelta fu seguire ciò che a
quei tempi era per me un superficiale hobby di chi non c’ha nulla da fare
tutto il giorno....iscriversi a Informatica! Da li sopraggiunse il nulla....e poi il
nulla ancora...un nulla trascorso bazzicando i corridoi delle aule ercolani e il
bar di fronte. Il sistema “cazzeggio” non durò molto fino a quando lo Stato
bussò alla mia porta con una bella cartolina: militare! Il sistema Modicopoli
fu scoperto!!! Condannato ad un anno di squalifica e costretto a scontare la
pena in uno squallido ufficio sperduto nei meandri delle case popolari di via
Gandusio capii che era ora di cominciare a muovere le chiappe togliendomi
dalla testa ogni pensiero di mollare tutto! Ciò nonostante sapevo che sarei
partito dalla Serie B con 19 punti di penalizzazione (anche se all’ultimo ricorso al tar del Lazio si è riusciti a toglierne 9)....beh come qualcuno potrebbe
dire...se si arriva in fondo e sotto non cè piu nulla da scavare...tanto vale cominciare a salire...almeno per fare qualcosa di diverso! Piu che altro mi ero
rotto di camminare su strade sferrate piene di buche e sassi...era arrivato il
momento di asfaltare con un bel rullo compressore!!! Ed è qui che cominciano i miei ringraziamenti.....il primo grazie in assoluto è dedicato senza alcun
dubbio a quei ragazzacci della New Team...Claudio, Tommaso e Paolo con
cui si è riusciti a far tremare il mondo inanellando progetti su progetti, esami
su esami...ad un ritmo talmente sfrenato che cominciava a spaventare anche
127
128
Ringraziamenti
noi! Un grazie a chi da molto tempo mi sopporta ed è riuscito addirittura a
sopportarmi nelle fasi finali di qualificazione per questo ambito premio....un
grazie al balottone romano applausi applausi per Rudy che rimarrà nei secoli
dei secoli un grande...per Stefano un grosso nell’apprendere da bravo allievo
lo slang bulgnas...per Beppe che se non era per NBA Live 95 (ahah che tajo!!) chissà che fine avrebbe fatto....per Nico che se a volte je menerei rimane
un grosso, soprattutto ripensando ai fasti gloriosi degli Amiant Boys....per il
Fiore che se ci si sente molto meno rimane cmq un amico su cui posso sempre
contare, per Emiliano (per gli amici Yoghi) che mi ha fatto vivere l’ebbrezza
dell’assistente giornalista in eventi che non si possono raccontare....un grazie
alla Sarah il prototipo del peperino per eccellenza, alla Michy una delle poche donne che è riuscita a tenermi imbrigliato come piace a me.....in generale
un grazie a tutte le mille di milioni di donne che hanno tempestato mille
di milioni di momenti che mò non stò qui a raccontare che sennò mi sbucano quelli di novella 2000 e non è bello ciò!....e dal fronte estero si passa in
terra nostrana.....ringraziando un pò tutta la balottona bolognese...un grazie
a tutti quei ragazzi che fin dai primi giorni in cui ero a Bologna mi hanno
subito accettato per quello che sono....un grazie a Roberto (detto il Ruggi)
a Cesto...un grazie anche a Dondo, meglio conosciuto a Roma come “quello
del Monopoli” che nonostante le tante sfuriate che mi ha lanciato è riuscito a
dimostrare sinceri attimi di amicizia, un grazie all’Anna, all’Adele, a Riccardo, a White Man detto Andrea, un grazie alla Giuly, alla Marta, all’Elisa, al
Pedocchi, alla Cecy, alla Tony, all’Elena, a Zac...un grazie anche al Buga e ad
Albe con cui si spera di sfondare nel mondo dello spettacolo scalando tutte le
classifiche musicali mondiali!!!!! Un grazie anche alla Famigghia Bigazzi.....a
Riccardo che è sempre un piacere vedere quando rosica quando si becca la
giubba a Pro Evolution...e a Vincenzo, alleato fedele contro il Bigattone al
Torneo Bigazzi e a Gianluca il compagno di camera che tutti vorrebbero avere!!
Passando in modalità seria ringrazio il mio relatore, Fabio Vitali, che in
questi otto mesi mi ha offerto la possibilità di vivere un’esperienza unica,
Ringraziamenti
129
insegnandomi tanti trucchetti per fare bene col minimo sforzo, facendomi
scoprire fino in fondo il piacere di coltivare la propria passione!
Infine vorrei ringraziare i miei sponsor ufficiali che nel bene e nel male mi
hanno sempre dato il giusto supporto per affrontare i pericoli, non solo per
il raggiungimento di un obiettivo cosi importante come la laurea, ma anche
quelli che ti insinua tutti i giorni la vita....un grazie alla mia mamma e al mio
papà....siete grandi! Rimanendo nella sfera familiare un veloce ringraziamento a mia sorella Elisabetta che si spera un giorno possa farmi un bel ritratto
su una enorme facciata di ceramica che farò costruire appositamente nella
mia supervilla...più bella di quella di Steve Jobs e Bill Gates messe assieme!
A questo punto dato che ci sono.....ringrazio anche me stesso che se non era
per me cor cavolo sarei riuscito ad arrivare a scrivere questi ringraziamenti!!!
Grazie a tutti!!!!