Specifiche di protocollo
Fa parte della versione 0.9.07 del protocollo totale – 30 Maggio 2007
Questa versione: WDraft7DFNOTA: VI CHIEDO CORTESEMENTE DI LEGGERE SEMPRE IL PARAGRAFO "NOTE GENERALI"
rawurlencode
, in PHP, o la encodeURIComponent
, in javascript, per la codifica dei dati.
E' obbligatorio usare la funzione rawurldecode
, in PHP, o la decodeURIComponent
, in javascript, per la decodifica dei dati.
Il DF dovra' implementare la logica di un webservice la cui interfaccia e' definita e fornita nel WSDL presente in sezione "5.1". Per ogni metodo definito nel WSDL dovra' essere fornita l'implementazione opportuna mediante una funzione avente ugual nome, la cui logica di funzionamento dipende dalla richiesta che tale funzione gestisce.
NOTA BENE: per l'implementazione del webservice lato server e client (DF e AC) si potranno usare ESCLUSIVAMENTE le estensioni SOAP gia' fornite dall'installazione di PHP presente su GOLEMI seguenti link puntanto ad una implementazione completa di un webservice-DF che rispetta l'interfaccia definita nel WSDL di sezione "5.1"
Il webservice-DF dovra' implementare e fornire l'interfaccia specificata nel WSDL seguente:
<?xml version="1.0" encoding="UTF-8"?> <definitions name='DfService' targetNamespace='http://tw.web.cs.unibo.it/DfService' xmlns='http://schemas.xmlsoap.org/wsdl/' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:tns='http://tw.web.cs.unibo.it/DfService' xmlns:xsd='http://www.w3.org/2001/XMLSchema'> <types/> <message name='DfService_richiedi_elenco'> </message> <message name='DfService_richiedi_elencoResponse'> <part name='resultElenco' type='xsd:string'/> </message> <message name='DfService_formatta_documento'> <part name='layout' type='xsd:int'/> <part name='skin' type='xsd:int'/> <part name='ajaxInfo' type='xsd:string'/> <part name='mioDocumento' type='xsd:string'/> </message> <message name='DfService_formatta_documentoResponse'> <part name='resultDocumento' type='xsd:string'/> </message> <message name='DfService_formatta_frammento'> <part name='currentlayout' type='xsd:int'/> <part name='currentskin' type='xsd:int'/> <part name='mioFrammento' type='xsd:string'/> </message> <message name='DfService_formatta_frammentoResponse'> <part name='resultFrammento' type='xsd:string'/> </message> <message name='DfService_Fault'> <part name="id" type="xsd:integer"/> </message> <portType name='DfService'> <operation name='richiedi_elenco'> <input message='tns:DfService_richiedi_elenco'/> <output message='tns:DfService_richiedi_elencoResponse'/> <fault name="error" message="tns:DfService_Fault"/> </operation> <operation name='formatta_documento'> <input message='tns:DfService_formatta_documento'/> <output message='tns:DfService_formatta_documentoResponse'/> <fault name="error" message="tns:DfService_Fault"/> </operation> <operation name='formatta_frammento'> <input message='tns:DfService_formatta_frammento'/> <output message='tns:DfService_formatta_frammentoResponse'/> <fault name="error" message="tns:DfService_Fault"/> </operation> </portType> <binding name='DfServiceBinding' type='tns:DfService'> <soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/> <operation name='richiedi_elenco'> <soap:operation soapAction='http://tw.web.cs.unibo.it/formatter.php/richiedi_elenco'/> <input> <soap:body namespace='http://tw.web.cs.unibo.it/DfService' use='literal'/> </input> <output> <soap:body namespace='http://tw.web.cs.unibo.it/DfService' use='literal'/> </output> <fault name="error"/> </operation> <operation name='formatta_documento'> <soap:operation soapAction='http://tw.web.cs.unibo.it/formatter.php/formatta_documento'/> <input> <soap:body namespace='http://tw.web.cs.unibo.it/DfService' use='literal'/> </input> <output> <soap:body namespace='http://tw.web.cs.unibo.it/DfService' use='literal'/> </output> <fault name="error"/> </operation> <operation name='formatta_frammento'> <soap:operation soapAction='http://tw.web.cs.unibo.it/formatter.php/formatta_frammento'/> <input> <soap:body namespace='http://tw.web.cs.unibo.it/DfService' use='literal'/> </input> <output> <soap:body namespace='http://tw.web.cs.unibo.it/DfService' use='literal'/> </output> <fault name="error"/> </operation> </binding> <service name='DfService'> <port binding='tns:DfServiceBinding' name='DfServicePort'> <soap:address location='http://tw.web.cs.unibo.it/formatter.php'/> </port> </service> </definitions>
In particolare dovra' implementare i tre metodi cosi definiti dal WSDL:
String richiedi_elenco()
il cui output e' un documento XML in formato stringa contenente l'elenco di layout e skin cosi come definito nella sezione "8.1"String formatta_documento(int layout, int skin, String ajaxInfo, String mioDocumento)
il cui output e' un documento XML in formato stringa contenente il documento XML specificato nel parametro "mioDocumento" opportunamente formattato, cosi come definito nella sezione "8.2"String formatta_frammento(int currentLayout, int currentSkin, String mioFrammento)
il cui output e' un documento XML in formato stringa contenente il documento XML specificato nel parametro "mioFrammento" opportunamente formattato, cosi come definito nella sezione "8.3"http://tw.web.cs.unibo.it/formatter.php
con la URL assoluta del proprio webservice (ovvero l'URL dello script DF che implementa il servizio).
MODIFICA: Aggiornato il wsdl, aggiunto il SoapFault?
Il catalogo di un Formatter contiene le metainformazione relative al Formatter stesso. È un documento XML (non necessariamente statico) di risposta alla richiesta analizzata in sez. 6.1 e validato dal seguente schema:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sch="http://purl.oclc.org/dsdl/schematron" xmlns="http://vitali.web.cs.unibo.it/view/TechWeb07/WorkingGroupACDF" xmlns:df="http://vitali.web.cs.unibo.it/view/TechWeb07/WorkingGroupACDF" targetNamespace="http://vitali.web.cs.unibo.it/view/TechWeb07/WorkingGroupACDF"> <!-- Inclusione degli elementi base della grammatica ( estensione di quelli comuni con il DataSource) --> <xs:include schemaLocation="DFtesto.xsd"/> <xs:element name="catalogoFormatter"> <xs:complexType> <xs:sequence> <xs:element name="nome" type="xs:string"/> <xs:element name="tipo" type="xs:string"/> <xs:element name="descrizione" type="DFtesto_t" /> <xs:element name="urlWsdl" type="xs:anyURI"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
Le metainformazioni sono espresse tramite i seguenti elementi:
nome
: il nome del Formattertipo
: il tipo di output prodotto. Ogni formatter
dichiara il content-type del risultato che produce, specificando un tipo MIME.
Valori possibili: text/html per le pagine HTML, application/pdf per i file PDF,
text/xhtml per documenti XHTML, etc. È possibile personalizzare il tipo di dato
prodotto ed aggiungere altri tipi a questo elenco.descrizione
: una descrizione human-readable del Formatter, del
tipo di dati che produce, eventualmente note su autori, implementazione o altre
informazioni.urlWsdl
: l’url per richiedere il WSDL fornito dal DF. Tale WSDL rappresenta l'interfaccia che definisce i punti di accesso al webservice-DF.Di seguito è riportato un esempio di catalogo di un Formatter:
<catalogoFormatter> <nome>TWformatter</nome> <tipo>application/pdf</tipo> <descrizione>Un efficiente e ricco formatter PDF</descrizione> <urlWsdl>http://tw.web.cs.unibo.it/formatter.wsdl</urlWsdl> </catalogoFormatter>
Tale richiesta è realizzata con una GET HTTP di un documento con URL stabilito e reso pubblico da ogni Formatter al momento della registrazione. Si assuma ad esempio che nel wiki sia registrato il seguente Formatter:
NOME | CATALOGO XML | CATALOGO HTML |
---|---|---|
TWFormatter | http://tw.web.cs.unibo.it/format.xml | http://tw.web.cs.unibo.it/format.html |
L’URL da utilizzare per la richiesta è appunto
http://tw.web.cs.unibo.it/format.xml
Il Formatter risponde con una auto-descrizione espressa in sintassi XML secondo le specifiche riportate nella sezione 6. Dal risultato della richiesta bisognera' estrapolare l'url del WSDL del DF; tale WSDL dovra' essere usato per interfacciarsi al webservice-DF ed eseguire richieste corrette. Si noti che il catalogo può essere un documento statico o dinamico e che è necessario fornire anche una versione human-readable (HTML) dello stesso.
Anche nel caso del DF il ruolo del catalogo è fondamentale: per ogni richiesta l'AC deve consultare il catalogo del DF e recuperare l'URL completo del WSDL; il WSDL rappresenta l'interfaccia del webservice fornito dal DF. Sebbene sia possibile implementare meccanismi di caching, è obbligatorio recuperare dinamicamente l'URL del WSDL del DF dal catalogo.
Come specificato in sezione 2, l’applicazione può inoltrare tre tipi di richieste al Formatter:
Nelle sottosezioni successive sono riportate le specifiche dettagliate e complete del protocollo DF.
Tale richiesta è realizzata invocando il metodo richiedi_elenco()
definito all'interno del WSDL.
Ad
esempio dato il seguente catalogo:
<catalogoFormatter> <nome>TWformatter</nome> <tipo>application/pdf</tipo> <descrizione>Un efficiente e ricco formatter PDF</descrizione> <urlWsdl>http://tw.web.cs.unibo.it/formatter.wsdl</urlWsdl> </catalogoFormatter>
l’applicazione, in base alla definizione del WSDL reperibile all'URL specificata in "urlWsdl", invoca il metodo opportuno fornito dal webservice-DF :
String richiedi_elenco()
ed il Formatter risponde con l’elenco dei layout e delle skin disponibili, in sintassi XML secondo le specifiche riportate in sez. 8.1.
Il DF fornisce nell'elenco un numero variabile di associazioni LAYOUT->SKIN dove la relazione tra i due elementi e' di 1->N. Per ogni layout e skin viene specificato un ID univoco associato.
La richiesta di
formattazione di un dato documento è realizzata mediante l'invocazione del metodo String formatta_documento(int layout, int skin, String ajaxInfo, String mioDocumento)
cosi come definito nel WSDL fornito dal DF. L’applicazione specifica nei parametri "layout" e "skin" gli ID scelti in base all'elenco ottenuto precedentemente;nel parametro "ajaxInfo" dovra' inserire la stringa ottenuta dal documento XML specificante le informazioni su ajax, nel parametro "mioDocumento" dovra' inserire la stringa ottenuta dal documento XML da formattare.
Il parametro ajaxInfo
deve contenere un documento XML valido secondo la grammatica fornita al paragrafo 7.2.1 .
Di seguito è riportato un
esempio di richiesta: l’applicazione chiede al Formatter di applicare ai dati
contenuti nel parametro mioDocumento
il
layout con id=12
ed aggiungere la
skin avente id=14
. Chiede inoltre di abilitare ajax secondo le informazioni contenute nel parametro ajaxInfo
.
result = formatta_documento(12,14, ajaxInfo, mioDocumento)
Il formatter risponde a tale richiesta con una stringa contenente il documento finale (pronto per la visualizzazione), secondo le specifiche riportate in sez. 6.3.
NOTA BENE:L'applicazione non deve in alcun modo modificare l'output finale prodotto dal DF. Essa deve limitarsi a redirigere l'output verso lo user-agent senza apportare modifiche all'output stesso ad eccezione esclusiva del "content/type". Il valore del "content/type" deve essere specificato in base al valore dell'attributo "type" del catalogo.
L'output finale dell'intera guida sarà un file PDF, che deve avere tutte le caratteristiche di un libro.
Oltre alle pagine dei contenuti, deve quindi avere:
Il contenuto XML presente in tale parametro serve a specificare le informazioni di inizializzazione dell'AC javascript.
In particolare si devono specificare:
Il seguente schema valida il contenuto ammissibile nel parametro ajaxInfo:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sch="http://purl.oclc.org/dsdl/schematron" xmlns="http://vitali.web.cs.unibo.it/view/TechWeb07/WorkingGroupACDF" xmlns:ds="http://vitali.web.cs.unibo.it/view/TechWeb07/WorkingGroupACDF" targetNamespace="http://vitali.web.cs.unibo.it/view/TechWeb07/WorkingGroupACDF"> <!-- ELEMENTO RADICE GLOBALE --> <xs:element name="ajax" type="ajax_t"/> <!-- COMPLEX TYPE AJAX_T --> <xs:complexType name="ajax_t"> <xs:annotation> <xs:documentation> L'elemento radice ajax deve contenere un elemento info ed un elemento scriptlist. L'elemento info contiene il nome della funzione inizializzatrice dell'AC javascript. L'elemento scriptlist e' una lista di URL di javascript da includere nell'output. </xs:documentation> </xs:annotation> <xs:all minOccurs="1" maxOccurs="1"> <xs:element name="info" type="xs:string"/> <xs:element name="scriptlist" type="scriptlist_t"/> </xs:all> </xs:complexType> <!-- COMPLEX TYPE SCRIPTLIST_T --> <xs:complexType name="scriptlist_t"> <xs:sequence minOccurs="1" maxOccurs="unbounded"> <xs:element name="urlscript" type="xs:anyURI"/> </xs:sequence> </xs:complexType> </xs:schema>
Di seguito e' riportato un esempio di contenuto valido rispetto alla grammatica precedente:
<?xml version="1.0" encoding="UTF-8"?> <ajax xmlns="http://vitali.web.cs.unibo.it/view/TechWeb07/WorkingGroupACDF" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://vitali.web.cs.unibo.it/view/TechWeb07/WorkingGroupACDF http://tomasell.web.cs.unibo.it/schema/ajax.xsd"> <info xmlns="">init()</info> <scriptlist xmlns=""> <urlscript>http://tomasell.web.cs.unibo.it/ac.js</urlscript> <urlscript>http://tomasell.web.cs.unibo.it/sarissa.js</urlscript> </scriptlist> </ajax>
Nel precedente esempio indichiamo al DF che:
init()
I dati da formattare contenuti in mioDocumento
possono essere di vari tipi:
elenco
, scheda
, commenti
, guidacompleta
: i dati ottenuti dall'output del data-source (eventualmente modificati nel loro contenuto mediante l'application logic). Possono essere anche un sottoinsieme o una versione modificata dei dati restituiti dai DS. Ad alcuni elementi possono essere aggiunti degli attributi per contenere collegamenti ad altre risorse, come descrito nella sezione 7.2.2.9;titolo
: un testo che descrive la pagina da formattare;query
: degli elementi che descrivono una maschera con la quale interrogare l'AC;menuContestuale
: una serie di elementi correlati ad una risorsa presente all'interno degli elementi elenco
e scheda
;menuStatico
: una serie di elementi (testo
o link
) che formano un menu con contenuti statici non legati ai dati presenti in elenco
o scheda
;contenuto
: alcuni elementi che forniscono informazioni statiche aggiuntive (credit, link alle pagine di aiuto, ecc);editor
: degli elementi che descrivono un editor per la modifica di schede del data-source (PdI?, Itinerario o Guida).Lo schema che definisce il contenuto valido per il parametro mioDocumento
e': formatta.xsd
L'elemento titolo
indica quale titolo è associato ai dati che l'AC sta spedendo al formatter.
title
nelle pagine HTML o come titolo con un font particolare nei PDF.
Ogni elemento query
indentifica una form con la quale l'utente può contattare l'AC.
titolo
indica il titolo della form contenuta.
L'attributo opzionale tipo
permette di indicare al formatter che la form contenuta rappresenta una query particolare che dovrebbe essere presenta in un modo diverso dal normale. Se l'attributo tipo
non è presente, allora la form contenuta rappresenta una query generica.
Esistono tre valori possibili per l'attributo tipo
:
ricercaVeloce
sceltaLayout
aggiuntaCommento
query
è l'elemento form
molto simile al corrispettivo HTML ma senza gli attributi presentazionali come id
e style
.
L'elemento form
contenuto in query si differenzia dall'elemento form
di HTML per tre particolarità:
label
si usa il relativo attributo label
associabile ad ogni elemento della form, non esiste l'elemento label
.form
(eg:
<form...>Ciao mamma <input...></input> guarda come mi diverto<input...></input></form>); per inserire del testo (ad esempio tra i campi della form) bisogna usare l'elemento
testo
ed indicare nel suo attributo for
il name
dell'elemento a cui si riferisce il testo contenuto. Se non viene specificato l'attributo for
allora il contenuto testuale di tale elemento verra' posizionato a discrezione del DF.form
uno o piu' elementi action
. Si veda la descrizione di tale elemento nel paragrafo 7.2.2.8 .In un
menuContestuale
possono essere inserite delle informazioni aggiuntive su una risorsa (Guida, Itinerario o PdI?). Ogni menuContestuale
è associabile ad una scheda del DS e/o ad ogni sottoelemento di una scheda del DS, oppure ad un elenco del DS e/o ad ogni suo possibile sottoelemento.
Per specificare l'associazione tra un menuContestuale ed una risorsa del DS si possono usare i due seguenti metodi:
codice
di menuContestuale e nell'attributo altreInfo
di una qualunque scheda o elenco e relativi sottoelementi. Il DF esaminando il menuContestuale A, con attributo codice avente id 123, andra' a cercare una scheda/elenco o sottoelementi contenenti il valore 123 nell'attributo altreInfo; una volta trovata la corrispondenza potra', ad esempio, visualizzare il menuContestuale in una posizione vicina all'elemento DS associato. La generazione di questi id deve essere univoca rispetto ad una singola richiesta di formattazione al DFxpath
di menuContestuale un xpath vero e proprio la cui valutazione su di una scheda/elenco del DS restituisca un nodo o un insieme di nodi. Il DF valutando l'xpath riesce a recuperare gli elementi del DS che sono associati al menuContestuale sottoposto a valutazione e di conseguenza puo' decidere una formattazione adeguata al caso. Si noti che, contrariamente al primo metodo, questo puo' generare una associazione 1->N (rispetto alla precedente 1->1), e' compito del DF decidere politiche di formattazione adeguate a questo caso. codice
, per il secondo e terzo uso xpath
ecc, tutto questo rispetto ad una singola richiesta di formattazione).
Le informazioni aggiuntive che possono essere specificate tramite un menuContestuale
si trovano nei suoi sottoelementi:
elementiCorrelati
elenco
e scheda
a cui e' stato aggiunto l'attributo href
; (eg: <PdI href="http://tw.web.cs.unibo.it/ac.php?query=parigi"/>
indica che alla scheda attualmente visualizzata e' associato il PdI? ottenibile mediante la ricerca specificata nell'attributo href)
navigazione
precedente
/ successivo
che descrivono un percorso di navigazione a partire da quella risorsa e una lista di link refInterno
che definiscono un percorso di navigazione all'interno della risorsa (ad esempio link ai punti di interesse contenuti in un itinerario);
altriLink
link
arbitrari (che puntano a risorse esterne al portale).
Un
menuStatico
rappresenta una serie di link a risorse non collegate con la scheda o l'elenco di voci mostrate all'utente.
L'attributo opzionale titolo
indica il titolo del menuStatico
.
All'interno di un elemento menuStatico
possono essere presenti solo degli elementi link
Gli elementi contenuto
possono essere usati per indicare delle informazioni funzionali della pagina. In particolare servono per esprimere tutte le informazioni che non riguardano, e non sono esprimibili tramite, :
tipo
permette di indicare al formatter che gli elementi presenti in un certo contenuto
hanno significato particolare e dovrebbero essere presenti in maniera diversa dai normali contenuto
. I valori assumibili da questo attributo sono:
contenuto
il cui significato semantico non e' precisabile (perche' non esiste o effettivamente non ne ha) si assegna il valore generico all'attributo tipo
.
All'interno di contenuto
, insieme al semplice testo, possono essere utilizzati un largo numero di elementi molto simili ai rispettivi HTML (e definiti in comune con il DS) a meno del primo (definito solo per il DF e non presente direttamente in HTML):
action
:un riferimento ad una azione che l'utente puo' eseguire sull'AC, si veda la descrizione di tale elemento nel paragrafo 7.2.2.8;link
:un link ad una risorsa esterna;img
:un'immagine;ul
e ol
:liste in cui l'ordine degli elementi (li
) non conta, liste ul
, e liste in cui l'ordine conta, liste ol
;table
:una tabella.p
:paragrafo di testo decorabile con elementi quali br, em, q ...h1 h2 h3
:header
Ogni elemento editor
indentifica una form con la quale l'utente può modificare il contenuto di una scheda del data-source oppure con la quale puo' editare una nuova scheda da aggiungere al data-source.
titolo
indica il titolo della form contenuta.
L'attributo obbligatorio tipo
permette di indicare al formatter la tipologia dell'editor da formattare;
Esistono tre valori possibili per l'attributo tipo
:
pdi
itinerario
guida
editor
è l'elemento form
molto simile al corrispettivo HTML ma senza gli attributi presentazionali come id
e style
.
Per le particolarita' dell'elemento form
fare riferimento alla sezione 7.2.2.3 .
L'elemento action
e' un collegamento ad una funzionalita' dell'AC, o meglio definito come un punto in cui l'utente puo' richiamare l'AC per richiedere un'azione.
L'attributo "extra" permette di indicare informazioni aggiuntive sull'azione.
L'elemento action puo' essere trasformato in un link o in un button XHTML (nell'output) a discrezione del DF.
Tale elemento permette al DF di distinguere visivamente link di navigazione da link riservati ad azioni. Il DF puo' inoltre decidere di trasformare tale elemento in un button
XHTML il cui tipo non puo' pero' essere submit
o reset
.
È possibile arricchiere i dati ricevuti dai DS con informazioni aggiuntive.
Per fare questo si possono aggiungere vari attributi opzionali ascheda
, elenco
, guidacompleta
e commenti
ed ai loro sotto-elementi.
Questi attributi aggiuntivi sono tre:
href
descrizione
href
;
altreInfo
codice
dell'elemento menuContestuale
che contiene altre informazioni correlate all'elemento d'appartenenza.
La richiesta di
formattazione di un dato frammento di documento è realizzata in modo simile alla formattazione di un intero documento.
La differenza principale e' che la specifica di un layout o skin serve soltanto come reminder per il DF e non come facolta' di scelta. Il DF infatti, in quanto stateless, ha bisogno di conoscere il layout al quale appartiene il frammento da formattare. Il frammento restituito dal DF
avra' come skin e layout quelli gia' stabiliti al momento della formattazione del documento dal quale il frammento proviene.
La formattazione di un frammento prevede l'invocazione del metodo String formattaFrammento(int currentayout, int currentskin, String mioFrammento)
cosi come definito nel WSDL fornito dal DF. L’applicazione nel parametro "mioDocumento" dovra' inserire la stringa ottenuta dal documento XML da formattare.
Di seguito è riportato un
esempio di richiesta: l’applicazione chiede al Formatter di formattare i dati
contenuti nel parametro mioFrammento
, aventi associati il layout 12 con skin 13
result = formatta_frammento(12, 13, mioFrammento)
Il formatter risponde a tale richiesta con una stringa contenente la porzione di documento (pronta per essere inserita dall'Ajax Engine nel documento visualizzato all'utente), secondo le specifiche riportate in sez. 8.3.
Il Formatter produce tre tipi di output: l’elenco dei layout disponibili, interi documenti formattati e porzioni di documenti formattate.
L’applicazione può chiedere al Formatter l’elenco dei layout a disposizione e le relative informazioni, come descritto in sez. 7.1. L'elenco dei layout racchiude informazioni sui layout messi a disposizione dal formatter ed e' validato dal seguente schema:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sch="http://purl.oclc.org/dsdl/schematron" xmlns="http://vitali.web.cs.unibo.it/view/TechWeb07/WorkingGroupACDF" xmlns:df="http://vitali.web.cs.unibo.it/view/TechWeb07/WorkingGroupACDF" targetNamespace="http://vitali.web.cs.unibo.it/view/TechWeb07/WorkingGroupACDF"> <!-- Inclusione degli elementi comuni con il DataSource --> <xs:include schemaLocation="DFtesto.xsd"/> <xs:element name="elencoLayout"> <xs:complexType> <xs:sequence> <xs:element name="layout" type="layout_t" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="layout_t"> <xs:sequence> <xs:element name="nome" type="xs:string"/> <xs:element name="urlEsempio" type="xs:anyURI" minOccurs="0" /> <xs:element name="descrizione" type="testoSemplice_t" minOccurs="0"/> <xs:element name="skin" type="skin_t" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="id" use="required" type="xs:NMTOKEN"/> </xs:complexType> <xs:complexType name="skin_t" mixed="true"> <xs:group ref="testoSemplice_g"/> <xs:attribute name="id" use="required" type="xs:NMTOKEN"/> <xs:attribute name="url" use="required"/> </xs:complexType> </xs:schema>Le informazioni relative ad ogni layout sono espresse tramite l'attributo
id
e gli elementi nome
, urlEsempio
, descrizione
e skin
:
id
: l'identificatore del layout. È utilizzato nella richiesta di formattazione (sezioni 7.2 e 7.3) per specificare il tipo di layout da applicare al documento;
nome
: il nome del layout;
urlEsempio
: l'URL di un documento di esempio che mostra il layout e la sua resa grafica finale;
descrizione
: una descrizione human-readable del layout, del tipo di formattazione che produce, dell'organizzazione della pagina, della divisione in blocchi, etc;
skin
: il nome di una skin che specifica lo stile grafico da applicare al layout. L'attributo id
è l'identificatore univoco della skin ed è usato nelle richieste di formattazione di dati al DF. L'attributo url
contiene l'URL della skin in formato CSS.
id
, l'elemento nome
ed almeno una skin
. Gli elementi urlEsempio
e descrizione
sono facoltativi.
Di seguito è riportato un esempio di elenco di layout:
<?xml version="1.0" encoding="UTF-8"?> <elencoLayout xmlns="http://vitali.web.cs.unibo.it/view/TechWeb07/WorkingGroupACDF" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://vitali.web.cs.unibo.it/view/TechWeb07/WorkingGroupACDF http://tomasell.web.cs.unibo.it/schema/elencoFormatter.xsd"> <layout xmlns="" id="1"> <nome>Normale</nome> <urlEsempio>http://tw.web.cs.unibo.it/esempi-formatter/normale.pdf</urlEsempio> <descrizione>Un layout con le sole informazioni</descrizione> <skin id="1" url="http://tw.web.cs.unibo.it/skin/layout1-giallo.css">Giallo</skin> <skin id="2" url="http://tw.web.cs.unibo.it/skin/layout1-verde.css">Verde</skin> </layout> <layout xmlns="" id="2"> <nome>Informazioni essenziali</nome> <skin id="1" url="http://tw.web.cs.unibo.it/skin/layout2-bn.css">Bianco e nero</skin> </layout> <layout xmlns="" id="3"> <nome>TUTTO!</nome> <urlEsempio>http://tw.web.cs.unibo.it/esempi-formatter/tutto.png</urlEsempio> <descrizione>Un layout semplicemente folle, c'è tutto! Vi lascerà a bocca aperta!</descrizione> <skin id="gothic" url="http://tw.web.cs.unibo.it/skin/layout3-gothic.css">Stile goth</skin> <skin id="puppy" url="http://tw.web.cs.unibo.it/skin/layout3-puppy.css">Cagnolini</skin> <skin id="train" url="http://tw.web.cs.unibo.it/skin/layout3-trainspotting.css">Trainspotting</skin> </layout> </elencoLayout>
L’operazione principale che il Formatter esegue è la generazione di un documento adatto alla visualizzazione a partire da un XML di dati (tipicamente non pensati per la visualizzazione) forniti in input.
È importante notare che l’output del Formatter è il documento pronto per la visualizzazione, per cui l’applicazione deve semplicemente inoltrarlo allo user-agent ed aggiungere le informazioni necessarie per una corretta visualizzazione. L’informazione da aggiungere è il content/type, che specifica appunto il tipo di dato prodotto. Il content-type è definito dal Formatter che lo invia assieme al documento formattato all’applicazione, che a sua volta inoltra questi dati allo user-agent. Fondamentalmente possono presentarsi due casi: output testuali (ed XML) e output binari.
E' importante inoltre ribadire che tutte le pagine (home, help, ricerca, etc.) devono essere formattate dal DF.
Nel caso di DF-XHTML e' infine fondamentale notare che ogni DF deve obbligatoriamente generare degli id univoci da associare ad ogni sezione del suo output; il DF deve inoltre usare gli stessi id generati anche nel caso di una formattazione di frammento. Questo e' indispensabile per garantire una corretta sostituzione del frammento generato quando questo arriva all'AC.
Un Formatter che produce pagine per i browser per PC o per device mobili, genera documenti HTML o XHTML. È inoltre possibile pensare a Formatter in grado di produrre documenti TEX o pagine Wiki e semplici file di testo.
In questo caso il Formatter risponde con una stringa contenente il documento trasformato. L'applicazione, in base al valore del campo "type" presente nel catalogo, specifica nell’header il content-type (application/xhtml+xml, application/pdf, etc.).
Il caso in cui il Formatter produce output binari, ad esempio file PDF, è da un punto di vista del protocollo identico al precedente con due differenze:
NOTA BENE: per garantire l'assenza di errori SOAP nell'invio di un contenuto binario e' obbligatorio codificare la "stringa" mediante la funzione rawurlencode
di PHP prima di restituire la stringa in output.
Questa sara' poi decodificata dall'AC mediante la rawurldecode
o la decodeURIComponent
in caso di AC JavaScript?
id
del nodo skin
specifica l'ID con il quale l'AC si può riferire ad una skin, mentre l'attributo url
contine l'URL della skin in formato CSS.
Il comportamento del formatter è diverso nel caso di supporto diretto dei CSS da parte dello user-agent o meno. In altri termini: in un documento XHTML è possibile semplicemente aggiungere il riferimento al CSS ma ad esempio in un PDF è necessario esprimere in modo alternativo le stesse proprietà. Di conseguenza il formatter, se produce documenti XHTML (o XHTML o XML) associa al documento direttamente il CSS e lo rispedisce all'applicazione, altrimenti recupera questa risorsa, interpreta le regole ed assegna la corretta formattazione al documento che sta producendo.
Si consideri ad esempio un formatter che produce file PDF utilizzando XSL-FO e riceve questa richiesta:
formatta_documento(12, 13, mioDocumento);Il CSS della skin richesta contiene la regola:
p { font-family: Arial; }Il formatter applica il layout con id
12
e, per applicare la skin, legge il CSS associato all'id 13
, trasforma questa regola in sintassi XSL-FO, la applica ad un blocco
<fo:block font-family="Arial">Contenuto del paragrafo</fo:block>e genera il risultato tramite un convertitore. Nel PDF finale il testo del paragrafo sarà di tipo Arial come richiesto dall'applicazione. NOTA BENE: tutto questo e' possibile poiche' e' il DF ha fornire le skin associabili ad un documento (PDF in questo caso), quindi il DF sa interpretare correttamente le regole di skin e produrre quindi un output corretto.
Nel caso in cui l'AC sia client-side (architettura Ajax) l’operazione principale che il Formatter esegue è la generazione di un frammento di documento adatto alla visualizzazione a partire da un XML di dati (tipicamente non pensati per la visualizzazione) forniti in input.
NOTA BENE: il funzionamento dell'architettura Ajax non richiede la presenza di script javascript nel DF. L'unica differenza per il DF e' la ricezione di richieste formatta_frammento
anzi che formatta_documento
. Eventuali script javascript risiederanno esclusivamente lato client (nell'AC) ed il DF si limita ad includerli, durante la formatta_documento
, ignorandone il funzionamento e/o lo scopo ma semplicemente seguendo le direttive specificate nel parametro ajaxInfo
.
Il mantra da seguire, affinche' l'architettura Ajax possa funzionare, e' quello di generare nel DF degli id univoci da associare ad ogni elemento dell'output generato; tali id dovranno essere coerenti nel tempo riguardo alla generazione dello stesso elemento di output e solo grazie a questo l'AC, in seguito ad una formatta_frammento, potra' eseguire la sostituzione corretta del frammento vecchio con quello nuovo.
Esempio: l'AC l richiede la formattazione di una pagina contenente, tra le varie cose, un menuStatico
. Il DF genera, nell'output XHTML, un elemento opportuno (ad esempio un div) per rappresentare il menuStatico e soprattutto marchia questo div con un id univoco.
Successivamente l'AC (questa volta Ajax, client-side) potra' richiedere la formattazione di un nuovo menuStatico
; in questo caso il DF deve generare un nuovo elemento di output (in questo caso un frammento) per rappresentare il menuStatico. Nel farlo deve marchiare tale elemento con lo stesso id usato la prima volta; solo cosi l'AC (Ajax, client-side) potra' sostituire il nuovo frammento basandosi esclusivamente sull'id associato (in javascript: getElementById) ed essere sicuro di sostituire effettivamente il vecchio menuStatico con quello nuovo.
Data la complessita' dell'architettura Ajax, ed affinche' tutto funzioni, e' consigliato riflettere accuaratamente su quanto appena espresso.
L'output del formatter, ovvero della funzione formatta_frammento
, è un documento XML che ha come radice l'elemento frammenti
. È compito dell'AC integrare questi frammenti con il documento finale.
I dati restituiti dal formatter in seguito ad una richiesta di formattazione dati devono validare il seguente schema:
<?xml version="1.0" encoding="UTF-8"?> <grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> <start> <ref name="frammenti"/> </start> <define name="frammenti"> <element name="frammenti"> <zeroOrMore> <ref name="ANYConID"/> </zeroOrMore> </element> </define> <define name="ANYConID"> <element> <anyName/> <zeroOrMore> <attribute> <anyName> <except> <name ns="">id</name> </except> </anyName> </attribute> </zeroOrMore> <attribute name="id"> <data type="NMTOKEN"/> </attribute> <mixed> <zeroOrMore> <element> <anyName/> <ref name="ANY"/> </element> </zeroOrMore> </mixed> </element> </define> <define name="ANY"> <zeroOrMore> <attribute> <anyName/> </attribute> </zeroOrMore> <mixed> <zeroOrMore> <element> <anyName/> <ref name="ANY"/> </element> </zeroOrMore> </mixed> </define> </grammar>
NOTA BENE: Tale schema e' espresso in relax-ng poiche' quanto volevasi esprimere e' risultato probabilmente non esprimibile in xml-schema. Tuttavia lo scopo di questo schema e' di assicurarsi che, nell'output della formatta_frammento di un DF, ogni sotto elemento di frammenti
sia un qualunque elemento xml ma avente, obbligatoriamente, il relativo attributo id
associato. Tale restrizione sull'attributo id e' relativa solo ai figli diretti di frammenti
(ovvero presenti al primo livello dell'albero xml) ma non ai loro ulteriori figli.
Per rendere piu' chiara la situazione vediamo un esempio di output valido per la formatta_frammento ed un esempio non valido.
Esempio valido:
<frammenti> <div id="123"> <div></div> </div> <div id="456"> <div></div> </div> </frammenti>
Come vedete ogno figlio diretto di frammenti
possiede il suo id associato. Nota, non e' obbligatorio usare elementi div
, la restrizione infatti non lavora sul nome dell'elemento ma esclusivamente sulla presenza dell'attributo.
Vediamo ora un esempio non valido:
<frammenti> <div> <div></div> </div> <div> <div></div> </div> </frammenti>
Come vedete ogno figlio diretto di frammenti
non possiede il suo id associato. Nota, non e' obbligatorio usare elementi div
, la restrizione infatti non lavora sul nome dell'elemento ma esclusivamente sulla presenza dell'attributo.
In conclusione quanto espresso in questo paragrafo vuole piu' che altro indicare la strada corretta affinche' l'architettura Ajax possa funzionare correttamente.
Le richieste inoltrate al Data Formatter possono generare diversi errori. Per gestirli il protocollo del DF prevede un messaggio di errore che riporta un codice ed una descrizione human-readable per l’errore. Per indicare un messaggio di errore il DF dovra' generare una SoapFault in questo modo:
return new SoapFault("CodiceDiErrore", "Descrizione dell'errore");
Questa azione generera' una eccezzione soap che dovra' e potra' essere gestita nell'AC in questo modo:
try { //.....Altro codice..... $client = new SoapClient('http://tomasell.web.cs.unibo.it/DF.wsdl'); //.....Altro codice..... $result = $client->__soapCall('richiedi_elenco', array()); //.....Altro codice..... } catch (SoapFault $soapFault) { trigger_error("Errore di SOAP: (codice di errore: {$soapFault->faultcode}, descrizione dell'errore: {$soapFault->faultstring})", E_USER_ERROR); }
Il blocco try & catch garantisce che ogni eccezzione di SOAP (incluse quelle generate nel DF) venga gestita e catturata. Ogni gruppo potra' decidere come comportarsi in presenza di un errore, di conseguenza il codice presente nel catch
e' assolutamente libero e non obbligatorio. Non e' obbligatorio restituire all'utente esattamente l'errore generatosi.
L'utilizzo delle eccezzioni SOAP al posto di una grammatica apposita semplifica la gestione degli errori, uniformandola e aggiungendo coerenza all'utilizzo dei webservices.
Viene riportata di seguito una tabella con i possibili errori e relative descrizioni:
Codice errore | Descrizione Errore |
---|---|
00 | Formatter non disponibile |
10 | Dati in input errati |
20 | Layout richiesto inesistente |
30 | Skin richiesta inesistente |
MODIFICA: Aggiornata la gestione degli errori.
5.1 MODIFICA: Aggiornato il WSDL, aggiunto SoapFault?
8.4 MODIFICA: Aggiornata la gestione degli errori.