Continuiamo la discussione su D2R Server trattando la generazione e il controllo sul modello e presentando le modalità operative per l’uso del server online. Si vedranno alcune interessanti possibilità offerte dal server.
Generazione e controllo sul modello
D2R permette di gestire anche la parte del modello. In pratica, essendo D2R Server orientato al LinkedData prevede di default la generazione di classi e proprietà istanziate. In questo modo, anche in assenza del modello, il server è in grado di avere dei riferimenti minimi alle definizioni di classi e proprietà riferite.
Ciò fa sì che in assenza di configurazioni particolari tutte le classi riferite con d2rq:class e le proprietà riferite con d2rq:property vengano generate e inserite nell’eventuale file di dump come rdfs:Class e rdfs:Property.
Nel caso di esempio, effettuando il dump, oltre alle istanze vengono generate classi e proprietà che di fatto sono già definite nel file specifiche.owl:
... foaf:Person a rdfs:Class . foaf:currentProject a rdf:Property . ...
Si noti che nel file di modello usato in realtà sono definite come owl:Class e owl:ObjectProperty. In questo modo il server D2R può generare direttamente anche una navigazione dalle istanze alle classi e le proprietà con lo stesso mapping (senza bisogno di avere il file di modello vero e proprio specifiche.owl).
In molti casi questo comportamento non è desiderabile, in quanto genera meta-informazioni non necessarie che sporcano le istanze e si sovrappongono (non in maniera errata comunque) con il modello vero e proprio.
Nella configurazione di D2R è possibile specificare di non generare nessun meta-dato, ossia di non creare le classi e property di modello riferite nel mapping. Per far questo basta definire una map:Configuration in cui si mette a false il flag d2rq:serveVocabulary:
map:Configuration a d2rq:Configuration; d2rq:serveVocabulary false; .
Di default il flag è true.
Per ulteriori dettagli su come usare Configuration si veda la documentazione ufficiale [5].
Aggiunta di meta-proprietà al modello: d2rq:AdditionalProperty
Nel caso si voglia lasciare che D2R rigeneri anche il modello, è possibile comunque agire e customizzare il modello stesso, aggiungendo delle meta-proprietà alle classi e alle property in modo da customizzare il modello a piacimento (in termini di annotazione, label, comment e tipizzazione).
Per caratterizzare classi e proprety associando opportuni attributi è possibile usare l’elemento d2rq:AdditionalProperty e poi richiamare l’AdditionalProperty o da un ClassMap o da un PropertyBridge.
Per esempio, se volessimo specificare che la classe spec-m:RequisitoNonFunzionale è non solo una rdfs:Class (meta-classe aggiunta di default) ma anche una owl:Class e che la sua label è “requisito non funzionale” potremmo aggiungere due AdditionalProperty come segue:
map:OWLClassTypeCasting a d2rq:AdditionalProperty; d2rq:propertyName rdf:type; d2rq:propertyValue owl:Class; . map:OWLReqNFunz_Class_Label a d2rq:AdditionalProperty; d2rq:propertyName rdfs:label; d2rq:propertyValue "Requisito non funzionale"; .
Per poi richiamarlo nel ClassMap associato a questa classe tramite l’uso di d2rq:additionalClassDefinitionProperty:
map:Requisito_nfun a d2rq:ClassMap; d2rq:dataStorage map:databaseReq; d2rq:condition "Requisiti$.Tipo <> 'fun'" ; d2rq:uriPattern "requisito-@@Requisiti$.Tipo@@_@@Requisiti$.Codice@@"; d2rq:class spec-m:RequisitoNonFunzionale; d2rq:additionalClassDefinitionProperty map:OWLClassTypeCasting; d2rq:additionalClassDefinitionProperty map:OWLReqNFunz_Class_Label; .
Effettuando un dump di questo mapping otterremmo quindi fra le istanze anche la definizione della classe di modello spec-m:RequisitoNonFunzionale come segue:
spec-m:RequisitoNonFunzionale owl:Class , rdfs:Class ; rdfs:label "Requisito non funzionale" .
che per l’appunto non è una istanza generata a partire dai dati presenti sul DB ma è una definizione di classe del modello generata da D2R con l’aggiunta di due AdditionalProperty (owl:Class e rdfs:Label).
Allo stesso modo, è possibile agire sulle property, per specificare per esempio il tipo di property (Datatype o Objectype) ed eventuali domain e range.
Nell’esempio vengono definite tre AdditionalProperty: una per specificare il tipo (owl:ObjectProperty), una per specificare il dominio e una per il range:
map:Requisito_di_PropertyCasting a d2rq:AdditionalProperty; d2rq:propertyName rdf:type; d2rq:propertyValue owl:ObjectProperty; . map:Requisito_di_PropertyDomain a d2rq:AdditionalProperty; d2rq:propertyName rdfs:range; d2rq:propertyValue spec-m:ProgettoSoftware; . map:Requisito_di_PropertyRange a d2rq:AdditionalProperty; d2rq:propertyName rdfs:domain; d2rq:propertyValue spec-m:RequisitoNonFunzionale; .
A questo punto le tre AdditionalProperty devono essere associate alla proprietà relativa e per fare questo si usa d2rq:additionalPropertyDefinitionProperty all’interno della definizione del PropertyBridge:
map:Requisito_requisito_di rdf:type d2rq:PropertyBridge ; d2rq:belongsToClassMap map:Requisito_fun, map:Requisito_nfun ; d2rq:uriPattern "progetto-@@Requisiti$.IdProgetto@@" ; d2rq:property spec-m:requisito_di ; d2rq:additionalPropertyDefinitionProperty map:Requisito_di_PropertyCasting; d2rq:additionalPropertyDefinitionProperty map:Requisito_di_PropertyDomain; d2rq:additionalPropertyDefinitionProperty map:Requisito_di_PropertyRange; .
Il risultato di queste proprietà aggiuntive è una definizione della proprietà nel dump come segue:
spec-m:requisito_di a rdf:Property , owl:ObjectProperty ; rdfs:domain spec-m:RequisitoNonFunzionale ; rdfs:range spec-m:ProgettoSoftware .
Uso del server online
Una volta creato un file di mapping (anche se non definitivo) il modo più semplice di testarlo è avviare il server e navigare le istanze via Web tramite LinkedData.
Il server può essere avviato come servizio Windows (o Linux), deployato come webapp in un servlet container o avviato da riga di comando. Per ulteriori dettagli sulle modalità di avvio del server e sulla sua configurazione si faccia riferimento alla documentazione ufficiale [6].
Per quato attiene a questo articolo, ci limiteremo a mostrare come avviare il server da linea di comando.
Avviare il server da linea di comando
Aprire il prompt dei comandi e posizionarsi alla root di D2RServer (quella scaricata da SVN o scompattata da ZIP versionato). Poi digitare:
> d2r-server custom_mappingD2R_UnionMapping_Prog_e_Req.n3
A questo punto, basta collegarsi via browser all’indirizzo configurato (nel nostro esempio http://localhost:2020) per accedere alla homepage del server appena avviato.
Navigazione LinkedData integrata
Partendo dalla homepage di D2RServer è possibile iniziare subito la navigazione attraverso i concetti mappati e le istanze generate con le relative proprietà e relazioni. Nella prima riga sotto il titolo si possono vedere i link ai ClassMap generati e quindi alle istanze delle varie classi mappate.
Cliccando per esempio su Progetti verrà visualizzata la lista delle istanze di progetto mappate
Cliccando uno di questi progetti, ha inizio la navigazione LinkedData (ossia dove ogni elemento dell’ontologia viene associato a runtime all’URL relativo del server).
La tabella lista tutti i valori per le proprietà definite dove, ogni valore di relazione verso un’altra istanza è a sua volta un link ad un’altra scheda di istanza.
Figura 6 – La tabella con la lista tutti i valori per le proprietà definite.
Cliccando per esempio sul link a fianco alla property doap:mantainer otteniamo la scheda del responsabile di progetto “Marco Rossi”.
Cliccando invece su link a destra di una delle proprietà “is spec-m:requisito_di of“, vedremo il dettaglio del requisito selezionato per quel progetto.
Va notato come la navigazione è assolutamente trasparente al fatto che le due informazioni derivino da due sorgenti dati fra loro scollegate. L’utente ha quindi la percezione di una integrazione totale fra i concetti e le valorizzazioni dei dati.
Relazioni inverse
C’è un’altra nota importante relativa alle relazioni inverse: va infatti considerato che anche se da mapping non è stata valorizzata la relazione da progetto a requisito “ha_requisito“, la navigazione sfrutta la relazione inversa (da requisito a progetto => “requisito_di“) e la mostra anche dal Progetto ma nella forma passiva “is requisito_di of“. Chiaramente funzionerebbe meglio se la relazione si chiamasse solo “project“, che passivato diventerebbe “is project of“, ma, insomma, il discorso è abbastanza chiaro.
In questo modo, si vedono i requisiti connessi al progetto anche se la relazione è valorizzata a partire dal requisito. Si noti infatti che, aprendo invece un requisito, la stessa relazione è espressa non più in forma passiva ma diretta (spec-m:requisito_di).
SPARQL Endpoint integrato e interrogazione
Dalla homepage del server lanciato (http://localhost:2020), è possibile accedere all’interfaccia di interrogazione SPARQL dell’endpoint cliccando sul link in fondo ” his AJAX-based SPARQL Explorer” (http://localhost:2020/snorql).
Notiamo, a proposito di SPARQL EndPoint Service, che l’endpoint è accessibile anche come servizio REST all’url http://localhost:2020/sparql dove, passando gli opportuni parametri (protocollo standard di interrogazione via http [6]) è possibile interrogarlo da una applicazione o da un tool esterno via GET e POST (per esempio usando JENA, [7]).
Da questa pagina è possibile effettuare query SPARQL e visualizzare la lista dei risultati navigabili sempre in modalità Linked Data.
Cliccando sul link dell’URI di un riga dei risultati (p.e.: <http://localhost:2020/resource/progetto-2>) si innesca una ulteriore query di dettaglio che mostra tutte le proprietà uscenti e entranti dall’istanza.
Cliccando invece sulla piccola freccia blu associata ad ogni URI si accede alla navigazione LinkedData vista precedentemente.
È anche possibile specificare un formato differente per i risultati restituiti, cambiando il valore nel comboBox Results: i formati possibili sono le serializzazioni JSON o XML.
Federated Query
A differenza del dump che, come vedremo non ha problemi, le query federated che coinvolgono elementi di due sorgenti non sono possibili. Questo perche’ il sistema di trasformazione delle query SPARQL -> SQL ancora non gestisce correttamente le query cross database. La feature però è ovviamente molto richiesta e si sta lavorando per cercare di farla funzionare correttamente nelle future versioni. Un esempio di query federated che non può funzionare live (ma sul dump invece funziona) è:
SELECT DISTINCT ?prog_label ?requisito_label WHERE { ?requisito spec-m:requisito_di ?progetto; rdfs:label ?requisito_label. ?progetto rdfs:label ?prog_label . } ORDER BY ?prog_label ?requisito_label
La query, se effettuata live, dà un errore del tipo:
[Microsoft][Driver ODBC Excel] Il modulo di gestione di database di Microsoft Office Access non è riuscito a trovare l'oggetto 'Progetti'. Assicurarsi che l'oggetto esista e che il nome e il percorso siano digitati correttamente.: SELECT DISTINCT "T2_Requisiti$"."Titolo", "T1_Requisiti$"."Codice", "T1_Requisiti$"."Tipo", "T1_Requisiti$"."IdProgetto", "T3_Progetti"."Nome" FROM "Progetti" AS "T3_Progetti", "Requisiti$" AS "T1_Requisiti$", "Requisiti$" AS "T2_Requisiti$" WHERE ("T1_Requisiti$"."Codice" = "T2_Requisiti$"."Codice" AND "T1_Requisiti$"."IdProgetto" = "T3_Progetti"."ID" AND "T1_Requisiti$"."Tipo" = "T2_Requisiti$"."Tipo" AND (Requisiti$.Tipo = 'fun'))
Conclusioni
In questa seconda parte della serie siamo entrati in aspetti più operativi, che ci hanno consentito di mettere le mani direttamente sulle potenzialità e sulle modalità operative con cui funziona D2R Server. Nel successivo articolo, concluderemo questa miniserie parlando di importazione di modelli, di Jena e presentando alcune note finali.
Riferimenti
[1] Un tutorial abbastanza completo sull’uso di D2R Server con un DB MySQL
http://sw.cs.technion.ac.il/d2rq/tutorial
[2] Guida per connettere una sorgente relazionale mappata tramite D2R con l’endpoint JOSEKI 2
http://www4.wiwiss.fu-berlin.de/bizer/d2rmap/usecases/joseki/D2R4joseki2.pdf
[3] D2R/Update Server, un tutorial sull’uso di D2R Server per effettuare query con SPARQL Update e quindi andare in scrittura sul DB
http://d2rqupdate.cs.technion.ac.il/tutorial
[4 ] SPARQL 1.1 Update. W3C Working Draft
http://www.w3.org/TR/2009/WD-sparql11-update-20091022/
[5] Configurazione del motore di mapping in DR2Server e avvio del server.
http://d2rq.org/d2rq-language#configuration
[6] Query Sparql
http://www.w3.org/TR/rdf-sparql-protocol/#query-bindings-http
[7] The D2RQ Mapping Language
http://d2rq.org/d2rq-language#sparql
Nato a Imola nel 1978, ha conseguito la laurea Specialistica in informatica nel 2005 presso l‘Università di Bologna con una tesi sull‘"Estrazione di Ontologie da Framework standardizzati EDI/XML". Per tre anni ha lavorato come ricercatore presso il centro ENEA di Bologna seguendo progetti sull‘applicazione di tecnologie semantiche a framework e standard per l‘interoperabilità come ebXML o UBL, pubblicando insieme ad altri ricercatori diversi articoli su tali argomenti.
Attualmente è consulente presso Imola Informatica S.r.l. dove si occupa di piattaforme Java EE based e progetti sul Semantic Web, e i suoi interessi principali si orientano alle piattaforme enterprise basate su middleware semantici, Ontology Engeenering e alle interfacce basate su AJAX e GWT.