Mozilla memorizza le informazioni RDF in qualcosa chiamato datasource.
Ogni datasource contiene una serie di triple RDF. Puoi fare una
ricerca delle triple nelle sorgenti di dati con diversi metodi. Questo
ti permette di navigare nel grafico RDF o determinare i dati contenuti
nella datasource. Alcune sorgenti di dati sono modificabili,
così si possono aggiungere o rimuovere triple dalla datasource. Puoi usare le sorgenti di dati indipendentemente l'una
dall'altra, oppure puoi combinarle in ciò che viene detto datasource composita. La datasource composita è un
gruppo di sorgenti di dati RDF
Generalmente, ogni datasource contiene dati relazionati in
qualche modo. Per esempio, Mozilla usa una datasource bookmarks
che contiene informazioni sui segnalibri. Mozilla usa diverse sorgenti
di dati, che contengono informazioni e se stai costruendo un'estenzione
per Mozilla, dovresti usare queste sorgenti di dati. Comunque, puoi
anche creare le tue sorgenti di dati. Mozilla supporta anche il parsing
di files RDF/XML in sorgenti di dati.
Tutte le sorgenti di dati implementano l'interfaccia nsIRDFdatasource.
Questa interfaccia offre metodi per ricercare e modificare le
informazioni nella datasource. Queste sono le più comuni
sorgenti di dati offerte da Mozilla che potresti usare:
| datasource |
Descrizione |
|---|---|
| in-memory-datasource | Questo
tipo di datasource tiene le triple RDF in memoria. Molte delle
altre sorgenti di dati sono basate su questa datasource. Questo
tipo di sorgente può essere modificata. |
| xml-datasource | Questa datasource contiene le triple lette da un file RDF/XML. Può tenere traccia del file da cui è stata caricata e salvare le modifiche nel file originale. Questa sorgente supporta anche i files RDF/XML caricati da un URL remoto, anche se questi non possono essere modificati o salvati. Tutte le sorgenti XML implementano l'interfaccia nsIRDFRemotedatasource, anche quelle caricate da files locali. |
| composite-datasource | Contiene
un insieme di altre sorgenti. Quando fai una ricerca in questa
datasource, ricercherai in una sorgente alla volta. Allo stesso modo,
le
modifiche si propagheranno ad ogni sorgente, finché una di loro
accetta il cambiamento. Queste sorgenti implementano l'interfaccia nsIRDFCompositedatasource |
Ci sono molte altri sorgenti di dati, ma queste contengono i dati specifici per le applicazioni Mozilla
Mozilla usa un servizio RDF che è responsabile
dell'acquisizione di sorgenti di dati RDF. Il servizio ritorna anche
altri oggetti riguardanti RDF come oggetti risorsa e letterale.
Le sorgenti di dati sono identificate da un URI. Se usi un URI,
questo risulterà in genere nella creazione di una datasource xml che caricherà RDF/XML da quell'URI.
Mozilla offre alcune sorgenti dati addizionali, che possono essere recuperate usando un URI che inizia con 'rdf:'. Per esempio, l'URI rdf:history ritornerà la sorgente dati history che contiene dati relativi alla cronologia delle pagine visitate. Quando chiedi una sorgente dati di questo tipo, cioè una sorgente con un URI che inizia con 'rdf:', Mozilla cercherà un componente che gestisca quella sorgente. Trova questo componente prendendo la parte di URI dopo il prefisso e la concatena alla stringa @mozilla.org/rdf/datasource;1?name= per formare il nome di un componente. Per esempio l'URI rdf:bookmarks, produrrà il componente @mozilla.org/rdf/datasource;1?name=bookmarks.
Tutte
le sorgenti di dati funzionano in questo modo. Se crei un'estensione
usando questa nomenclatura, sarai in grado di recuperare la sorgente
dati usando il servizio RDF. Puoi anche creare la sorgente dati in un template
impostando l'URI su un attributo di sorgente dati di un elemento. Le
sorgenti di dati 'rdf:' hanno in genere una gestione speciale dei
metodi delle sorgenti di dati, o memorizzano i dati in maniera diversa.
Per esempio, la sorgente dati history memorizza i dati in un formato
diverso e usa del codice per circondare i dati così che possano
essere usate le API RDF per cercare i dati. La sorgente dati bookmarks
memorizza i dati in un formato proprietario, ma usa una in-memory-datasource per tenere i dati quando caricata.
Il servizio RDF ha due metodi per recuperare le sorgenti dati. Il primo metodo, GetDataSource
è usato per caricare una sorgente dati in maniera asincrona.
Questa funzione può ritornare prima che la sorgente dati sia
completamente caricata, anche se i dati già caricati saranno
subito disponibili. Le sorgenti dati 'rdf:' sono in genere disponibili
subito, visto che il browser ne farà già uso. Inoltre, le
sorgenti 'rdf:' faranno subito tutte le inizializzazioni. Questo
significa che il metodo GetDataSource è adatto a caricare questo
tipo di sorgenti di dati. Dovresti usare questo metodo per caricare
file RDF/XML remoti, in modo da poterli caricare in background.
Più tardi vedremo un metodo per capire se il caricamento
è completo.
Il secondo metodo, GetDataSourceBlocking preleva una datasource e aspetta che sia caricata. Questo metodo può essere usato per files locali RDF/XML. Questo metodo ritornerà non appena la datasource è stata caricata e parserizzata. Questo metodo per ora non funziona su files remoti.
Entrambe i metodi prendono un argomento singolo, l' URI della
sorgente dati da caricare ed entrambe ritornano la sorgente dati. Nel
caso della funzione GetDataSource, la sorgente dati è ritornata,
ma può non contenere ancora dati. Ecco alcuni esempi delle
funzioni
var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].
getService(Components.interfaces.nsIRDFService);
var historyDS = rdfService.GetDataSource("rdf:history");
var fileDS = rdfService.GetDataSourceBlocking("file:///somedir/somefile.rdf");
Prima, otteniamo il servizio RDF. Dal momento che è un servizio, usiamo getService invece di createInstance. La linea successiva carica la datasource history usando la funzione GetDataSource. Infine, carichiamo un file RDF/XML usando la funzione GetDataSourceBlocking, che può essere modificato immediatamente. Ognuna delle sorgenti di dati caricate implementa l'interfaccia nsIRDFDataSource.
Per le sorgenti di dati 'rdf:', GetDataSource e
GetDataSourceBlocking creano la nuova datasource come servizio.
Questo significa che può esistere solo una copia della sorgente
dati alla volta. Fai attenzione a questo quando implementi le tue
sorgenti dati. Se vuoi che sia creata una sorgente dati differente ogni
volta, avrai bisogno di creare il componente nella normale maniera
XPCOM, con il metodo createInstance. Per esempio, per creare una nuova in-memory-datasource (sorgente dati in memoria), fai così:
var inmemds = Components.classes["@mozilla.org/rdf/datasource;1?name=in-memory-datasource"]
.createInstance(Components.interfaces.nsIRDFDataSource);
Questo è necessario perché non volevi usare ogni volta gli stessi dati in memoria.
Il servizio RDF tiene in memoria ("cache") le sorgenti di dati che
sono state caricate. Questo significa che quando tu provi a richiamare
lo stesso URI usando le funzioni GetDataSource o GetDataSourceBlocking,
il servizio RDF ritornerà lo stesso oggetto. Questo evita di
creare e caricare continuamente la stessa sorgente dati ogni volta che
la si richiede. Inoltre, significa che puoi chiamare il servizio RDF
per la stessa sorgente dati diverse volte e ottenere sempre lo stesso
oggetto.
Tecnicamente, la precedente descrizione non dice esattamente come
lavora la cache. Quando viene chiamata la funzione GetDataSource o
GetDataSourceBlocking, queste funzioni guardano nella cache del server
RDF per cercare sorgenti dati già caricate. Se l'URI viene
trovato, viene caricata quella sorgente dati. Se l'URI non è
trovato, viene creata una nuova sorgente dati del tipo appropriato,
come descritto sopra. Il servizio RDF non aggiunge comunque in cache le
sorgenti dati appena create. Questa è responsabilità
della sorgente dati stessa, che deve chiamare il metodo RegisterDataSource del servizio RDF. Se la sorgente dati non chiama mai questo metodo, non apparirà mai in cache.
Questo creerà una nuova datasource ogni volta. Le
altre sorgenti chiameranno RegisterDataSource così che non venga
creato un nuovo oggetto ogni volta. Quando RegisterDataSource è
chiamato, il servizio RDF richiama l'URI della datasource e la
memorizza nella cache. Nota che è possibile per una datasource
ritornare un URI diverso da quello con cui è stata creata,
che può permettere possibilità interessanti. La
datasource xml, chiama il metodo RegisterDataSource, ma l'URL
sarà
l'URL del file RDF/XML. Una datasource può chiamare il
metodo RegisterDataSource in ogni momento, così è
possibile inserire una sorgente dati in cache subito prima.
Per rimuovere le sorgenti dati dalla cache si usa il corrispettivo metodo UnregisterDataSource.
Questo in genere viene chiamato dal distruttore della sorgente dati,
cioè quando la sorgente dati viene cancellata. Una sorgente dati
viene cancellata quando non esistono più riferimenti nei suoi
confronti. Quando è cancellata, la sorgente dati dovrebbe
deregistrarsi con il servizio RDF e sarà rimossa dalla cache.
Quando l'URL viene chiesto di nuovo, la sorgente dati avrà
bisogno di essere ricreata. Anche se è possibile rimuovere una datasource dal servizio RDF in ogni momento usando
UnRegisterDataSource, la sorgente e i suoi dati continueranno ad
esistere finché ci saranno dei riferimenti nei suoi confronti.
Gli elementi XUL posson avere una sorgente dati associata. Ogni elemento XUL in un documento XUL può avere una sorgente dati, inoltre per altri tipi di elementi inseriti in un documento XUL è possibile avere delle sorgenti dati. Gli elementi che non sono in un documento XUL non possono usare i templates. La sorgente dati associatao con un elemento può essere recuperata chiamando il valore della proprietà database dell'elemento. Il database è sempre una sorgente dati composita (composite-datasource). che contiene un certo numero di sorgenti RDF. Può avere qualsiasi numero di sorgenti dati, anche nessuna, e il set di sorgenti può essere modificato usando i metodi dell'interfaccia nsIRDFCompositeDataSource.
La maggior parte degli elementi non avranno una sorgente dati associata, così la proprietà database sara di tipo null. Puoi indicare che vuoi che un elemento abbia un database aggiungendo l'attributo datasources
all'elemento. Il valore di questo attributo sovrebbe essere una lista
di URI delle sorgenti di dati che devono essere aggiunte al database,
con gli elementi separati da spazi. Mentre puoi cambiare le sorgenti
dati usando i metodi dell'interfaccia nsIRDFCompositeDataSource,
l'attributo datasources rappresenta solo la sorgente dati iniziali da
usare. Cambiare il valore dell'attributo non cambia le sorgenti dati
nel database.
Per esempio nell'esempio sotto, sono assegnate due sorgenti, così che esse siano associate all'elemento tree.
<tree datasources="rdf:bookmarks animals.rdf">
Questo farà concatenare una sorgente dati composita
all'albero che contiene le due sorgenti dati specificate. La prima
sorgente dati è rdf:bookmarks, che è la sorgente dati
usata da Mozilla per memorizzare i bookmarks. La seconda sorgente
è trattata come l'URI di un file XML/RDF, in questo caso il path
è relativo al file XUL.
In questo esempio, la sorgente dati bookmarks sarebbe usata solo
se il codice ha privilegi, il che significa che sta funzionando su
un'applicazione chrome. Codice senza privilegi non sarà in grado
di accedere alla sorgente dati bookmarks.
Un'ulteriore differenza tra codice con e senza privilegi
è che per il codice con privilegi, la sorgente dati
rdf:local-store è sempre inclusa nella lista delle sorgenti
dati, senza necessità di essere specificata. Questa sorgente
è normalmente usata per memorizzare dati riguardo a informazioni
come le dimensioni delle finestre, le barre degli strumenti, la
dimensione delle colonne dei Tree, e così via. Questo significa
che il database nell'esempio di sopra avrà tre sorgenti dati,
local store, bookmarks e animals.rdf. Codice senza privilegi che gira
da un sito remoto non include questa sorgente dati, perché
contiene informazioni sull'utente.
Una volta che un database è stato applicato a un
elemento, non è rimosso finché il documento non è
distrutto, che avviene quando l'utente va su un'altra pagina o chiude
la finestra. Perciò, rimuovendo un elemento e riaggiungendolo al
documento farà mantenere lo stesso database. Se un elemento, con
un attributo datasource, che non era prima nel documento, viene inserito, per questo elemento verrà creato un nuovo database.
In genere si usa un template dentro l'elemento con un database,
anche se non è sempre necessario. Il template deve essere o un
elemento template, che è figlio diretto dell'elemento con
l'attributo datasources, oppure ci si deve riferire ad esso tramite
l'attributo template. Nel secondo caso, il valore dell'attributo
dovrebbe essere il valore dell'attributo id in un elemento template da
qualche parte nel documento. Questo permetter di usare un singolo
template in diversi posti, anche se non accade spesso di doverlo fare.
Un costruttore di template sarà usato per costruire il
contenuto reale dal template. Userà il template per
costruire nuovi nodi DOM che saranno inseriti nel documento. Se i dati
in una datasource associata con un elemento cambiano, il
costruttore di template rigenererà i dati, aggiungendo,
rimuovendo o cambiando il contenuto se necessario. Il costruttore di
template gestisce questo registrandosi come observer della sorgente dati, così da poter essere avvisato nei cambiamenti.
La ricostruzione automatica del contenuto del template avviene
solo in due situazioni. La prima è quando la sorgente RDF
sottostante cambia. Quando l'RDF cambia, il costruttore di template
verrà avvisato del cambiamento. Il costruttore di template
ricostruirà le parti modificate, ma non quelle che non hanno
subito modifiche. Questa ricostruzione automatica avviene ogni volta
che si realizza un'operazione Assert, Unassert o Change. Ma non con un'operazione Move. Il costruttore di template ricostruirà anche automaticamente dopo un'operazione batch quando viene chiamato un metodo onEndUpdateBatch.
La seconda situazione che provocherà una ricostruzione
automatica del contenuto del template è quando viene cambiato un
attributo ref sull'elemeto esterno del database. Questo
farà sì che venga ricostruito l'intero contenuto. Il
valore deve essere cambiato a un valore differente. Impostare
l'attributo ref allo stesso valore non provocherà una
ricostruzione. Fai attenzione a questo, visto che che le versioni
precedenti di Mozilla effettuavano una ricostruzione anche quando
veniva reimpostato lo stesso valore.
Tutte le altre modifiche non provocano una ricostruzione.
Più precisamente, aggiungere o rimuovere sorgenti dati, cambiare
l'attributo datasources o modificare il contenuto del template non
provocano una ricostruzione automatica. Se sei in dubbio, fai una
ricostruzione manuale.
La ricostruzione manuale può essere fatta chiamando il metodo rebuild del costruttore di template. Tutti gli elementi XUL hanno una proprietà builder
che è un riferimento al costruttore di template associato
all'elemento. Se non c'è un costruttore di template associato
con un elemento, il valore di questa proprietà sarà null. Il seguente codice è usato per ricostruire i contenuti da un template, dove element è l'elemento con il database:
element.builder.rebuild();
Cambiare l'attributo ref ha lo stesso effetto che farebbe se il
codice sottostante venisse riscostruito manualmente, eccetto che per
ricostruire il contenuto viene usato il nuovo nodo radice.
Il costruttore di template creerà pigramente il contenuto. Questo significa che creerà realmente il contenuto solo quando è necessario visualizzarlo. Per esempio, il contenuto di un menu non è generato finché il menu non viene aperto. Allo stesso modo, i nodi figli di un tree non sono creati finché non viene aperto il nodo genitore. Bisogna fare attenzione a questo quando si esamina un albero DOM.