Écrit par Neil Deakin.
Traduit par René-Luc D'Hont (13/06/2005).
Page originale :
http://www.xulplanet.com/tutorials/mozsdk/rdfmods.php
Cette section décrit comment ajouter, modifier et supprimer des informations d'un datasource RDF.
Les datasources ont quatre méthodes qui peuvent être employées pour modifier un datasource. Il est possible de modifier un datasource en utilisant seulement ces quatre méthodes. Pas tous les datasources sont modifiables. Ces datasources renveront une exception quand vous essaierez d'appeler les méthodes. Par exemple, des fichiers RDF/XML chargés d'un emplacement distant ne peuvent pas être modifiés directement.
Pour ajouter un triplet RDF à un datasource, employez la méthode Assert
. Donné un sujet, un attribut et une cible,
cette méthode ajoutera ce lien au datasource. Si le lien existe déjà, on
l'ajoute encore. Cela signifie que vous pouvez souhaiter employer la
méthode GetTarget
et vérifier le lien d'abord.
Dans la terminologie de Mozilla, un triplet ou le lien RDF s'appelle une
affirmation (assertion), voici d'où vient le nom de la méthode.
Essentiellement, nous affirmons de l'information.
Disons que nous avons voulu ajouter un nom pour une personne. Voici un exemple de comment faire cela.
var subject = rdfService.GetResource("http://www.xulplanet.com/rdf/people/David");
var predicate = rdfService.GetResource("http://www.xulplanet.com/rdf/people/name");
var name = rdfService.GetLiteral("David");
datasource.Assert(subject, predicate, name, true);
D'abord, nous obtenons des objets ressource pour le sujet et le prédicat.
Nous voulons ajouter un nom, ainsi nous employons le prédicat 'name',
qualifié par le namespace. Le nom lui-même est un literal ainsi nous
obtenons un objet literal pour celui-ci. Chacun des trois sont recherché
par le service RDF. Nous pourrions avoir employé GetAnonymousResource
pour obtenir le sujet si nous
voulions nous assurer que l'URI de la ressource était unique.
En conclusion, Assert
s'utilise avec
quatre arguments, le sujet, le prédicat, la cible et la valeur de vérité.
Ce dernier argument peut être employé pour indiquer que quelque chose
est faux. C'est rarement utile, ainsi le quatrième argument devrait
presque toujours être vrai.
Le datasource peut ne pas accepter le changement. Par exemple, quand un datasource n'est pas inscriptible ou vous essayez d'ajouter des données inadmissibles, le datasource rejettera le changement. En code natif, vous pouvez détecter ceci car le datasource renverra un code de statut NS_RDF_ASSERTION_REJECTED. Ce code de statut n'est cependant pas une erreur.
Pour enlever un lien d'un datasource, il y a une méthode semblable
Unassert
. Cette méthode enlèvera un seul
lien à partir des arguments de sujet, de prédicat et de cible. Par
exemple, nous pourrions enlever le lien précédant que nous venons juste
d'ajouter avec ce qui suit:
datasource.Unassert(subject, predicate, name);
Il n'importe pas que le lien existe ou pas. La méthode Unassert
ne causera pas d'erreur si il
n'existe pas.
La méthode Change
peut être employée
pour changer la cible d'un lien en une autre valeur. Par exemple, ceci
pourrait être employé pour changer le nom d'une personne en une autre
valeur. C'est équivalent à enlever la vieille valeur en appelant
Unassert
et en ajoutant alors la nouvelle
valeur en appelant Assert
. Cependant, la
méthode Change
fait les deux en une
étape.
Voici un exemple:
var subject = rdfService.GetResource("http://www.xulplanet.com/rdf/people/George");
var predicate = rdfService.GetResource("http://www.xulplanet.com/rdf/people/name");
var oldName = rdfService.GetLiteral("George");
var newName = rdfService.GetLiteral("Georgina");
datasource.Change(subject, predicate, oldName, newName);
Dans ce cas-ci, nous changeons la valeur du prédicat 'name' de la ressource 'George' de la valeur 'George' en 'Georgina'. L'ancienne valeur sera enlevée du datasource et remplacée par la nouvelle valeur.
En conclusion, la méthode Move
peut
être employée pour changer la source de lien en une autre valeur. Ceci
serait employé pour changer la ressource qui a un nom donné. Par exemple,
nous pourrions décider que le nom de Georgina devrait être associé
réellement à une ressource 'Georgina'.
var oldSubject = rdfService.GetResource("http://www.xulplanet.com/rdf/people/George");
var newSubject = rdfService.GetResource("http://www.xulplanet.com/rdf/people/Georgina");
var predicate = rdfService.GetResource("http://www.xulplanet.com/rdf/people/name");
var name= rdfService.GetLiteral("Georgina");
datasource.Move(oldSubject, newSubject, predicate, name);
Comme avec la méthode Change
, la
vieille valeur est enlevée et la nouvelle valeur est ajoutée. La
méthode Move
est l'inverse parce qu'elle
change les sources au lieu des cibles.
Les deux méthodes Change
et Move
ne s'arrêtent pas si la vieille valeur
n'était pas présente. Pour les deux méthodes, elles veulent absolument
ajouter la nouvelle valeur. Pour cette raison, vous devriez vous
assurer que la vieille valeur existe d'abord si c'est un souci.
Disons que vous construisez un catalogue de photos. Vous pourriez avoir une variété d'informations à stocker pour chaque photo, telle que l'endroit, la date et une description de la photo. Pour chaque photo nous prendrons une ressource et un certain nombre de propriétés. Les propriétés ne doivent pas être les mêmes pour chaque photo, ainsi nous pouvons omettre des choses pour quelques photos et ajouter plus de détail pour d'autres. Une interface utilisateur montrant les données pourrait seulement montrer les champs qui sont présents.
D'abord, commençons en créant un nouveau datasource vide dans la mémoire (in-memory) :
var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
var photosDS = Components.classes["@mozilla.org/rdf/datasource;1?name=in-memory-datasource"].createInstance(Components.interfaces.nsIRDFDataSource);
Après, ajoutons quelques données pour chaque photo. Nous pourrions
employer GetAnonymousResource
pour produire
des UIRs de ressource anonyme pour chaque photo. Ou, nous pourrions
employer l'Uri du site Web où la photo est placée. Nous pourrions
employer l'un ou l'autre puisque RDF emploie l'Uri seulement comme
gardien de place (placeholder) et que nous ne téléchargeons pas le
contenu. Dans notre exemple, prenons l'exemple d'URI suivant
http://www.example.com/image/clown.jpeg.
La première photo a deux propriétés, une date et une description.
Nous devrons faire deux appels à la méthode Assert
pour ajouter cette information. Par
exemple:
var photoRes = rdfService.GetResource("http://www.example.com/image/clown.jpeg");
var dateProp = rdfService.GetResource("http://www.example.com/rdfns/date");
var descriptionProp = rdfService.GetResource("http://www.example.com/rdfns/description");
var photoDate = rdfService.GetLiteral("January 20, 2003");
var photoDescription = rdfService.GetLiteral(
"The clown at Simone's birthday party makes a funny face.");
photosDS.Assert(photoRes, dateProp, photoDate, true);
photosDS.Assert(photoRes, descriptionProp, photoDescription, true);
D'abord, nous obtenons les objets ressource et literal requis. Nous pourrions utilisé nsIRDFDate au lieu d'un simple literal pour la date, mais ce n'est pas le sujet de cet exemple.
Les deux lignes Assert
ajoutent
respectivement la date et la description. Si nous décidons plus tard
que nous voulons enlever une propriété, nous pouvons juste employer
la méthode Unassert
.
Ajoutons une deuxième photo, dans ce cas-ci une prise à la même date.
var photo2Res = rdfService.GetResource("http://www.example.com/image/cake.jpeg");
var photo2Description = rdfService.GetLiteral(
"Simone blows out the candles on her cake to officially mark that she is four.");
photosDS.Assert(photo2Res, dateProp, photoDate, true);
photosDS.Assert(photo2Res, descriptionProp, photo2Description, true);
Dans ce cas-ci, nous n'avons pas besoin d'obtenir autant d'objets
ressource et literal puisque nous avons déjà les objets d'avant. Il
n'y a aucun avantage à demander au service RDF ces objets à plusieurs
reprises puisque le service RDF renverra le même objet de toute façon.
La date est identique également ainsi nous pouvons juste réutiliser
l'objet. La méthode Assert
est aussi appelé
deux fois comme avant, mais en utilisant les données pour la deuxième
photo.
Puisque les deux dates sont identiques, nous pouvons interroger le
datasource pour toutes les photos à cette date en employant la méthode
GetSources
. Le code d'exemple ci-dessous
renverra une énumération avec deux items en lui, puisqu'il y a deux
photos enregistrées pour la date du '20 janvier 2003'. Notez que la
chaîne de caractère doit être exactement la même.
var sources = photosDS.GetSources(dateProp, photoDate, true);
while (sources.hasMoreElements()){
var photoRes = sources.getNext();
if (photoRes instanceof Components.interfaces.nsIRDFResource){
var description = photosDS.GetTarget(photoRes, descriptionProp, true);
if (description instanceof Components.interfaces.nsIRDFLiteral){
alert(description.Value);
}
}
}
Pour chaque item de l'énumération, nous réclamons la méthode
GetTarget
pour obtenir la description de
la photo. En donnant seulement la date de la photo, nous aurions trouvé
les deux descriptions. Ces genres de questions nous permettent de
naviguer à travers les informations du graphique RDF facilement.
Après, nous décidons de changer la description de la première photo.
Nous ne voulons pas créer une nouvelle ressource et encore ajouter les
données. Nous emploierons à la place juste la méthode Change pour
réaliser ceci. Cette méthode permettra à la valeur d'une propriété
d'être changée d'une valeur à l'autre. Nous ne pouvons pas simplement
appeler Assert
puisque cela ajoutera une
deuxième valeur, et n'enlèvera pas l'autre. Ceci pourrait être utile
dans certains cas cependant. Voici un exemple pour changer une valeur.
var photoNewDescription = rdfService.GetLiteral(
"Simone laughs when the clown at her birthday party makes a funny face.");
photosDS.Change(photoRes, descriptionProp, photoDescription, photoNewDescription);
Parfois plus tard, nous pourrons découvrir que les descriptions des
photos sont renversées. Nous pourrons employer la méthode Move
pour les changer de sorte que les
descriptions soient associées aux bonnes ressources. Il est également
possible d'enlever les vieilles valeurs et réinsérer les valeurs au
bon endroit.
photosDS.Move(photoRes, photo2Res, descriptionProp, photoNewDescription);
photosDS.Move(photo2Res, photoRes, descriptionProp, photo2Description);
La première ligne ajuste la première description de la première
ressource photo sur la deuxième ressource. La deuxième ligne ajuste la
deuxième description de la deuxième photo sur la première. C'est un
exemple plutôt insignifiant, mais certainement utile. Un exemple plus
efficace de l'utilisation de la méthode Move
est de déplacer une ressource d'un endroit à l'autre. Par exemple, si
des photos sont stockées dans un ensemble de groupes, on pourrait
déplacer une photo d'un groupe à l'autre en employant la méthode Move
pour changer le groupe au quel elle a été
associé. Par exemple :
var oldFolderRes = rdfService.GetResource("http://www.example.com/folder/unsorted");
var newFolderRes = rdfService.GetResource("http://www.example.com/folder/simonesbirthday");
var photoChildProp = rdfService.GetResource("http://www.example.com/rdfns/photo");
photosDS.Move(oldFolderRes, newFolderRes, photoChildProp, photoRes);
Cet exemple déplacera une photo d'un groupe à l'autre. Nous pourrions employer un code semblable pour déplacer un groupe à l'intérieur d'un autre groupe. Dans ce cas-ci nous employons une propriété pour indiquer qu'une photo est dans un groupe. Nous pourrions vouloir utiliser un conteneur RDF à la place. Ceci est décrit dans la prochaine section.
Les datasources RDF peuvent avoir un ou plusieurs observateurs attachés à eux. Les observateurs sont appelés toutes les fois que le datasource change. Il peut être utile d'observer les datasources fournis par Mozilla ou vos propres datasources. Par exemple, ceci pourrait aider à garder certain code séparé l'un de l'autre, si désiré. Le constructeur de template de XUL emploie des observateurs pour observer des changements de datasource RDF de sorte que le contenu du template puisse être reconstruit.
Vous pouvez ajouter un observateur à un datasource avec la méthode
de datasource AddObserver
. Vous pouvez
l'enlever en employant encore la méthode RemoveObserver
. Les datasources peuvent avoir
plusieurs observateurs et ils seront tous appellés quand le datasource
changera. Les observateurs devraient appliquer des méthodes de
l'interface nsIRDFObserver.
L'observateur reçoit un avis séparé pour chaque modification du
datasource. Les arguments fournis aux méthodes de l'observateur
indiquent ce qui a changé. L'observateur devrait appliquer une méthode
pour chacun des quatre types de changement qui peuvent se produire
dans le datasource, comme décrit ci-dessus. Ces changements sont
insertion, désinsertion, changement et mouvement. Le
nsIRDFObserver
a quatre méthodes correspondant à ces
quatre types, avec pour en tête 'on'. Par exemple, la méthode onAssert
sera appelée toutes les fois que
Assert
sera appelé sur le datasource.
Deux méthodes, onBeginUpdateBatch
et onEndUpdateBatch
additionnels sont
appelées quand les méthodes correspondantes du datasource sont
appelées. Bien qu'il n'y ait rien de spécial que ces méthodes doivent
faire, elles sont un indicateur au datasource et ses observateurs
qu'un grand nombre de changements vont être faits au datasource.
Puisqu'il pourrait être inefficace de manipuler chaque changement,
les méthodes en lots vous permettent de détecter quand un groupe de
changements commence et fini, et optimisent le code pour ce cas.
Par exemple, quand une opération en lots commence, le constructeur
de template de XUL ne reconstruit aucun contenu de template jusqu'à
ce que l'opération en lots finisse. Si les changements étaient faits
sans les traiter en lots, le constructeur reconstruirait sur chaque
changement qui serait inefficace.
Vous devez appliquer les six méthodes de l'interface nsIRDFObserver, bien que vous n'ayez pas besoin de prendre toutes les étapes parmis celles offertes. Voici un exemple :
var observer = {
onAssert : function(ds, source, predicate, target)
{
var dateProp = rdfService.GetResource("http://www.example.com/rdfns/date");
var photoDate = rdfService.GetLiteral("January 20, 2003");
if ((dateProp == predicate) && (photoDate == target)){
alert("That is Simone's birthday!");
}
},
onUnassert : function(ds, source, predicate, target){},
onChange : function(ds, source, predicate, oldTarget, newTarget){},
onMove : function(ds, oldSource, newSource, predicate, target){},
onBeginUpdateBatch : function(ds){},
onEndUpdateBatch : function(ds){}
};
photosDS.AddObserver(observer);
Dans cet exemple, nous voulons seulement écouter les liens étant
ajoutés au datasource, ainsi nous ne faisons rien avec les autres méthodes.
Nous devons toujours les déclarer ou des erreurs se produiront.
Les arguments de la méthode onAssert
indiquent les données qui ont été ajoutées. Ceci est employé pour
comparer la date à une date spécifique et pour afficher un message
d'alerte si la date est le '20 janvier 2003'. Notez que nous pouvons
comparer des ressources et des literals en utilisant l'opérateur ==
.
Le in-memory-datasource
implémente l'interface
nsIRDFPropagatableDataSource.
Elle a une simple propriété propagateChanges
qui peut être placé à vrai ou faux. Par défaut, la valeur de cette
propriété est vraie, mais si vous la changez en faux, la notification
de l'observateur sera mis hors service. Ceci neutralisera tous les avis
des observateurs ainsi ils ne seront plus appellés. En replaçant la valeur
sur true les avis seront réactivé. Les changements réalisés tandis que la
valeur est sur false n'atteindront pas les observateurs. Comme exemple,
le datasource de signets neutralise les avis en triant un dossier,
puisqu'une grande quantité de données est brassée pendant l'opération de
trie.
Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™
sont des marques de la fondation Mozilla.