File:  [mozdev] / books / www / docbook / ch10.xml
Revision 1.5: download - view: text, annotated - select for diffs - revision graph
Thu May 29 20:31:48 2003 UTC (16 years, 5 months ago) by brian
Branches: MAIN
CVS tags: HEAD
Last of the corrections in place.

Fixes bugs 3554, 3555 and 3556

    1: <chapter label="10" id="mozilla-CHP-10">
    2: 
    3: <title>RDF, RDF Tools, and the Content Model</title>
    4: 
    5: 
    6: <para><link linkend="mozilla-CHP-9">Chapter 9</link> introduced the Resource Description
    7: Framework (RDF) as the basis for building display data in the
    8: interface, where XUL templates take RDF-based data and transform it
    9: into regular widgets. But RDF is used in many other more subtle ways
   10: in Mozilla. In fact, it is the technology Mozilla uses for much of
   11: its own internal data handling and manipulation.
   12: </para>
   13: 
   14: <para>RDF is, as its name suggests, a framework for integrating many types
   15: of data that go into the browser, including bookmarks, mail messages,
   16: user profiles, IRC channels, new Mozilla applications, and your
   17: collection of sidebar tabs. All these items are sets of data that RDF
   18: represents and incorporates into the browser consistently. RDF is
   19: used prolifically in Mozilla, which is why this chapter is so dense.
   20: </para>
   21: 
   22: <para>This chapter introduces RDF, provides some detail about how Mozilla
   23: uses RDF for its own purposes, and describes the RDF tools that are
   24: available on the Mozilla platform. The chapter includes information
   25: on special JavaScript libraries that make RDF processing much easier,
   26: and on the use of RDF in manifests to represent JAR file contents and
   27: cross-platform installation archives to Mozilla.
   28: </para>
   29: 
   30: <para>Once you understand the concepts in this chapter, you can make better
   31: use of data and metadata in your own application development.
   32: </para>
   33: 
   34: 
   35: <sect1 role="" id="mozilla-CHP-10-SECT-1" label="10.1">
   36: <title>RDF Basics</title>
   37: 
   38: <para>RDF has two<indexterm id="IXT-10-908"><primary>RDF (Resource Description
   39: Framework)</primary><secondary>overview</secondary></indexterm>
   40: parts: the <emphasis>RDF Data Model</emphasis> and the <emphasis>RDF
   41: Syntax</emphasis> (or Grammar). The RDF Data Model is a graph with
   42: nodes and arcs, much like other data graphs. More specifically,
   43: it's a <filename>labeled-directed</filename> graph.
   44: All nodes and arcs have some type of label (i.e., an identifier) on
   45: them, and arcs point only in one direction.
   46: </para>
   47: 
   48: <para>The RDF Syntax determines how the RDF Data Model is represented,
   49: typically as a special kind of XML. Most XML specifications define
   50: data in a tree-like model, such as XUL and XBL. But the RDF Data
   51: Model cannot be represented in a true tree-like structure, so the
   52: RDF/XML syntax includes properties that allow you to represent the
   53: same data in more than one way: elements can appear in different
   54: orders but mean the same thing, the same data can be represented as a
   55: child element or as a parent attribute, and data have indirect
   56: meanings. The meaning is not inherent in the structure of the RDF/XML
   57: itself; only the relationships are inherent. Thus, an RDF processor
   58: must make sense of the represented RDF data. Fortunately, an
   59: excellent RDF processor is integrated into Mozilla.
   60: </para>
   61: 
   62: <sect2 role="" id="mozilla-CHP-10-SECT-1.1" label="10.1.1">
   63: <title>RDF Data Model</title>
   64: 
   65: <para>Three <indexterm id="IXT-10-909"><primary>RDF (Resource Description
   66: Framework)</primary><secondary>data
   67: model</secondary></indexterm><indexterm id="IXT-10-910"><primary>data model
   68: (RDF)</primary></indexterm>different types of RDF objects are the
   69: basis for all other RDF concepts: <emphasis>resources</emphasis>,
   70: <emphasis>properties</emphasis>, and <emphasis>statements</emphasis>.
   71: Resources
   72: <indexterm id="IXT-10-911"><primary>resources</primary><secondary>RDF</secondary></indexterm>are
   73: any type of data described by RDF. Just as an English sentence is
   74: comprised of subjects and objects, the resources described in RDF are
   75: typically subjects and objects of RDF statements. Consider this
   76: example:
   77: </para>
   78: 
   79: <blockquote>
   80: <para>Eric wrote a book.</para>
   81: </blockquote>
   82: 
   83: <para><emphasis>Eric</emphasis> is the subject of this statement, and would
   84: probably be an RDF resource in an RDF statement. <filename>A
   85: book</filename>, the object, might also be a resource because it
   86: represents something about which we might want to say more in
   87: RDF -- for example, the book is a computer book or the book sells
   88: for twenty dollars. A property
   89: <indexterm id="IXT-10-912"><primary>properties</primary><secondary>RDF</secondary></indexterm>is
   90: a characteristic of a resource and might have a relationship to other
   91: resources. In the example, the book was written by Eric. In the
   92: context of RDF, <filename>wrote</filename> is a property of the
   93: <filename>Eric</filename> resource. An RDF statement is a resource, a
   94: property, and another resource grouped together. Our example, made
   95: into an RDF statement, might look like this:
   96: </para>
   97: 
   98: <blockquote>
   99: <para>(Eric) wrote (a book)</para>
  100: </blockquote>
  101: 
  102: <para>Joining RDF statements makes an entire RDF graph.</para>
  103: 
  104: 
  105: 
  106: <tip id="ch10-4-fm2xml" role="ora">
  107: <para>We are describing the RDF data model here, not the RDF syntax. The
  108: RDF syntax uses XML to describe RDF statements and the relationship
  109: of resources.
  110: </para>
  111: </tip>
  112: 
  113: <para>As mentioned in the introduction, the RDF content model is a
  114: <filename>labeled-directed
  115: </filename><indexterm id="IXT-10-913"><primary>labeled-directed graphs
  116: (RDF)</primary></indexterm>graph, which means that all relationships
  117: expressed in the graph are unidirectional, as displayed in <link linkend="mozilla-CHP-10-FIG-1">Figure 10-1</link>. 
  118: </para>
  119: 
  120: <figure id="mozilla-CHP-10-FIG-1" label="10-1">
  121: <title>Simple labeled-directed graph</title>
  122: <graphic fileref="figs/moz_1001.png"/></figure>
  123: 
  124: <para>A resource can contain either a URI or a literal. The root resource
  125: might have a <indexterm id="IXT-10-914"><primary>URIs (Universal Resource
  126: Identifiers)</primary><secondary>RDF</secondary></indexterm>URI, for
  127: example, from which all other resources in the graph descend. The RDF
  128: processor continues from the root resource along its properties to
  129: other resources in the graph until it runs out of properties to
  130: traverse. RDF processing terminates at
  131: a<indexterm id="IXT-10-915"><primary>literals</primary><secondary>RDF</secondary></indexterm>
  132: literal, which is just what it sounds like: something that stands
  133: only for itself, generally represented by a string (e.g.,
  134: "book," if there were no more
  135: information about the book in the graph). A literal resource contains
  136: only non-RDF data. A literal is a terminal point in the RDF graph.
  137: </para>
  138: 
  139: <para>For a resource to be labeled, it must be addressed through a
  140: universal resource identifier (URI). This address must be a unique
  141: string that designates what the resource is. In practice, most
  142: resources don't have identifiers because they are
  143: not nodes on the RDF graph that are meant to be accessed through a
  144: URI. <link linkend="mozilla-CHP-10-FIG-2">Figure 10-2</link> is a modified version of <link linkend="mozilla-CHP-10-FIG-1">Figure 10-1</link> that shows <filename>Eric</filename> as a
  145: resource identifier and <filename>book</filename> as a literal.
  146: </para>
  147: 
  148: <figure id="mozilla-CHP-10-FIG-2" label="10-2">
  149: <title>Resource to literal relationship</title>
  150: <graphic fileref="figs/moz_1002.png"/></figure>
  151: 
  152: <para>Resources can have any number of properties, which themselves differ.
  153: In <link linkend="mozilla-CHP-10-FIG-2">Figure 10-2</link>, <filename>wrote</filename> is a
  154: property of <filename>Eric</filename>. However, resources can also
  155: have multiple properties, as shown in <link linkend="mozilla-CHP-10-FIG-3">Figure 10-3</link>.
  156: </para>
  157: 
  158: <figure id="mozilla-CHP-10-FIG-3" label="10-3">
  159: <title>RDF Graph with five nodes</title>
  160: <graphic fileref="figs/moz_1003.png"/></figure>
  161: 
  162: <para>The RDF graph in <link linkend="mozilla-CHP-10-FIG-3">Figure 10-3</link> has five nodes, two
  163: resources, and three literals. If this graph were represented in XML,
  164: it would probably have three different XML namespaces inside of it:
  165: RDF/XML, a <filename>book</filename> XML specification, and a
  166: <filename>computer</filename> XML specification. In English, the
  167: graph in <link linkend="mozilla-CHP-10-FIG-3">Figure 10-3</link> might be expressed as follows:
  168: </para>
  169: 
  170: <blockquote>
  171: <para>Eric wrote a book of unknown information. Eric's
  172: computer is 700 MHz and has an Athlon CPU.
  173: </para>
  174: </blockquote>
  175: 
  176: <para>Note that if Eric wrote a poem and a book, it would be possible to
  177: have two <filename>wrote</filename> properties for the same resource.
  178: Using the same property to point to separate resources is confusing,
  179: however. Instead, RDF containers (see the section <link linkend="mozilla-CHP-10-SECT-1.2.2">Section 10.1.2.2</link>, later in this chapter) are
  180: the best way to organize data that would otherwise need a single
  181: property to branch in this way.
  182: </para>
  183: 
  184: <sect3 role="" id="mozilla-CHP-10-SECT-1.1.1" label="10.1.1.1">
  185: <title>RDF URIs relating to namespaces</title>
  186: 
  187: <para>The <indexterm id="IXT-10-916"><primary>RDF (Resource Description
  188: Framework)</primary><secondary>data
  189: model</secondary><tertiary>URIs</tertiary></indexterm><indexterm id="IXT-10-917"><primary>data
  190: model
  191: (RDF)</primary><secondary>URIs</secondary></indexterm><indexterm id="IXT-10-918"><primary>URIs
  192: (Universal Resource
  193: Identifiers)</primary><secondary>RDF</secondary><tertiary>namespaces</tertiary></indexterm><indexterm id="IXT-10-919"><primary>namespaces</primary><secondary>RDF,
  194: URIs and</secondary></indexterm>URIs used in RDF can be part of the
  195: element namespace. (See <link linkend="mozilla-CHP-2-SECT-2.3">Section 2.2.3</link> and in <link linkend="mozilla-CHP-7-SECT-1.3">Section 7.1.3</link> for more information about XML namespaces.)
  196: This use is especially true for properties. Some namespaces can be
  197: created from previous examples:
  198: </para>
  199: 
  200: <programlisting>xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  201: xmlns:book="http://www.oreilly.com/rdf#"
  202: xmlns:comp="my.computer.hardware#"</programlisting>
  203: 
  204: <para>When you use namespaces, the graph looks much different, as shown in
  205: <link linkend="mozilla-CHP-10-FIG-4">Figure 10-4</link>.
  206: </para>
  207: 
  208: <figure id="mozilla-CHP-10-FIG-4" label="10-4">
  209: <title>Namespaces applied to Figure 10-3</title>
  210: <graphic fileref="figs/moz_1004.png"/></figure>
  211: 
  212: 
  213: 
  214: <tip id="ch10-6-fm2xml" role="ora">
  215: <para>The resource identifier is often displayed in a URL format too, but
  216: it shouldn't use the same namespace URL as the
  217: RDF/XML file. The URL typically tries to describe a unique object,
  218: such as <systemitem role="url">http://my.jar-of-flies.com</systemitem>.
  219: </para>
  220: </tip>
  221: 
  222: </sect3>
  223: 
  224: <sect3 role="" id="mozilla-CHP-10-SECT-1.1.2" label="10.1.1.2">
  225: <title>RDF triples: subject, predicate, and object</title>
  226: 
  227: <para>A triple <indexterm id="IXT-10-920"><primary>statements, RDF,
  228: triples</primary></indexterm><indexterm id="IXT-10-921"><primary>triples</primary><secondary>RDF
  229: statements</secondary></indexterm><indexterm id="IXT-10-922"><primary>RDF (Resource
  230: Description Framework)</primary><secondary>statements,
  231: triples</secondary></indexterm>is a type of RDF statement. While an
  232: RDF statement can be a loose collection of resources, properties, and
  233: literals, a triple typically defines a tighter relationship between
  234: such elements.
  235: </para>
  236: 
  237: <para>The first part of a triple is the <filename>subject</filename>. This
  238: part is the resource described by the triple. The second part of the
  239: triple is the <filename>predicate</filename>. This part is a
  240: subject's property, a thing that joins it with
  241: something else. The third part is the <filename>object</filename>,
  242: which is either a resource or a literal.
  243: </para>
  244: 
  245: <para>RDF triples are significant because their stricter semantics
  246: guarantee the relationship between parts. A triple is a more formal
  247: version of the RDF statement, which is used more broadly. In <link linkend="mozilla-CHP-10-FIG-4">Figure 10-4</link>, all statements are formally subject
  248: &gt; predicate &gt; object, so those
  249: statements are triples.
  250: </para>
  251: 
  252: </sect3>
  253: 
  254: <sect3 role="" id="mozilla-CHP-10-SECT-1.1.3" label="10.1.1.3">
  255: <title>RDF data model terminology</title>
  256: 
  257: <para>When <indexterm id="IXT-10-923"><primary>RDF (Resource Description
  258: Framework)</primary><secondary>data
  259: model</secondary><tertiary>terminology</tertiary></indexterm><indexterm id="IXT-10-924"><primary>data
  260: model
  261: (RDF)</primary><secondary>terminology</secondary></indexterm>reading
  262: RDF specifications, documentation, examples, and other related
  263: material on the Internet, you can encounter a dizzying array of terms
  264: that mean the same thing. <link linkend="mozilla-CHP-10-TABLE-1">Table 10-1</link> should help
  265: clarify these different terms. The italicized versions of the
  266: synonyms all do not technically mean the same thing, but are loose
  267: synonyms whose meanings depend on the context in which they are used.
  268: </para>
  269: 
  270: <table id="mozilla-CHP-10-TABLE-1" label="10-1">
  271: 
  272: <title>Synonyms in RDF </title>
  273: <tgroup cols="2">
  274: <colspec colnum="1" colname="col1"/>
  275: <colspec colnum="2" colname="col2"/>
  276: <thead>
  277: <row>
  278: <entry>
  279: <para>Common term</para>
  280: </entry>
  281: <entry>
  282: <para>Synonyms</para>
  283: </entry>
  284: </row>
  285: </thead>
  286: <tbody>
  287: <row>
  288: <entry>
  289: <para>Resource</para>
  290: </entry>
  291: <entry>
  292: <para>Subject, object</para>
  293: </entry>
  294: </row>
  295: <row>
  296: <entry>
  297: <para>Resource identifier</para>
  298: </entry>
  299: <entry>
  300: <para>Name, (resource) URI, ID, identifier, URL, label</para>
  301: </entry>
  302: </row>
  303: <row>
  304: <entry>
  305: <para>Properties</para>
  306: </entry>
  307: <entry>
  308: <para>Attributes</para>
  309: </entry>
  310: </row>
  311: <row>
  312: <entry>
  313: <para>Statement</para>
  314: </entry>
  315: <entry>
  316: <para>Triple, tuple, binding, assertion</para>
  317: </entry>
  318: </row>
  319: <row>
  320: <entry>
  321: <para>Subject</para>
  322: </entry>
  323: <entry>
  324: <para>Source, resource, node, root</para>
  325: </entry>
  326: </row>
  327: <row>
  328: <entry>
  329: <para>Predicate</para>
  330: </entry>
  331: <entry>
  332: <para>Arc, (statement) URI, property, atom</para>
  333: </entry>
  334: </row>
  335: <row>
  336: <entry>
  337: <para>Object</para>
  338: </entry>
  339: <entry>
  340: <para>Value, resource, node, literal</para>
  341: </entry>
  342: </row>
  343: </tbody>
  344: </tgroup>
  345: </table>
  346: 
  347: </sect3>
  348: </sect2>
  349: <sect2 role="" id="mozilla-CHP-10-SECT-1.2" label="10.1.2">
  350: <title>RDF Syntax</title>
  351: 
  352: <para>Mozilla<indexterm id="IXT-10-925"><primary>RDF (Resource Description
  353: Framework)</primary><secondary>syntax</secondary><tertiary>overview</tertiary></indexterm><indexterm id="IXT-10-926"><primary>syntax,
  354: RDF</primary><secondary>overview</secondary></indexterm> uses XML to
  355: represent RDF data. In 1999, the W3C defined the RDF/XML
  356: specification syntax to make it the most common way RDF is used. The
  357: RDF/XML format is sometimes called the RDF serialization syntax
  358: because it allows RDF models to be sent easily from one computer
  359: application to another in a common XML format.
  360: </para>
  361: 
  362: <para>When an application reads an RDF file, the Mozilla RDF processor
  363: builds a graphical interpretation in-memory. In this section, you
  364: learn how to build an RDF file from scratch and see what the graph
  365: looks like after running through Mozilla's RDF
  366: processor.
  367: </para>
  368: 
  369: 
  370: 
  371: <tip id="ch10-8-fm2xml" role="ora">
  372: <para><literal>RDF:RDF</literal> is a common namespace representation of
  373: RDF/XML data and is the one most frequently used in Mozilla files.
  374: However, it can be hard to read, so this chapter uses
  375: <literal>rdf:RDF</literal>. The W3C also used
  376: <literal>rdf:RDF</literal> in the RDF recommendation document.
  377: </para>
  378: </tip>
  379: 
  380: <sect3 role="" id="mozilla-CHP-10-SECT-1.2.1" label="10.1.2.1">
  381: <title>Examining a simple RDF file</title>
  382: 
  383: <para>We begin<indexterm id="IXT-10-927"><primary>RDF (Resource Description
  384: Framework)</primary><secondary>syntax</secondary><tertiary>files</tertiary></indexterm><indexterm id="IXT-10-928"><primary>syntax,
  385: RDF</primary><secondary>files</secondary></indexterm><indexterm id="IXT-10-929"><primary>files</primary><secondary>RDF</secondary><tertiary>syntax</tertiary></indexterm>
  386: with an example of an RDF file whose basic layout and simple syntax
  387: can be a model for the more advanced data introduced later. The RDF
  388: file shown in <link linkend="mozilla-CHP-10-EX-1">Example 10-1</link> is a list of three types
  389: of "flies," with the context of
  390: those "flies" inside a
  391: "jar." <link linkend="mozilla-CHP-10-EX-1">Example 10-1</link>
  392: also contains a namespace that defines these types of flies and shows
  393: the <literal>rdf</literal> and <literal>fly</literal> XML
  394: intertwined.
  395: </para>
  396: 
  397: <example id="mozilla-CHP-10-EX-1" label="10-1">
  398: <title>Simple RDF file with "fly" namespace </title>
  399: <programlisting>  &lt;?xml version="1.0"?&gt;
  400:   &lt;rdf:RDF
  401:      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  402:      xmlns:fly="http://xfly.mozdev.org/fly-rdf#"&gt;
  403:     &lt;rdf:Description about="urn:root"&gt;
  404:       &lt;fly:types&gt;
  405:         &lt;rdf:Bag&gt;
  406:           &lt;rdf:li&gt;
  407:             &lt;rdf:Description fly:name="Horse"/&gt;
  408:           &lt;/rdf:li&gt;
  409:           &lt;rdf:li&gt;
  410:             &lt;rdf:Description fly:name="House"/&gt;
  411:           &lt;/rdf:li&gt;
  412:           &lt;rdf:li&gt;
  413:             &lt;rdf:Description fly:name="Fruit"/&gt;
  414:           &lt;/rdf:li&gt;
  415:         &lt;/rdf:Bag&gt;
  416:       &lt;/fly:types&gt;
  417:     &lt;/rdf:Description&gt;
  418:   &lt;/rdf:RDF&gt;</programlisting>
  419: </example>
  420: 
  421: <para><literal>&lt;rdf:Description&gt;</literal><indexterm id="IXT-10-930"><primary>rdf\:Description
  422: element</primary></indexterm> is the tag used to outline a resource.
  423: <link linkend="mozilla-CHP-10-EX-1">Example 10-1</link> shows how the <literal>about</literal>
  424: attribute references the resource identifier and makes this resource
  425: unique in the document. Two resources cannot have the same
  426: <literal>about</literal> value in a document, just as tags cannot
  427: share an <literal>id</literal> in an XML document. Both attributes
  428: guarantee the unique nature of each element and relationship.
  429: </para>
  430: 
  431: <programlisting>  &lt;rdf:Description about="<userinput>http://my.jar-of-flies.com</userinput>"&gt;
  432:     &lt;fly:types&gt;
  433:       &lt;rdf:Bag&gt;</programlisting>
  434: 
  435: <para><literal>http://my.jar-of-flies.com</literal>, is the subject shown
  436: in the previous code snippet. <filename>My jar of flies</filename> is
  437: a resource definition and defines only what
  438: <filename>flies</filename> are inside of the statement. The
  439: predicate, which addresses a property in the resource, is defined by
  440: the tag <literal>&lt;types&gt;</literal> (of the
  441: <literal>http://xfly.mozdev.org/fly-rdf#</literal> namespace).
  442: </para>
  443: 
  444: <para>The final part of the statement, the object, is the actual data of
  445: the predicate and a container of type bag. The container is an RDF
  446: resource that "holds," or points
  447: to, a collection of other resources. In the next section, container
  448: types are discussed in depth. <link linkend="mozilla-CHP-10-FIG-5">Figure 10-5</link>
  449: illustrates how the triple originates from the root subject and
  450: includes the container object.
  451: </para>
  452: 
  453: <figure id="mozilla-CHP-10-FIG-5" label="10-5">
  454: <title>The first statement of the graph, with labeled parts</title>
  455: <graphic fileref="figs/moz_1005.png"/></figure>
  456: 
  457: <para>In this case, an RDF statement is extracted from the example, but no
  458: useful data is reached. Little can be done with an empty RDF
  459: container, and two more steps are needed to reach literals that
  460: contain names of the flies.
  461: </para>
  462: 
  463: </sect3>
  464: 
  465: <sect3 role="" id="mozilla-CHP-10-SECT-1.2.2" label="10.1.2.2">
  466: <title>RDF containers</title>
  467: 
  468: <para>Containers <indexterm id="IXT-10-931"><primary>RDF (Resource Description
  469: Framework)</primary><secondary>containers</secondary></indexterm><indexterm id="IXT-10-932"><primary>containers</primary><secondary>RDF</secondary></indexterm>are
  470: a list of resources or literals. They are a form of RDF
  471: <indexterm id="IXT-10-933"><primary>resources</primary><secondary>RDF</secondary><tertiary>containers</tertiary></indexterm>resource.
  472: There are three different container types: <literal>bag</literal>,
  473: <literal>sequence</literal>, and <literal>alternative</literal>.
  474: <literal>Bag</literal> is an unordered list of items, whereas
  475: <literal>sequence</literal> is an ordered list of items. They both
  476: allow duplicate values. <literal>Alternative</literal> is a list of
  477: values that could replace a particular property in a resource.
  478: <literal>Sequence</literal> is the most popular container for use in
  479: Mozilla applications because it frequently uses ordered lists of
  480: data. A container's graphical definition is an
  481: entire separate statement about its type and the items it contains.
  482: In <link linkend="mozilla-CHP-10-FIG-6">Figure 10-6</link>, you can see the type of the
  483: container defined in the RDF statement with the property
  484: <literal>rdf:type</literal>. The remaining properties are the
  485: container's items.
  486: </para>
  487: 
  488: <figure id="mozilla-CHP-10-FIG-6" label="10-6">
  489: <title>The second statement of the graph, with labeled parts</title>
  490: <graphic fileref="figs/moz_1006.png"/></figure>
  491: 
  492: <para>Once the container is defined, you can examine its collection of
  493: elements. At this point in the RDF code, direct comparisons can again
  494: be made from the code to the graph:
  495: </para>
  496: 
  497: <programlisting>  &lt;rdf:Bag&gt;
  498:     &lt;rdf:li&gt;
  499:       &lt;rdf:Description ...</programlisting>
  500: 
  501: <para>Here, the
  502: <literal>&lt;rdf:li&gt;</literal><indexterm id="IXT-10-934"><primary>rdf\:li
  503: tag</primary></indexterm> tag is similar to the
  504: <literal>&lt;li&gt;</literal> tag in HTML, which stands for
  505: "list item." Moving from code to
  506: graph, the new representation is shown in <link linkend="mozilla-CHP-10-FIG-6">Figure 10-6</link>. 
  507: </para>
  508: 
  509: <para>In <link linkend="mozilla-CHP-10-FIG-6">Figure 10-6</link>, the subject is the instance of the
  510: container. This statement does not begin from
  511: <literal>rdf:Bag</literal> because that resource is only a type
  512: definition. The actual items in the container originate from the
  513: instance created in memory by any RDF processor, including
  514: Mozilla's.
  515: </para>
  516: 
  517: 
  518: 
  519: <tip id="ch10-10-fm2xml" role="ora">
  520: <para>Mozilla's RDF processor fills in the
  521: <literal>rdf:*(1)</literal> of the resource identifier in <link linkend="mozilla-CHP-10-FIG-6">Figure 10-6</link> with a hashed value. The same is true for the
  522: container's resource identifier. The actual values
  523: come out as something like <literal>rdf:#$0mhkm1</literal>, though
  524: the values change each time the RDF document is loaded.
  525: </para>
  526: </tip>
  527: 
  528: <para>Objects inside of the container
  529: have<indexterm id="IXT-10-935"><primary>properties</primary><secondary>RDF</secondary><tertiary>containers</tertiary></indexterm>
  530: properties identified automatically as <literal>rdf:_1</literal>,
  531: <literal>rdf:_2</literal>, etc., as defined by the RDF model
  532: specification. However, RDF applications such as Mozilla may use
  533: different identifiers to differentiate list objects.
  534: </para>
  535: 
  536: </sect3>
  537: 
  538: <sect3 role="" id="mozilla-CHP-10-SECT-1.2.3" label="10.1.2.3">
  539: <title>Literals</title>
  540: 
  541: <para>The final <indexterm id="IXT-10-936"><primary>RDF (Resource Description
  542: Framework)</primary><secondary>literals</secondary></indexterm>statement
  543: in <link linkend="mozilla-CHP-10-EX-1">Example 10-1</link> allows the predicate to reach the
  544: text data, the literal "horse"
  545: shown in <link linkend="mozilla-CHP-10-FIG-7">Figure 10-7</link>. Note that the
  546: <literal>about</literal> reference on the
  547: <literal>Description</literal> is fictitious RDF, but it demonstrates
  548: the difference between a resource and a literal.
  549: </para>
  550: 
  551: <programlisting>  &lt;rdf:Description <replaceable>about="rdf:*(1)"</replaceable> fly:name="Horse"/&gt;</programlisting>
  552: 
  553: <figure id="mozilla-CHP-10-FIG-7" label="10-7">
  554: <title>The third statement of the graph, with labeled parts</title>
  555: <graphic fileref="figs/moz_1007.png"/></figure>
  556: 
  557: <para>The previous RDF <indexterm id="IXT-10-937"><primary>RDF (Resource Description
  558: Framework)</primary><secondary>syntax</secondary><tertiary>shorthand</tertiary></indexterm><indexterm id="IXT-10-938"><primary>syntax,
  559: RDF</primary><secondary>shorthand</secondary></indexterm>code for the
  560: literal is syntactic shorthand. Using this type of shortcut can make
  561: RDF much easier to read. The previous code snippet is the same as the
  562: longer and more cumbersome one shown here:
  563: </para>
  564: 
  565: <programlisting>  &lt;rdf:Description <replaceable>about="rdf:*(1)"</replaceable>&gt;
  566:     &lt;fly:name&gt;Horse&lt;/fly:name&gt;
  567:   &lt;/rdf:Description&gt;</programlisting>
  568: 
  569: <para>The shorthand version of this statement can be useful when you have a
  570: lot of data or when you want to use one syntax to show all
  571: relationships in the graph.
  572: </para>
  573: 
  574: </sect3>
  575: 
  576: <sect3 role="" id="mozilla-CHP-10-SECT-1.2.4" label="10.1.2.4">
  577: <title>The RDF syntax and RDF graphs</title>
  578: 
  579: <para><link linkend="mozilla-CHP-10-FIG-8">Figure 10-8</link> shows the entire RDF graph for the RDF
  580: file in <link linkend="mozilla-CHP-10-EX-1">Example 10-1</link>. This graph was compiled by
  581: combining the concepts you've seen in Figures 10-5
  582: through 10-7.
  583: </para>
  584: 
  585: <para>As you can see, the statements fit together quite nicely. Four
  586: resources originate from the container, and one is the container type
  587: definition. The other two properties are numbered according to their
  588: order in the RDF file.
  589: </para>
  590: 
  591: <figure id="mozilla-CHP-10-FIG-8" label="10-8">
  592: <title>The full graph</title>
  593: <graphic fileref="figs/moz_1008.png"/></figure>
  594: 
  595: </sect3>
  596: </sect2>
  597: <sect2 role="" id="mozilla-CHP-10-SECT-1.3" label="10.1.3">
  598: <title>Building an RDF File from Scratch</title>
  599: 
  600: <para>Now that <indexterm id="IXT-10-939"><primary>RDF (Resource Description
  601: Framework)</primary><secondary>files</secondary><tertiary>creating</tertiary></indexterm><indexterm id="IXT-10-940"><primary>files</primary><secondary>RDF</secondary><tertiary>creating</tertiary></indexterm>you
  602: understand the basic principles of a simple RDF file, this section
  603: steps through the creation of an RDF file from information found in
  604: regular text:
  605: </para>
  606: 
  607: <blockquote>
  608: <para>There is a jar with the name urn:root. Inside of it there are two
  609: types of flies listed as House and Horse.
  610: </para>
  611: 
  612: <para>There are three Horse flies. The Face Fly, coded in green, is
  613: officially identified as "musca
  614: autumnalis". The Stable Fly, coded in black, has the
  615: identification
  616: "stomoxys_calcitrans." The
  617: red-coded Horn Fly, located in Kansas, is identified as
  618: "haematobia_irritans."
  619: </para>
  620: 
  621: <para>There are also three house flies.
  622: "musca_domestica," coded in brown,
  623: has the name "Common House Fly." A
  624: gray fly named "Carrion Fly" has
  625: the ID "sarcophagid" and is found
  626: globally. Finally, The "Office
  627: Fly," coded with white, is prevalent in the Bay
  628: Area.
  629: </para>
  630: </blockquote>
  631: 
  632: <para>You can use the techniques described here to model the data you want
  633: in your application: spreadsheet-like rosters of people, family
  634: trees, or catalogs of books or other items.
  635: </para>
  636: 
  637: <sect3 role="" id="mozilla-CHP-10-SECT-1.3.1" label="10.1.3.1">
  638: <title>Identify namespaces</title>
  639: 
  640: <para>The new
  641: <indexterm id="IXT-10-941"><primary>namespaces</primary><secondary>identifying,
  642: creating RDF files</secondary></indexterm><indexterm id="IXT-10-942"><primary>RDF
  643: (Resource Description
  644: Framework)</primary><secondary>files</secondary><tertiary>identifying
  645: namespaces</tertiary></indexterm><indexterm id="IXT-10-943"><primary>files</primary><secondary>RDF</secondary><tertiary>identifying
  646: namespaces</tertiary></indexterm>RDF file will have three namespaces
  647: including the RDF namespace. The result is two different data types
  648: that are connected in an RDF graph. For the sake of the example, one
  649: namespace is not in the standard URL format. Here is how the RDF file
  650: namespaces are set up:
  651: </para>
  652: 
  653: <programlisting>&lt;?xml version="1.0"?&gt;
  654: &lt;rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  655:          xmlns:fly="http://xfly.mozdev.org/fly-rdf#"
  656:          xmlns:location="fly-location#"&gt;
  657: &lt;/rdf:RDF&gt;</programlisting>
  658: 
  659: </sect3>
  660: 
  661: <sect3 role="" id="mozilla-CHP-10-SECT-1.3.2" label="10.1.3.2">
  662: <title>Root resource</title>
  663: 
  664: <para>This file's
  665: <indexterm id="IXT-10-944"><primary>resources</primary><secondary>RDF</secondary><tertiary>creating
  666: files</tertiary></indexterm><indexterm id="IXT-10-945"><primary>root resources, RDF
  667: files</primary></indexterm><indexterm id="IXT-10-946"><primary>RDF (Resource
  668: Description
  669: Framework)</primary><secondary>files</secondary><tertiary>root
  670: resources</tertiary></indexterm><indexterm id="IXT-10-947"><primary>files</primary><secondary>RDF</secondary><tertiary>root
  671: resources</tertiary></indexterm>root resource is an
  672: <literal>urn:root</literal>, which is the conventional name for root
  673: nodes in Mozilla's RDF files. When rendering RDF
  674: files, defining a root node for processing the document can be
  675: useful -- especially when building templates. This root node can
  676: be entered as the first item in the file:
  677: </para>
  678: 
  679: <programlisting>&lt;?xml version="1.0"?&gt;
  680: &lt;rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  681:          xmlns:fly="http://xfly.mozdev.org/fly-rdf#"
  682:          xmlns:location="fly-location#"&gt;
  683:   &lt;rdf:Description about="urn:root"&gt;
  684:   &lt;/rdf:Description&gt;
  685: &lt;/rdf:RDF&gt;</programlisting>
  686: 
  687: </sect3>
  688: 
  689: <sect3 role="" id="mozilla-CHP-10-SECT-1.3.3" label="10.1.3.3">
  690: <title>Root sequence</title>
  691: 
  692: <para>Next, a <indexterm id="IXT-10-948"><primary>sequences,
  693: RDF</primary><secondary>creating
  694: files</secondary></indexterm><indexterm id="IXT-10-949"><primary>root sequences, RDF
  695: files</primary></indexterm><indexterm id="IXT-10-950"><primary>RDF (Resource
  696: Description
  697: Framework)</primary><secondary>files</secondary><tertiary>root
  698: sequesces</tertiary></indexterm><indexterm id="IXT-10-951"><primary>files</primary><secondary>RDF</secondary><tertiary>root
  699: sequesces</tertiary></indexterm>generic tag needs to be used to
  700: specify a sequence of "fly" data.
  701: As in <link linkend="mozilla-CHP-10-EX-2">Example 10-2</link>,
  702: <literal>&lt;fly:list&gt;</literal> is used as a list of fly types.
  703: This tag is a generic name because of the way XUL templates process
  704: lists of RDF data. If a list of data has sublists, as in the
  705: following examples, then they must use the same tag name to recurse
  706: correctly for the data they contain.
  707: </para>
  708: 
  709: <para><link linkend="mozilla-CHP-10-EX-2">Example 10-2</link> represents all the information given in
  710: the first paragraph of the text example: "There is a
  711: jar set up with the name <filename>urn:root</filename>. Inside of it
  712: there are two types of flies, listed as House and
  713: Horse."
  714: </para>
  715: 
  716: <example id="mozilla-CHP-10-EX-2" label="10-2">
  717: <title>RDF root sequence </title>
  718: <programlisting>&lt;?xml version="1.0"?&gt;
  719: &lt;rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  720:          xmlns:fly="http://xfly.mozdev.org/fly-rdf#"
  721:          xmlns:location="fly-location#"&gt;
  722:   &lt;rdf:Description about="urn:root"&gt;
  723:     &lt;fly:list&gt;
  724:       &lt;rdf:Seq&gt;
  725:         &lt;rdf:li&gt;
  726:           &lt;rdf:Description ID="House" fly:label="House"/&gt;
  727:         &lt;/rdf:li&gt;
  728:         &lt;rdf:li&gt;
  729:           &lt;rdf:Description ID="Horse" fly:label="Horse"/&gt;
  730:         &lt;/rdf:li&gt;
  731:       &lt;/rdf:Seq&gt;
  732:     &lt;/fly:list&gt;
  733:   &lt;/rdf:Description&gt;
  734: &lt;/rdf:RDF&gt;</programlisting>
  735: </example>
  736: 
  737: <para>An RDF sequence resides with its list of resources inside
  738: <literal>&lt;fly:list&gt;</literal>. Here, shorthand RDF specifies a
  739: label with the <literal>fly:label</literal> attribute. The
  740: <literal>ID</literal> attribute within this sequence is actually a
  741: pointer to the main definition of the resource described by an
  742: <literal>about</literal> attribute of the same value. The
  743: <literal>about</literal> attribute includes a <literal>#</literal> in
  744: its identifier, much like HTML anchors use <literal>&lt;a
  745: href="#frag"&gt;</literal> to refer to <literal>&lt;a
  746: name="frag"&gt;</literal>. For example, <literal>ID="Horse"</literal>
  747: points to <literal>about="#Horse</literal>"
  748: elsewhere in the file, allowing you to add to the description of any
  749: element with new properties and resources.
  750: </para>
  751: 
  752: </sect3>
  753: 
  754: <sect3 role="" id="mozilla-CHP-10-SECT-1.3.4" label="10.1.3.4">
  755: <title>Secondary sequences and literals</title>
  756: 
  757: <para>The <indexterm id="IXT-10-952"><primary>sequences, RDF</primary><secondary>creating
  758: files</secondary></indexterm><indexterm id="IXT-10-953"><primary>secondary sequences,
  759: RDF files</primary></indexterm><indexterm id="IXT-10-954"><primary>RDF (Resource
  760: Description
  761: Framework)</primary><secondary>files</secondary><tertiary>secondary
  762: sequesces</tertiary></indexterm><indexterm id="IXT-10-955"><primary>files</primary><secondary>RDF</secondary><tertiary>secondary
  763: sequesces</tertiary></indexterm><literal>Horse</literal> and
  764: <literal>House</literal> resources need to be defined next. <link linkend="mozilla-CHP-10-EX-3">Example 10-3</link> shows the creation of <literal>Horse</literal>
  765: from the second paragraph. The process for creating
  766: <literal>House</literal> is almost identical.
  767: </para>
  768: 
  769: <example id="mozilla-CHP-10-EX-3" label="10-3">
  770: <title>The Horse sequence </title>
  771: <programlisting>&lt;rdf:Description about="#Horse"&gt;
  772:     &lt;fly:list&gt;
  773:       &lt;rdf:Seq&gt;
  774:         &lt;rdf:li&gt;
  775:           &lt;rdf:Description about="musca_autumnalis" 
  776:                            fly:label="Face fly" 
  777:                            fly:color="green"/&gt;
  778:         &lt;/rdf:li&gt;
  779:         &lt;rdf:li&gt;
  780:           &lt;rdf:Description about="stomoxys_calcitrans" 
  781:                            fly:label="Stable Fly" 
  782:                            fly:color="black"/&gt;
  783:         &lt;/rdf:li&gt;
  784:         &lt;rdf:li&gt;
  785:           &lt;rdf:Description about="haematobia_irritans" 
  786:                            fly:label="Horn Fly" 
  787:                            fly:color="red"
  788:                            location:location="Kansas"/&gt;
  789:         &lt;/rdf:li&gt;
  790:       &lt;/rdf:Seq&gt;
  791:     &lt;/fly:list&gt;
  792:   &lt;/rdf:Description&gt;</programlisting>
  793: </example>
  794: 
  795: <para>Here the shorthand RDF definition continues to use only the
  796: attributes. Again, a <literal>&lt;fly:list&gt;</literal> is defined
  797: and the items inside it are listed. The listed values have multiple
  798: attribute values, all of which are RDF literals. In longhand with RDF
  799: showing all literals, the last item would be written out as follows:
  800: </para>
  801: 
  802: <programlisting>&lt;rdf:li&gt;
  803:    &lt;rdf:Description about="haematobia_irritans "&gt; 
  804:        &lt;fly:label&gt;Horn Fly&lt;/fly:label&gt;
  805:        &lt;fly:color&gt;red&lt;/fly:color&gt;
  806:        &lt;location:location&gt;Kansas&lt;/location:location&gt;
  807:    &lt;/rdf:Description&gt;
  808: &lt;/rdf:li&gt;</programlisting>
  809: 
  810: <para>The two different namespace literals are both resource attributes.
  811: <literal>haematobia_irritans</literal> is used as the resource
  812: identifier because it is a unique value among all data.
  813: </para>
  814: 
  815: <para>Laying out the data in the same pattern gives you the final, full RDF
  816: file in <link linkend="mozilla-CHP-10-EX-4">Example 10-4</link>.
  817: </para>
  818: 
  819: <example id="mozilla-CHP-10-EX-4" label="10-4">
  820: <title>Entire RDF file </title>
  821: <programlisting>&lt;?xml version="1.0"?&gt;
  822: &lt;rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  823:          xmlns:fly="http://xfly.mozdev.org/fly-rdf#"
  824:          xmlns:location="fly-location#"&gt;
  825:   &lt;rdf:Description about="urn:root"&gt;
  826:     &lt;fly:list&gt;
  827:       &lt;rdf:Seq&gt;
  828:         &lt;rdf:li&gt;
  829:           &lt;rdf:Description ID="House" fly:label="House"/&gt;
  830:         &lt;/rdf:li&gt;
  831:         &lt;rdf:li&gt;
  832:           &lt;rdf:Description ID="Horse" fly:label="Horse"/&gt;
  833:         &lt;/rdf:li&gt;
  834:       &lt;/rdf:Seq&gt;
  835:     &lt;/fly:list&gt;
  836:   &lt;/rdf:Description&gt;
  837:   &lt;rdf:Description about="#Horse"&gt;
  838:     &lt;fly:list&gt;
  839:       &lt;rdf:Seq&gt;
  840:         &lt;rdf:li&gt;
  841:           &lt;rdf:Description about="musca_autumnalis" 
  842:                            fly:label="Face fly" 
  843:                            fly:color="green"/&gt;
  844:         &lt;/rdf:li&gt;
  845:         &lt;rdf:li&gt;
  846:           &lt;rdf:Description about="stomoxys_calcitrans" 
  847:                            fly:label="Stable Fly" 
  848:                            fly:color="black"/&gt;
  849:         &lt;/rdf:li&gt;
  850:         &lt;rdf:li&gt;
  851:           &lt;rdf:Description about="haematobia_irritans" 
  852:                            fly:label="Horn Fly" 
  853:                            fly:color="red"
  854:                            location:location="Kansas"/&gt;
  855:         &lt;/rdf:li&gt;
  856:       &lt;/rdf:Seq&gt;
  857:     &lt;/fly:list&gt;
  858:   &lt;/rdf:Description&gt;
  859:   &lt;rdf:Description about="#House"&gt;
  860:     &lt;fly:list&gt;
  861:       &lt;rdf:Seq&gt;
  862:         &lt;rdf:li&gt;
  863:           &lt;rdf:Description about="musca_domestica" 
  864:                            fly:label="Common House Fly" 
  865:                            fly:color="brown"/&gt;
  866:         &lt;/rdf:li&gt;
  867:         &lt;rdf:li&gt;
  868:           &lt;rdf:Description about="sarcophagid" 
  869:                            fly:label="Carrion Fly" 
  870:                            fly:color="gray"
  871:                            location:location="Worldwide"/&gt;
  872:         &lt;/rdf:li&gt;
  873:         &lt;rdf:li&gt;
  874:           &lt;rdf:Description about="musca_oficio" 
  875:                            fly:label="Office Fly" 
  876:                            fly:color="white" 
  877:                            location:location="California, Bay Area"/&gt;
  878:         &lt;/rdf:li&gt;
  879:       &lt;/rdf:Seq&gt;
  880:     &lt;/fly:list&gt;
  881:   &lt;/rdf:Description&gt;
  882: &lt;/rdf:RDF&gt;</programlisting>
  883: </example>
  884: 
  885: <para><link linkend="mozilla-CHP-10-EX-4">Example 10-4</link> shows the RDF data used in several
  886: template examples in <link linkend="mozilla-CHP-9">Chapter 9</link>. <link linkend="mozilla-CHP-9-EX-4">Example 9-4</link> includes the <emphasis>10-4.rdf</emphasis>
  887: datasource, as do many of those templates. You can copy the data out
  888: of <link linkend="mozilla-CHP-10-EX-4">Example 10-4</link> and into a file of the same name to
  889: use as a datasource.
  890: </para>
  891: 
  892: </sect3>
  893: </sect2>
  894: </sect1>
  895: 
  896: <sect1 role="" id="mozilla-CHP-10-SECT-2" label="10.2">
  897: <title>The Mozilla Content Model</title>
  898: 
  899: <para>One theme <indexterm id="IXT-10-956"><primary>content
  900: model</primary><secondary>overview</secondary></indexterm><indexterm id="IXT-10-957"><primary>Gecko
  901: rendering engine</primary><secondary>Mozilla content
  902: model</secondary></indexterm>of this book -- and a general goal of
  903: the Mozilla development environment -- is that developers can
  904: create real applications using many of the same technologies they use
  905: to create a web page. The Gecko rendering engine, sitting at the
  906: heart of Mozilla and happily rendering web content, XML files, XUL
  907: interfaces, and whatever else they can support, is what makes this
  908: type of development possible. But how does Gecko know what to render
  909: and how? How can RDF data be handed over so that Gecko knows how to
  910: draw it?
  911: </para>
  912: 
  913: <para>When a browser uses the same engine to draw everything -- its own
  914: interface as well as the various kinds of content it
  915: supports -- that engine treats everything as content. Gecko needs
  916: a way to understand all the various parts of the Mozilla browser
  917: itself -- such as the sidebar, the toolbars, and the mail folders
  918: and mail messages -- as resources it can render and display in the
  919: Mozilla chrome. This approach to the Mozilla application interface is
  920: called the content model.
  921: </para>
  922: 
  923: <para>In Mozilla's content model, XUL documents and other
  924: interface resources are transformed into RDF when they are read. Each
  925: chunk of content is represented as a separate RDF datasource (see the
  926: next section, <link linkend="mozilla-CHP-10-SECT-2.1">Section 10.2.1</link>, for
  927: more information) and is then fed to the XUL Content Builder and
  928: rendered as the actual bits on the screen, as <link linkend="mozilla-CHP-10-FIG-9">Figure 10-9</link> shows.
  929: </para>
  930: 
  931: <figure id="mozilla-CHP-10-FIG-9" label="10-9">
  932: <title>Diagram of Mozilla's content model</title>
  933: <graphic fileref="figs/moz_1009.png"/></figure>
  934: 
  935: <para>As you can see in <link linkend="mozilla-CHP-10-FIG-9">Figure 10-9</link>, the content model can
  936: be complex. The XUL documents in <link linkend="mozilla-CHP-10-FIG-9">Figure 10-9</link> are
  937: files such as <filename>navigator.xul</filename>, which defines the
  938: main browser window's basic layout; the RDF
  939: documents include files like <filename>help-toc.rdf</filename>, which
  940: defines the Mozilla Help viewer's table of contents.
  941: The list of mail folders and accounts shown in <link linkend="mozilla-CHP-10-EX-5">Example 10-5</link> are part of the built-in data that Mozilla
  942: renders into browser content.
  943: </para>
  944: 
  945: <para>Whatever the source, the content model gets everything processed
  946: in-memory as RDF so that any data can be combined and formatted into
  947: XUL or other interface code. All sources of RDF data are called
  948: datasources.
  949: </para>
  950: 
  951: <sect2 role="" id="mozilla-CHP-10-SECT-2.1" label="10.2.1">
  952: <title>Datasources</title>
  953: 
  954: <para>A datasource <indexterm id="IXT-10-958"><primary>content
  955: model</primary><secondary>datasources</secondary></indexterm><indexterm id="IXT-10-959"><primary>datasources</primary><secondary>content
  956: model</secondary></indexterm>is a collection of related, typically
  957: homogenous, RDF statements. A datasource may be a single RDF file
  958: like <filename>localstore.rdf</filename>, a combination of files, or
  959: RDF structures that exist only in memory (as discussed later).
  960: </para>
  961: 
  962: <para>In Mozilla, datasources represent the messages in your email inbox,
  963: your bookmarks, the packages you installed, your browser history, and
  964: other sets of data. Datasources can be combined easily (or
  965: "composed," which is where the term
  966: "composite datasource" comes from).
  967: </para>
  968: 
  969: <sect3 role="" id="mozilla-CHP-10-SECT-2.1.1" label="10.2.1.1">
  970: <title>A datasource example: mailboxes</title>
  971: 
  972: <para>Several <indexterm id="IXT-10-960"><primary>content
  973: model</primary><secondary>datasources</secondary><tertiary>example</tertiary></indexterm><indexterm id="IXT-10-961"><primary>datasources</primary><secondary>content
  974: model</secondary><tertiary>example</tertiary></indexterm>datasources
  975: describe all the folders and messages in Mozilla's
  976: email. A root datasource called <literal>msgaccounts</literal>
  977: describes which mail servers and accounts are present. Separate
  978: datasources then represent each account separately. These datasources
  979: are composed to create the entire email storage system. The higher
  980: levels of this content structure look like <link linkend="mozilla-CHP-10-EX-5">Example 10-5</link>. 
  981: </para>
  982: 
  983: <example id="mozilla-CHP-10-EX-5" label="10-5">
  984: <title>Content model of email datasources </title>
  985: <programlisting>msgaccounts:/ 
  986: +-- <replaceable>http://home.netscape.com/NC-rdf#child</replaceable> --&gt; 
  987:     <userinput>imap:</userinput><replaceable>//</replaceable><userinput>oeschger@imap.netscape.com</userinput> 
  988:     |    +-- <replaceable>http://home.netscape.com/NC-rdf#IsServer</replaceable> --&gt; "true"
  989:     |    +-- <replaceable>http://home.netscape.com/NC-rdf#child</replaceable> --&gt;
  990:     |        <userinput>imap:</userinput><replaceable>//</replaceable><userinput>oeschger@imap.netscape.com/INBOX</userinput> 
  991:     |    +-- <replaceable>http://home.netscape.com/NC-rdf#TotalMessages</replaceable> --&gt; "4"
  992:     |    +-- <replaceable>http://home.netscape.com/NC-rdf#IsServer</replaceable> --&gt; "false"
  993:     |    +-- <replaceable>http://home.netscape.com/NC-rdf#MessageChild</replaceable> --&gt; 
  994:     |        <userinput>imap_message://oeschger@imap.netscape.com/INBOX#1</userinput> 
  995:     |    +-- <replaceable>http://home.netscape.com/NC-rdf#MessageChild</replaceable> --&gt; 
  996:     |        <userinput>imap_message://oeschger@imap.netscape.com/INBOX#2</userinput> 
  997:     |    +-- <replaceable>http://home.netscape.com/NC-rdf#MessageChild</replaceable> --&gt; 
  998:     |    etc... 
  999:     |         
 1000: +-- <replaceable>http://home.netscape.com/NC-rdf#child</replaceable> --&gt; 
 1001:     <userinput>mailbox:</userinput><replaceable>//</replaceable><userinput>oeschger@pop.netscape.com</userinput> 
 1002:     |    +-- <replaceable>http://home.netscape.com/NC-rdf#IsServer</replaceable> --&gt; "true"
 1003:     |    +-- <replaceable>http://home.netscape.com/NC-rdf#child</replaceable> --&gt; 
 1004:     |        <userinput>mailbox:</userinput><replaceable>//</replaceable><userinput>oeschger@pop.oeschger.com/INBOX</userinput> 
 1005:     |    +-- <replaceable>http://home.netscape.com/NC-rdf#TotalMessages</replaceable> --&gt; "2"
 1006:     |    etc...</programlisting>
 1007: </example>
 1008: 
 1009: <para>Each direct child of the root <filename>msgaccounts:/</filename> is a
 1010: mail server. This portion of the graph shows two Mozilla email
 1011: accounts that are the primary children:
 1012: <filename>imap://oeschger@imap.netscape.com</filename> and
 1013: <filename>mailbox://oeschger@pop.netscape.com</filename>. These two
 1014: accounts are entirely different datasources that can exist on their
 1015: own. The content model for email actually extends much lower than
 1016: what is represented in this outline. It uses RDF to represent the
 1017: data all the way into the actual message lists.
 1018: </para>
 1019: 
 1020: </sect3>
 1021: 
 1022: <sect3 role="" id="mozilla-CHP-10-SECT-2.1.2" label="10.2.1.2">
 1023: <title>Types of datasources</title>
 1024: 
 1025: <para>As you <indexterm id="IXT-10-962"><primary>content
 1026: model</primary><secondary>datasources</secondary><tertiary>types</tertiary></indexterm><indexterm id="IXT-10-963"><primary>datasources</primary><secondary>content
 1027: model</secondary><tertiary>types</tertiary></indexterm>may have
 1028: already inferred, email accounts are not actually RDF files. Mozilla
 1029: provides a custom RDF map of all email accounts and messages and the
 1030: content model represents the accounts and their relationships to one
 1031: another as RDF so they can be integrated and rendered properly. The
 1032: interface to this custom mail RDF map makes it possible to display a
 1033: list of messages and mailboxes in a <literal>&lt;tree&gt;</literal>
 1034: template.
 1035: </para>
 1036: 
 1037: <para>Another example of a datasource, the
 1038: <filename>in-memory-datasource,</filename> doesn't
 1039: come from an actual RDF file. When an in-memory datasource is
 1040: created, it doesn't contain data. However, data can
 1041: be inserted into it and stored in memory until the datasource is
 1042: destroyed. In-memory datasources frequently represent ephemeral data
 1043: like search results. Other basic datasource types are described in
 1044: <link linkend="mozilla-CHP-10-TABLE-2">Table 10-2</link>.
 1045: </para>
 1046: 
 1047: <table id="mozilla-CHP-10-TABLE-2" label="10-2">
 1048: 
 1049: <title>Types of datasources </title>
 1050: <tgroup cols="2">
 1051: <colspec colnum="1" colname="col1"/>
 1052: <colspec colnum="2" colname="col2"/>
 1053: <thead>
 1054: <row>
 1055: <entry>
 1056: <para>Type</para>
 1057: </entry>
 1058: <entry>
 1059: <para>Description</para>
 1060: </entry>
 1061: </row>
 1062: </thead>
 1063: <tbody>
 1064: <row>
 1065: <entry>
 1066: <para>Local datasource</para>
 1067: </entry>
 1068: <entry>
 1069: <para>A local datasource is an RDF graph contained in an RDF/XML file on a
 1070: local disk. All RDF files in the chrome registry (e.g.,
 1071: <filename>all-packages.rdf</filename> in the
 1072: <filename>chrome</filename> directory, which keeps track packages
 1073: installed in Mozilla) are local datasources.
 1074: </para>
 1075: </entry>
 1076: </row>
 1077: <row>
 1078: <entry>
 1079: <para>Remote datasource</para>
 1080: </entry>
 1081: <entry>
 1082: <para>RDF can be accessed locally or remotely. A remote datasource is an
 1083: RDF/XML file stored on a server and accessed with a URL.
 1084: </para>
 1085: </entry>
 1086: </row>
 1087: <row>
 1088: <entry>
 1089: <para>In-memory datasource</para>
 1090: </entry>
 1091: <entry>
 1092: <para>An in-memory datasource exists only in memory during a Mozilla
 1093: session. In-memory datasources are built with
 1094: <filename>assertions</filename>, statements that build an in-memory
 1095: data model by adding resources, properties, and value to those.
 1096: </para>
 1097: </entry>
 1098: </row>
 1099: <row>
 1100: <entry>
 1101: <para>Built-in datasource</para>
 1102: </entry>
 1103: <entry>
 1104: <para>These unique, prefabricated datasources represent something used
 1105: often in Mozilla, such as a built-in <filename>filesystem</filename>
 1106: datasource and a <filename>history</filename> datasource.
 1107: </para>
 1108: </entry>
 1109: </row>
 1110: <row>
 1111: <entry>
 1112: <para>Composite datasource</para>
 1113: </entry>
 1114: <entry>
 1115: <para>A composite datasource may be a combination of any of the datasources
 1116: previously listed. RDF allows you to merge different graphs.
 1117: </para>
 1118: </entry>
 1119: </row>
 1120: </tbody>
 1121: </tgroup>
 1122: </table>
 1123: 
 1124: </sect3>
 1125: </sect2>
 1126: </sect1>
 1127: 
 1128: <sect1 role="" id="mozilla-CHP-10-SECT-3" label="10.3">
 1129: <title>RDF Components and Interfaces</title>
 1130: 
 1131: <para>Once you are comfortable using XUL templates to display RDF data (see
 1132: <link linkend="mozilla-CHP-9">Chapter 9</link>), you should explore the various ways to
 1133: create and change that data. In Mozilla, data is generally RDF, since
 1134: all data in Mozilla is either represented formally in RDF or passed
 1135: through the RDF-based content model for display. Use the tools
 1136: described in this section to manipulate RDF and the data it
 1137: represents.
 1138: </para>
 1139: 
 1140: <para>Mozilla has a great set of interfaces for creating, manipulating, and
 1141: managing RDF, and it also provides ready-made RDF components that
 1142: represent datasources used in Mozilla. Think of RDF interfaces as
 1143: ways to manipulate RDF directly and of RDF components as sets of the
 1144: interfaces already associated with a particular kind of data, such as
 1145: bookmarks. Interfaces tend to deal with the RDF model itself, without
 1146: regard to the kinds of data being handled, while RDF components give
 1147: you control over specific Mozilla data. See the next two sections for
 1148: more information on RDF interfaces and components.
 1149: </para>
 1150: 
 1151: <sect2 role="" id="mozilla-CHP-10-SECT-3.1" label="10.3.1">
 1152: <title>What Is an RDF Component?</title>
 1153: 
 1154: <para>An RDF <indexterm id="IXT-10-964"><primary>RDF (Resource Description
 1155: Framework)</primary><secondary>components,
 1156: overview</secondary></indexterm><indexterm id="IXT-10-965"><primary>components</primary><secondary>RDF,
 1157: overview</secondary></indexterm>component may implement any number of
 1158: the general RDF interfaces described here, in addition to special
 1159: interfaces for accessing and controlling the data the datasource
 1160: represents. For example,
 1161: <literal>@mozilla.org/rdf/datasource;1?name=internetsearch</literal>
 1162: is an RDF component used to control Mozilla's
 1163: internet searching facility. In Mozilla, a component can act as a
 1164: library of code specific to a given set of data or domain. The
 1165: <literal>internetsearch</literal><indexterm id="IXT-10-966"><primary>internetsearch
 1166: component</primary></indexterm> component is instantiated and used to
 1167: recall text entered in a previous search:
 1168: </para>
 1169: 
 1170: <programlisting>var searchDS = Components.classes["@mozilla.org/rdf/datasource;1?name=internetsearch"]
 1171:       .getService(Components.interfaces.nsIInternetSearchService);
 1172:  
 1173: searchDS.RememberLastSearchText(escapedSearchStr);</programlisting>
 1174: 
 1175: <para>This RDF component implements an interface called
 1176: <emphasis>nsIInternetSearchService</emphasis><indexterm id="IXT-10-967"><primary>nsIInternetSearchService
 1177: interface</primary></indexterm><indexterm id="IXT-10-968"><primary>interfaces</primary><secondary>nsIInternetSearchService</secondary></indexterm>,
 1178: which is selected from the component and used to call the
 1179: <literal>RememberLastSearchText</literal> method. Although you can
 1180: also use the <literal>getService</literal> method to get one of a
 1181: component's RDF interfaces (e.g., by using
 1182: <literal>getService(Components.interfaces.nsIRDFDataSource)</literal>),
 1183: doing so is seldom necessary in practice. RDF components are tailored
 1184: to the datasources they represent and usually provide all the access
 1185: you need to access that data directly. <link linkend="mozilla-CHP-10-EX-6">Example 10-6</link>
 1186: lists RDF components in Mozilla.
 1187: </para>
 1188: 
 1189: <example id="mozilla-CHP-10-EX-6" label="10-6">
 1190: <title>RDF-specific components built into Mozilla </title>
 1191: <programlisting>@mozilla.org/rdf/container;1 
 1192: @mozilla.org/rdf/content-sink;1 
 1193: @mozilla.org/rdf/datasource;1?name=addresscard 
 1194: @mozilla.org/rdf/datasource;1?name=addressdirectory 
 1195: @mozilla.org/rdf/datasource;1?name=bookmarks 
 1196: @mozilla.org/rdf/datasource;1?name=charset-menu 
 1197: @mozilla.org/rdf/datasource;1?name=composite-datasource 
 1198: @mozilla.org/rdf/datasource;1?name=files 
 1199: @mozilla.org/rdf/datasource;1?name=history 
 1200: @mozilla.org/rdf/datasource;1?name=httpindex 
 1201: @mozilla.org/rdf/datasource;1?name=in-memory-datasource 
 1202: @mozilla.org/rdf/datasource;1?name=internetsearch 
 1203: @mozilla.org/rdf/datasource;1?name=ispdefaults 
 1204: @mozilla.org/rdf/datasource;1?name=local-store 
 1205: @mozilla.org/rdf/datasource;1?name=localsearch 
 1206: @mozilla.org/rdf/datasource;1?name=mailnewsfolders 
 1207: @mozilla.org/rdf/datasource;1?name=msgaccountmanager 
 1208: @mozilla.org/rdf/datasource;1?name=msgfilters 
 1209: @mozilla.org/rdf/datasource;1?name=msgnotifications 
 1210: @mozilla.org/rdf/datasource;1?name=smtp 
 1211: @mozilla.org/rdf/datasource;1?name=subscribe 
 1212: @mozilla.org/rdf/datasource;1?name=window-mediator 
 1213: @mozilla.org/rdf/datasource;1?name=xml-datasource 
 1214: @mozilla.org/rdf/delegate-factory;1?key=filter&amp;scheme=imap 
 1215: @mozilla.org/rdf/delegate-factory;1?key=filter&amp;scheme=mailbox 
 1216: @mozilla.org/rdf/delegate-factory;1?key=filter&amp;scheme=news 
 1217: @mozilla.org/rdf/delegate-factory;1?key=smtpserver&amp;scheme=smtp 
 1218: @mozilla.org/rdf/rdf-service;1 
 1219: @mozilla.org/rdf/resource-factory;1 
 1220: @mozilla.org/rdf/resource-factory;1?name=abdirectory 
 1221: @mozilla.org/rdf/resource-factory;1?name=abmdbcard 
 1222: @mozilla.org/rdf/resource-factory;1?name=abmdbdirectory 
 1223: @mozilla.org/rdf/resource-factory;1?name=imap 
 1224: @mozilla.org/rdf/resource-factory;1?name=mailbox 
 1225: @mozilla.org/rdf/resource-factory;1?name=news 
 1226: @mozilla.org/rdf/xml-parser;1 
 1227: @mozilla.org/rdf/xml-serializer;1</programlisting>
 1228: </example>
 1229: 
 1230: <para>From this list, components used often in the Mozilla source code
 1231: include bookmarks, history, mail and news folders, and address books.
 1232: </para>
 1233: 
 1234: <sidebar id="mozilla-CHP-10-SIDEBAR-1">
 1235: <title>Special URIs</title>
 1236: 
 1237: <para>Mozilla's built-in datasource
 1238: <indexterm id="IXT-10-969"><primary>URIs (Universal Resource
 1239: Identifiers)</primary><secondary>datasource
 1240: components</secondary></indexterm><indexterm id="IXT-10-970"><primary>components</primary><secondary>URIs</secondary></indexterm>components
 1241: have special URIs for access. Here is the format used to determine
 1242: the URI from the component reference:
 1243: </para>
 1244: 
 1245: <para>Component:</para>
 1246: 
 1247: <programlisting>@mozilla.org/rdf/datasource;1?name=SomeName</programlisting>
 1248: 
 1249: <para>Datasource URI:</para>
 1250: 
 1251: <programlisting>rdf:SomeName</programlisting>
 1252: 
 1253: <para>The URI, such as rdf:someName, is also accessible as a datasource property:</para>
 1254: 
 1255: <programlisting>foo-ds.URI</programlisting>
 1256: </sidebar>
 1257: 
 1258: </sect2>
 1259: <sect2 role="" id="mozilla-CHP-10-SECT-3.2" label="10.3.2">
 1260: <title>What Are RDF Interfaces?</title>
 1261: 
 1262: <para>RDF interfaces <indexterm id="IXT-10-971"><primary>RDF (Resource Description
 1263: Framework)</primary><secondary>interfaces</secondary><tertiary>overview</tertiary></indexterm><indexterm id="IXT-10-972"><primary>interfaces</primary><secondary>RDF</secondary><tertiary>overview</tertiary></indexterm>are
 1264: interfaces in Mozilla designed to manipulate RDF structures and data.
 1265: They typically deal with RDF generally, rather than specific sets of
 1266: data (as in the case of components). A common use for an RDF
 1267: interface in JavaScript, shown in <link linkend="mozilla-CHP-10-EX-7">Example 10-7</link>, is to
 1268: use <emphasis>nsIRDFService</emphasis> to retrieve or assert the root
 1269: node of an RDF datasource.
 1270: </para>
 1271: 
 1272: <example id="mozilla-CHP-10-EX-7" label="10-7">
 1273: <title>Creating a root node </title>
 1274: <programlisting>// get the nsIRDFService interface and assign it to RDF
 1275: RDF = Components.classes[`@mozilla.org/rdf/rdf-service;1'].
 1276:       getService(Components.interfaces.nsIRDFService);
 1277: // call the GetResource method from the interface
 1278: rootResource = RDF.GetResource('urn:root');</programlisting>
 1279: </example>
 1280: 
 1281: <para>Like all Mozilla interfaces, RDF interfaces (shown in <link linkend="mozilla-CHP-10-TABLE-3">Table 10-3</link>) are defined in IDL and can be accessed
 1282: through XPCOM. The examples in this section use JavaScript and
 1283: XPConnect to access the components for simplicity, but you can also
 1284: use these interfaces with C++, as they are often in the actual
 1285: Mozilla source code. Most interfaces deal with datasources, which
 1286: drive the use of RDF in Mozilla.
 1287: </para>
 1288: 
 1289: <table id="mozilla-CHP-10-TABLE-3" label="10-3">
 1290: 
 1291: <title>Mozilla's built-in RDF interfaces </title>
 1292: <tgroup cols="2">
 1293: <colspec colnum="1" colname="col1"/>
 1294: <colspec colnum="2" colname="col2"/>
 1295: <thead>
 1296: <row>
 1297: <entry>
 1298: <para>RDF interface</para>
 1299: </entry>
 1300: <entry>
 1301: <para>Description</para>
 1302: </entry>
 1303: </row>
 1304: </thead>
 1305: <tbody>
 1306: <row>
 1307: <entry>
 1308: <para><emphasis>nsIRDFService</emphasis></para>
 1309: </entry>
 1310: <entry>
 1311: <para>Mostly used for retrieving datasources, resources, and literals. It
 1312: also registers and unregisters datasources and resources.
 1313: </para>
 1314: </entry>
 1315: </row>
 1316: <row>
 1317: <entry>
 1318: <para><emphasis>nsIRDFCompositeDataSource</emphasis></para>
 1319: </entry>
 1320: <entry>
 1321: <para>Allows the addition and removal of a datasource from a composite
 1322: datasource (which may be empty).
 1323: </para>
 1324: </entry>
 1325: </row>
 1326: <row>
 1327: <entry>
 1328: <para><emphasis>nsIRDFDataSource, nsIRDFPurgeableDataSource,
 1329: nsIRDFRemoteDataSource</emphasis>
 1330: </para>
 1331: </entry>
 1332: <entry>
 1333: <para>Mostly used for adding, removing, and changing triples in a
 1334: datasource. It provides the means to change the graph.
 1335: </para>
 1336: </entry>
 1337: </row>
 1338: <row>
 1339: <entry>
 1340: <para><emphasis>nsIRDFNode, nsIRDFResource, nsIRDFLiteral</emphasis></para>
 1341: </entry>
 1342: <entry>
 1343: <para>Provide an equality function. Values for resources and literals can
 1344: be retrieved. Objects of these types are retrieved from
 1345: <literal>nsIRDFService</literal>.
 1346: </para>
 1347: </entry>
 1348: </row>
 1349: <row>
 1350: <entry>
 1351: <para><emphasis>nsIRDFContainer</emphasis></para>
 1352: </entry>
 1353: <entry>
 1354: <para>Provides vector-like access to an RDF container's
 1355: elements.
 1356: </para>
 1357: </entry>
 1358: </row>
 1359: <row>
 1360: <entry>
 1361: <para><emphasis>nsIRDFContainerUtils</emphasis></para>
 1362: </entry>
 1363: <entry>
 1364: <para>Provides container creation and other container-related functions.</para>
 1365: </entry>
 1366: </row>
 1367: <row>
 1368: <entry>
 1369: <para><emphasis>nsIRDFObserver</emphasis></para>
 1370: </entry>
 1371: <entry>
 1372: <para>Fires events when data is changed in a datasource.</para>
 1373: </entry>
 1374: </row>
 1375: <row>
 1376: <entry>
 1377: <para><emphasis>nsIRDFXMLParser, nsIRDFXMLSerializer, nsIRDFXMLSink,
 1378: nsIRDFXMLSource</emphasis>
 1379: </para>
 1380: </entry>
 1381: <entry>
 1382: <para>Used for working with RDF/XML. Functions are provided for parsing
 1383: files and serializing content.
 1384: </para>
 1385: </entry>
 1386: </row>
 1387: </tbody>
 1388: </tgroup>
 1389: </table>
 1390: 
 1391: <para>The sheer variety of RDF interfaces may seem overwhelming, but all
 1392: interfaces serve different purposes and are often used in conjunction
 1393: with one another. In your particular application space, you may find
 1394: yourself using some subsets of these interfaces constantly and others
 1395: not at all. This section describes some of the most commonly used
 1396: functions. You can look up all of interfaces in their
 1397: entirety<indexterm id="IXT-10-973"><primary>web sites</primary><secondary>RDF
 1398: interfaces</secondary></indexterm> at <systemitem role="url">http://lxr.mozilla.org/seamonkey/source/rdf/base/idl/</systemitem>.
 1399: </para>
 1400: 
 1401: </sect2>
 1402: <sect2 role="" id="mozilla-CHP-10-SECT-3.3" label="10.3.3">
 1403: <title>nsIRDFService</title>
 1404: 
 1405: <para>If you<indexterm id="IXT-10-974"><primary>nsIRDFService
 1406: interface</primary></indexterm><indexterm id="IXT-10-975"><primary>RDF (Resource
 1407: Description
 1408: Framework)</primary><secondary>interfaces</secondary><tertiary>nsIRDFService</tertiary></indexterm><indexterm id="IXT-10-976"><primary>interfaces</primary><secondary>RDF</secondary><tertiary>nsIRDFService</tertiary></indexterm>
 1409: will do any sort of RDF processing, you need to use the
 1410: <emphasis>nsIRDFService</emphasis> interface. It provides the basics
 1411: for working with datasources, resources, and literals, and is useful
 1412: when you process RDF data. <emphasis>nsIRDFService</emphasis> can be
 1413: initialized by using the <literal>getService</literal> method of the
 1414: <literal>rdf-service</literal> class:
 1415: </para>
 1416: 
 1417: <programlisting>RDF = Components.classes[`@mozilla.org/rdf/rdf-service;1']
 1418:       getService(Components.interfaces.nsIRDFService);</programlisting>
 1419: 
 1420: <para>Once the service is available, it's ready to go to
 1421: work. Even though no datasource is created yet (in this particular
 1422: example), the RDF service can still get resources and literals, as
 1423: shown in the next section.
 1424: </para>
 1425: 
 1426: <sect3 role="" id="mozilla-CHP-10-SECT-3.3.1" label="10.3.3.1">
 1427: <title>Getting a resource</title>
 1428: 
 1429: <para>Once a
 1430: resource<indexterm id="IXT-10-977"><primary>resources</primary><secondary>nsIRDFService
 1431: interface</secondary></indexterm> is created (e.g., with the
 1432: identifier <literal>urn:root</literal> in <link linkend="mozilla-CHP-10-EX-7">Example 10-7</link>), it needs to be added to a datasource:
 1433: </para>
 1434: 
 1435: <programlisting>rootResource = RDF.GetResource('urn:root');</programlisting>
 1436: 
 1437: <para>When a resource is already registered under the given identifier (see
 1438: <link linkend="mozilla-CHP-10-SECT-3.3.4">Section 10.3.3.4</link>, later in this chapter
 1439: for more information about RDF registration), then
 1440: <literal>GetResource</literal><indexterm id="IXT-10-978"><primary>GetResource
 1441: function</primary></indexterm> returns that resource.
 1442: </para>
 1443: 
 1444: </sect3>
 1445: 
 1446: <sect3 role="" id="mozilla-CHP-10-SECT-3.3.2" label="10.3.3.2">
 1447: <title>Getting an anonymous resource</title>
 1448: 
 1449: <para>Anonymous resources are resources with no resource identifier. Here
 1450: is the creation of a new anonymous resource and a test of its
 1451: anonymity:
 1452: </para>
 1453: 
 1454: <programlisting>anonResource = RDF.GetAnonymousResource( );
 1455: // This would be true. Checking is not necessary, just here for example.
 1456: isAnon = RDF.isAnonymousResource(anonResource);</programlisting>
 1457: 
 1458: <para>Typically, these resources are turned into containers, as shown in
 1459: the next section. Anonymous resources exist when names are not needed
 1460: and a simple reference to that resource is all that is required.
 1461: </para>
 1462: 
 1463: </sect3>
 1464: 
 1465: <sect3 role="" id="mozilla-CHP-10-SECT-3.3.3" label="10.3.3.3">
 1466: <title>Getting a literal</title>
 1467: 
 1468: <para>The <literal>GetLiteral</literal><indexterm id="IXT-10-979"><primary>GetLiteral
 1469: function</primary></indexterm> function
 1470: <indexterm id="IXT-10-980"><primary>literals</primary><secondary>nsIRDFService
 1471: interface</secondary></indexterm>returns the given name in the format
 1472: of a literal, which you can then use to assert into an RDF graph as a
 1473: resource.
 1474: </para>
 1475: 
 1476: <programlisting>myName = RDF.GetLiteral('Eric');</programlisting>
 1477: 
 1478: <para>Variations on this function are <literal>GetIntLiteral</literal> and
 1479: <literal>GetDateLiteral</literal>.
 1480: </para>
 1481: 
 1482: </sect3>
 1483: 
 1484: <sect3 role="" id="mozilla-CHP-10-SECT-3.3.4" label="10.3.3.4">
 1485: <title>Registering and unregistering datasources</title>
 1486: 
 1487: <para>If you create
 1488: <indexterm id="IXT-10-981"><primary>datasources</primary><secondary>registering</secondary></indexterm><indexterm id="IXT-10-982"><primary>registering</primary><secondary>datasources</secondary></indexterm><indexterm id="IXT-10-983"><primary>RDF
 1489: (Resource Description Framework)</primary><secondary>datasources,
 1490: registering</secondary></indexterm>a Mozilla application that uses
 1491: the same datasource or RDF resources in different ways, you may want
 1492: to register the datasource with Mozilla. When you register a
 1493: datasource, you register it as a component in Mozilla (see <link linkend="mozilla-CHP-8-SECT-1.6">Section 8.1.6</link> for more information on
 1494: Mozilla's component model), which means it can be
 1495: accessed and used as easily as any other XPCOM component, and from
 1496: anywhere in Mozilla.
 1497: </para>
 1498: 
 1499: <para>To register a datasource, call the
 1500: <literal>RegisterDatasource</literal><indexterm id="IXT-10-984"><primary>RegisterDatasource
 1501: method</primary></indexterm> method of the RDF Service. In this
 1502: example, the datasource already exists and is assigned to a variable
 1503: named <emphasis>myDatasource</emphasis>:
 1504: </para>
 1505: 
 1506: <programlisting>RDF.RegisterDataSource(myDatasource, false);</programlisting>
 1507: 
 1508: <para>In this case, <emphasis>myDatasource</emphasis> is the datasource
 1509: name, and the <literal>false</literal> parameter specifies that this
 1510: datasource is not replacing a datasource with the same name. Once a
 1511: datasource is registered with the component manager in this way, it
 1512: can be retrieved by name and associated with another instance:
 1513: </para>
 1514: 
 1515: <programlisting>secondDatasource = anotherRDF.GetDataSource("My Datasource");</programlisting>
 1516: 
 1517: <para>To unregister a datasource from the RDF Service, pass the datasource
 1518: into the <literal>UnRegisterDataSource</literal> function:
 1519: </para>
 1520: 
 1521: <programlisting>RDF.UnRegisterDataSource(myDatasource);</programlisting>
 1522: 
 1523: <para>Once it's unregistered, a datasource is no longer
 1524: available to other instances of the RDF Service. Registered resources
 1525: work the same way as datasources in the RDF Service: if a resource is
 1526: registered with the RDF Service, then it is available in every
 1527: instance of RDF Service. To get two different instances of the same
 1528: registered datasource and unregister its use:
 1529: </para>
 1530: 
 1531: <programlisting>newResource = RDF.GetResource('my.resource');
 1532: RDF.RegisterResource(newResource,false);
 1533: notNewResource = RDF.GetResource('my.resource');
 1534: RDF.UnRegisterResource(notNewResource);</programlisting>
 1535: 
 1536: 
 1537: 
 1538: <tip id="ch10-13-fm2xml" role="ora">
 1539: <para>If you register resources and datasources, be sure to use the
 1540: <emphasis>overwrite</emphasis> Boolean variable on
 1541: <literal>RegisterDataSource</literal> and
 1542: <literal>RegisterResource</literal> to avoid overwriting existing
 1543: datasources.
 1544: </para>
 1545: </tip>
 1546: 
 1547: </sect3>
 1548: 
 1549: <sect3 role="" id="mozilla-CHP-10-SECT-3.3.5" label="10.3.3.5">
 1550: <title>Getting a remote datasource</title>
 1551: 
 1552: <para>Finally, <emphasis>nsIRDFService</emphasis>
 1553: provides<indexterm id="IXT-10-985"><primary>datasources</primary><secondary>remote,
 1554: getting</secondary></indexterm><indexterm id="IXT-10-986"><primary>remote
 1555: datasources, getting</primary></indexterm> a useful method that loads
 1556: a datasource from a remote server, which is a process that occurs
 1557: asynchronously. Compared to forthcoming discussions about datasource
 1558: loading, <literal>GetDataSource</literal> is a real shortcut:
 1559: </para>
 1560: 
 1561: <programlisting>remoteDatasource = RDF.GetDataSource('http://books.mozdev.org/file.rdf');</programlisting>
 1562: 
 1563: 
 1564: 
 1565: <note id="ch10-15-fm2xml" role="ora">
 1566: <para>Remember that RDF files requested in this way must be set with the
 1567: text/rdf MIME type on the web server to load properly.
 1568: </para>
 1569: </note>
 1570: 
 1571: </sect3>
 1572: </sect2>
 1573: <sect2 role="" id="mozilla-CHP-10-SECT-3.4" label="10.3.4">
 1574: <title>nsIRDFCompositeDataSource</title>
 1575: 
 1576: <para>When you work <indexterm id="IXT-10-987"><primary>nsIRDFCompositeDataSource
 1577: interface</primary></indexterm><indexterm id="IXT-10-988"><primary>RDF (Resource
 1578: Description
 1579: Framework)</primary><secondary>interfaces</secondary><tertiary>nsIRDFCompositeDataSource</tertiary></indexterm><indexterm id="IXT-10-989"><primary>interfaces</primary><secondary>RDF</secondary><tertiary>nsIRDFCompositeDataSource</tertiary></indexterm>with
 1580: multiple datasources, you can make things easier by grouping them,
 1581: which <emphasis>nsIRDFCompositeDataSource</emphasis> allows you to
 1582: do. This functionality aggregates data in a number of
 1583: Mozilla's applications. To get this interface,
 1584: invoke:
 1585: </para>
 1586: 
 1587: <programlisting>composite_datasource   
 1588:    = '@mozilla.org/rdf/datasource;1?name=composite-datasource';
 1589: compDataSource = Components.classes[composite_datasource]
 1590:    getService(Components.interfaces.nsIRDFCompositeDataSource);</programlisting>
 1591: 
 1592: <para>Once you have the interface, adding and removing datasources from the
 1593: composite is easy. You can also enumerate the datasources by using
 1594: the <literal>getNext</literal> method. <link linkend="mozilla-CHP-10-EX-8">Example 10-8</link>
 1595: demonstrates how to add, remove, and cycle through datasources.
 1596: </para>
 1597: 
 1598: <example id="mozilla-CHP-10-EX-8" label="10-8">
 1599: <title>Manipulating datasources </title>
 1600: <programlisting>compDataSource.AddDataSource(datasource1);
 1601: compDataSource.AddDataSource(datasource2);
 1602: compDataSource.AddDataSource(datasource3);
 1603: compDataSource.RemoveDataSource(datasource1);
 1604: allDataSources = compDataSource.GetDataSources( );
 1605: datasource2 = allDataSources.getNext( );
 1606: datasource2.QueryInterface(Components.interfaces.nsIRDFDataSource);
 1607: datasource3 = allDataSources.getNext( );
 1608: datasource3.QueryInterface(Components.interfaces.nsIRDFDataSource);</programlisting>
 1609: </example>
 1610: 
 1611: <para>In <link linkend="mozilla-CHP-10-EX-8">Example 10-8</link>, <literal>allDataSources</literal> is
 1612: an <emphasis>nsISimpleEnumerator</emphasis> returned by the
 1613: <literal>GetDataSources</literal> method on the composite datasource.
 1614: <literal>datasource1</literal> is removed from the composite, and
 1615: then the remaining datasources are cycled through. This step provides
 1616: a way to iterate through a collection of datasources.
 1617: <emphasis>nsIRDFCompositeDatasource</emphasis> also inherits the many
 1618: functions of <emphasis>nsIRDFDataSource</emphasis>; refer to the
 1619: section <link linkend="mozilla-CHP-10-SECT-3.5">Section 10.3.5</link> for more
 1620: information.
 1621: </para>
 1622: 
 1623: </sect2>
 1624: <sect2 role="" id="mozilla-CHP-10-SECT-3.5" label="10.3.5">
 1625: <title>nsIRDFDataSource</title>
 1626: 
 1627: <para>The
 1628: <emphasis>nsIRDFDataSource</emphasis><indexterm id="IXT-10-990"><primary>nsIRDFDataSource
 1629: interface</primary></indexterm><indexterm id="IXT-10-991"><primary>RDF (Resource
 1630: Description
 1631: Framework)</primary><secondary>interfaces</secondary><tertiary>nsIRDFDataSource</tertiary></indexterm><indexterm id="IXT-10-992"><primary>interfaces</primary><secondary>RDF</secondary><tertiary>nsIRDFDataSource</tertiary></indexterm>
 1632: interface is large, with twenty functions and one attribute
 1633: (<literal>URI</literal>), so it's one of the most
 1634: common interfaces used to manipulate RDF data.
 1635: <emphasis>nsIRDFDataSource</emphasis> contains all the components in
 1636: <link linkend="mozilla-CHP-10-EX-6">Example 10-6</link> with
 1637: "datasource" in their contract IDs,
 1638: along with other common components:
 1639: </para>
 1640: 
 1641: <programlisting>@mozilla.org/browser/bookmarks-service;1
 1642: @mozilla.org/related-links-handler;1
 1643: @mozilla.org/browser/localsearch-service;1
 1644: @mozilla.org/registry-viewer;1
 1645: @mozilla.org/browser/global-history;1</programlisting>
 1646: 
 1647: <para>The <emphasis>nsIRDFDataSource</emphasis> interface is meant to
 1648: handle some of the core interaction with the datasource. APIs such as
 1649: <literal>URI</literal>, <literal>GetTarget</literal>,
 1650: <literal>Assert</literal>, and <literal>Change</literal> are helpful
 1651: for working on the RDF graph itself. For example, the
 1652: <literal>@mozilla.org/rdf/datasource;1?name=in-memory-datasource</literal>
 1653: RDF component demonstrates the use of the
 1654: <emphasis>nsIRDFDataSource</emphasis> interface. When this component
 1655: is created, it's a blank datasource in memory, into
 1656: which objects are inserted, changed, and removed. You can access the
 1657: <emphasis>nsIRDFDataSource</emphasis> interface from the RDF
 1658: component by first constructing an RDF graph in the in-memory
 1659: datasource:
 1660: </para>
 1661: 
 1662: <programlisting>mem = '@mozilla.org/rdf/datasource;1?name=in-memory-datasource';
 1663: datasource = Components.classes[mem].
 1664:              createInstance(Components.interfaces.nsIRDFDataSource);</programlisting>
 1665: 
 1666: <para>Of the twenty functions (found at
 1667: <emphasis>http://lxr.mozilla.org/seamonkey/source/rdf/base/idl/nsIRDFDataSource.idl</emphasis>)
 1668: in this interface, we show only a handful here:
 1669: </para>
 1670: 
 1671: <itemizedlist><listitem>
 1672: <para>Assertion and removal</para>
 1673: </listitem><listitem>
 1674: <para>Changing values</para>
 1675: </listitem><listitem>
 1676: <para>Moving triples</para>
 1677: </listitem><listitem>
 1678: <para>HasAssertion</para>
 1679: </listitem><listitem>
 1680: <para>GetTarget</para>
 1681: </listitem><listitem>
 1682: <para>GetSource</para>
 1683: </listitem></itemizedlist>
 1684: <para>The main purpose of the <emphasis>nsIRDFDatasource</emphasis>
 1685: interface is to work with RDF triples inside a datasource, allowing
 1686: you to change that datasource's RDF graph.
 1687: </para>
 1688: 
 1689: <sect3 role="" id="mozilla-CHP-10-SECT-3.5.1" label="10.3.5.1">
 1690: <title>Assertion and removal</title>
 1691: 
 1692: <para>Recall from
 1693: the<indexterm id="IXT-10-993"><primary>triples</primary><secondary>nsIRDFDataSource
 1694: interface</secondary></indexterm> <link linkend="mozilla-CHP-10-SECT-1.1.2">Section 10.1.1.2</link> section, earlier in this
 1695: chapter, that triples are RDF statements in which the relationship
 1696: between the subject, predicate, and object is more strictly defined.
 1697: In the interface code, a triple's elements are all
 1698: typically defined as resources rather than plain URIs, which means
 1699: they can be asserted into a datasource in the particular sequence
 1700: that makes them meaningful as parts of a triple:
 1701: </para>
 1702: 
 1703: <programlisting>rootSubject = RDF.GetResource('urn:root');
 1704: predicate = RDF.GetResource('http://books.mozdev.org/rdf#chapters');
 1705: object = RDF.GetResource('Chapter1');
 1706: datasource.Assert(rootSubject,predicate,object,true);</programlisting>
 1707: 
 1708: <para>Once you assert the statement's elements into the
 1709: datasource in this way, the datasource contains the triple. The
 1710: <literal>truth</literal> value parameter in the last slot indicates
 1711: that the given node is "locked" and
 1712: thus cannot be overwritten.
 1713: </para>
 1714: 
 1715: <para>Removing a triple from the datasource is as easy as adding it. If you
 1716: try to remove a triple that doesn't exist, your
 1717: request is ignored and no error messages are raised. To unassert a
 1718: triple in the datasource, use:
 1719: </para>
 1720: 
 1721: <programlisting>rootSubject = RDF.GetResource('urn:root');
 1722: predicate = RDF.GetResource('http://books.mozdev.org/rdf#chapters');
 1723: object = RDF.GetResource('Chapter8');
 1724: datasource.Unassert(rootSubject,predicate,object);</programlisting>
 1725: 
 1726: </sect3>
 1727: 
 1728: <sect3 role="" id="mozilla-CHP-10-SECT-3.5.2" label="10.3.5.2">
 1729: <title>Changing values</title>
 1730: 
 1731: <para>Changing values
 1732: <indexterm id="IXT-10-994"><primary>literals</primary><secondary>values,
 1733: changing</secondary></indexterm><indexterm id="IXT-10-995"><primary>datasources</primary><secondary>values,
 1734: changing</secondary></indexterm>in a datasource is also very easy.
 1735: Assert and change a literal in the datasource as follows:
 1736: </para>
 1737: 
 1738: <programlisting>subject = RDF.GetResource('Chapter1');
 1739: predicate = RDF.GetResource('http://books.mozdev.org/rdf#title');
 1740: object = RDF.GetLiteral('Mozilla as a Platform');
 1741: datasource.Assert(subject,predicate,object,true);
 1742: newObject = RDF.GetLiteral('Mozilla is a cool Platform!');
 1743: datasource.Change(subject,predicate,newObject,);</programlisting>
 1744: 
 1745: <para>If working with triples seems hard in the template generation, their
 1746: use in these examples -- where adding to and changing the parts is
 1747: so easy -- may make things clearer.
 1748: </para>
 1749: 
 1750: </sect3>
 1751: 
 1752: <sect3 role="" id="mozilla-CHP-10-SECT-3.5.3" label="10.3.5.3">
 1753: <title>Moving triples</title>
 1754: 
 1755: <para>Moving a
 1756: triple<indexterm id="IXT-10-996"><primary>triples</primary><secondary>moving</secondary></indexterm>
 1757: in a datasource also requires some simple code. This example moves
 1758: the asserted triple in the previous section:
 1759: </para>
 1760: 
 1761: <programlisting>newSubject = RDF.GetResource('Chapter99');
 1762: // Moving from Chapter1 to Chapter99
 1763: datasource.Move(subject,newSubject,predicate,object);</programlisting>
 1764: 
 1765: </sect3>
 1766: 
 1767: <sect3 role="" id="mozilla-CHP-10-SECT-3.5.4" label="10.3.5.4">
 1768: <title>HasAssertion</title>
 1769: 
 1770: <para>This next example<indexterm id="IXT-10-997"><primary>HasAssertion
 1771: function</primary></indexterm> checks if the previous statement still
 1772: exists in the datasource.
 1773: </para>
 1774: 
 1775: <programlisting>datasource.HasAssertion(newSubject,predicate,object,true);</programlisting>
 1776: 
 1777: <para>This function is useful when you create new statements and resources
 1778: and want to make sure you are not overwriting pre-existing resources.
 1779: </para>
 1780: 
 1781: </sect3>
 1782: 
 1783: <sect3 role="" id="mozilla-CHP-10-SECT-3.5.5" label="10.3.5.5">
 1784: <title>GetTarget</title>
 1785: 
 1786: <para>The <literal>GetTarget</literal><indexterm id="IXT-10-998"><primary>GetTarget
 1787: method</primary></indexterm> method returns the
 1788: resource's property value (i.e., the object). Given
 1789: the RDF statement "(Eric) wrote (a
 1790: book)," for example, the
 1791: <literal>GetTarget</literal> method would input
 1792: "Eric" and
 1793: "wrote" and get back the object
 1794: "a book." Once again, the example
 1795: code is based on the previous examples:
 1796: </para>
 1797: 
 1798: <programlisting>object = datasource.GetTarget(newSubject,predicate,true);
 1799: objects = datasource.GetTargets(rootSubject,predicate,true);
 1800: // objects is an nsIEnumeration of the object and its properties</programlisting>
 1801: 
 1802: <para>In addition to <literal>GetTarget</literal>, as seen above, a
 1803: <literal>GetTargets</literal> function returns an object and its
 1804: properties in an enumeration. This function can be very handy for
 1805: quick access to resources with fewer function calls.
 1806: </para>
 1807: 
 1808: </sect3>
 1809: 
 1810: <sect3 role="" id="mozilla-CHP-10-SECT-3.5.6" label="10.3.5.6">
 1811: <title>GetSource</title>
 1812: 
 1813: <para><literal>GetSource</literal><indexterm id="IXT-10-999"><primary>GetSource
 1814: method</primary></indexterm> is the inverse of
 1815: <literal>GetTarget</literal>. Whereas <literal>GetTarget</literal>
 1816: returns an object, <literal>GetSource</literal> returns the subject
 1817: attached to an object. Given the RDF statement
 1818: "(Eric) wrote (a book)" again, in
 1819: other words, the <literal>GetSource</literal> method would input
 1820: "wrote" and "a
 1821: book" and get back the statement subject
 1822: "Eric."
 1823: </para>
 1824: 
 1825: <programlisting>subject = datasource.GetSource(object,predicate,true);
 1826: subjects = datasource.GetSources(object,predicate,true);
 1827: // subjects is an nsIEnumeration of the subject and its properties</programlisting>
 1828: 
 1829: <para>When you create RDF statements with assertions or work with in-memory
 1830: datasources, it is often difficult to remember the shape of the
 1831: graph, which statements exist about which resources, or which objects
 1832: are attached to which subjects. These
 1833: "getter" methods can help you
 1834: verify the shape of your graph.
 1835: </para>
 1836: 
 1837: </sect3>
 1838: </sect2>
 1839: <sect2 role="" id="mozilla-CHP-10-SECT-3.6" label="10.3.6">
 1840: <title>nsIRDFRemoteDataSource</title>
 1841: 
 1842: <para>The<indexterm id="IXT-10-1000"><primary>nsIRDFRemoteDataSource
 1843: interface</primary></indexterm><indexterm id="IXT-10-1001"><primary>RDF (Resource
 1844: Description
 1845: Framework)</primary><secondary>interfaces</secondary><tertiary>nsIRDFRemoteDataSource</tertiary></indexterm><indexterm id="IXT-10-1002"><primary>interfaces</primary><secondary>RDF</secondary><tertiary>nsIRDFRemoteDataSource</tertiary></indexterm>
 1846: <link linkend="mozilla-CHP-10-SECT-3.3">Section 10.3.3</link> section (earlier in
 1847: this chapter) showed how to load a datasource from a remote server
 1848: simply. If you want control over that datasource, you can manage it
 1849: by using the <emphasis>nsIRDFRemoteDatasource</emphasis> to set up a
 1850: remote datasource:
 1851: </para>
 1852: 
 1853: <programlisting>xml = '@mozilla.org/rdf/datasource;1?name=xml-datasource';
 1854: datasource = Components.classes[xml].
 1855:              createInstance(Components.interfaces.nsIRDFRemoteDataSource);
 1856: datasource.Init('http://books.mozdev.org/file.rdf');
 1857: datasource.Refresh(false);</programlisting>
 1858: 
 1859: <para>In this example, the <literal>Init</literal> and
 1860: <literal>Refresh</literal> methods control the datasource on the
 1861: server. In addition to these methods, you can call the
 1862: <literal>Flush</literal> method to flush the data
 1863: that's been changed and reload, or you can check
 1864: whether the datasource is loaded by using the
 1865: <literal>loaded</literal> property:
 1866: </para>
 1867: 
 1868: <programlisting>if (datasource.loaded) {
 1869:   // Do something
 1870: }</programlisting>
 1871: 
 1872: <para>Built-in datasources that implement
 1873: <emphasis>nsIRDFRemoteDataSource</emphasis> (and other necessary
 1874: interfaces) and do their own data handling include:
 1875: </para>
 1876: 
 1877: <programlisting>@mozilla.org/rdf/datasource;1?name=history 
 1878: @mozilla.org/browser/bookmarks-service;1 
 1879: @mozilla.org/autocompleteSession;1?type=history 
 1880: @mozilla.org/browser/global-history;1 
 1881: @mozilla.org/rdf/datasource;1?name=bookmarks</programlisting>
 1882: 
 1883: </sect2>
 1884: <sect2 role="" id="mozilla-CHP-10-SECT-3.7" label="10.3.7">
 1885: <title>nsIRDFPurgeableDataSource</title>
 1886: 
 1887: <para>Using <indexterm id="IXT-10-1003"><primary>nsIRDFPurgeableDataSource
 1888: interface</primary></indexterm><indexterm id="IXT-10-1004"><primary>RDF (Resource
 1889: Description
 1890: Framework)</primary><secondary>interfaces</secondary><tertiary>nsIRDFPurgeableDataSource</tertiary></indexterm><indexterm id="IXT-10-1005"><primary>interfaces</primary><secondary>RDF</secondary><tertiary>nsIRDFPurgeableDataSource</tertiary></indexterm>the
 1891: <emphasis>nsIRDFPurgeableDatasource</emphasis> interface allows you
 1892: to delete a whole section of an existing in-memory datasource in one
 1893: fell swoop. This means that all relatives -- all statements
 1894: derived from that node -- are removed. When you work with large
 1895: in-memory datasources (such as email systems), the using interface
 1896: can manipulate the data efficiently. The <literal>Sweep( )</literal>
 1897: method can delete a section that is marked in the datasource.
 1898: </para>
 1899: 
 1900: <programlisting>datasource.
 1901:    QueryInterface(Components.interfaces.nsIRDFPurgeableDataSource);
 1902: rootSubject = RDF.GetResource('urn:root');
 1903: predicate = RDF.GetResource('http://books.mozdev.org/rdf#chapters');
 1904: object = RDF.GetResource('Chapter1');
 1905: datasource.Mark(rootSubject,predicate,object,true);
 1906: datasource.Sweep( );</programlisting>
 1907: 
 1908: <para>In this instance, a statement about a chapter in a book is marked and
 1909: then removed from the datasource. You can also mark more than one
 1910: node before sweeping.
 1911: </para>
 1912: 
 1913: </sect2>
 1914: <sect2 role="" id="mozilla-CHP-10-SECT-3.8" label="10.3.8">
 1915: <title>nsIRDFNode, nsIRDFResource, and nsIRDFLiteral</title>
 1916: 
 1917: <para>These types of objects come from only a few different places. Here
 1918: are all the functions that can return the resource of a literal:
 1919: </para>
 1920: 
 1921: <programlisting>nsIRDFService.GetResource
 1922: nsIRDFService.GetAnonymousResource
 1923: nsIRDFService.GetLiteral
 1924: nsIRDFDataSource.GetSource
 1925: nsIRDFDataSource.GetTarget</programlisting>
 1926: 
 1927: <para><emphasis>nsIRDFNode</emphasis><indexterm id="IXT-10-1006"><primary>nsIRDFNode
 1928: interface</primary></indexterm><indexterm id="IXT-10-1007"><primary>RDF (Resource
 1929: Description
 1930: Framework)</primary><secondary>interfaces</secondary><tertiary>nsIRDFNode</tertiary></indexterm><indexterm id="IXT-10-1008"><primary>interfaces</primary><secondary>RDF</secondary><tertiary>nsIRDFNode</tertiary></indexterm>
 1931: is the parent of <emphasis>nsIRDFResource</emphasis> and
 1932: <emphasis>nsIRDFLiteral</emphasis>. It is not used often because
 1933: it's sole function is to test equality:
 1934: </para>
 1935: 
 1936: <programlisting>isEqual = resource1.EqualsNode(resource2);</programlisting>
 1937: 
 1938: <para>The other two interfaces inherit this function automatically.
 1939: <literal>EqualsNode</literal> tests the equivalency of two resources,
 1940: which can be useful when you try to put together different statements
 1941: (e.g., "Eric wrote a book" and
 1942: "[This] book is about XML") and
 1943: want to verify that a resource like
 1944: "book" is the same in both cases.
 1945: </para>
 1946: 
 1947: <sect3 role="" id="mozilla-CHP-10-SECT-3.8.1" label="10.3.8.1">
 1948: <title>nsIRDFResource</title>
 1949: 
 1950: <para>Like<indexterm id="IXT-10-1009"><primary>nsIRDFResource
 1951: interface</primary></indexterm><indexterm id="IXT-10-1010"><primary>RDF (Resource
 1952: Description
 1953: Framework)</primary><secondary>interfaces</secondary><tertiary>nsIRDFResource</tertiary></indexterm><indexterm id="IXT-10-1011"><primary>interfaces</primary><secondary>RDF</secondary><tertiary>nsIRDFResource</tertiary></indexterm>
 1954: <emphasis>nsIRDFNode</emphasis>, <emphasis>nsIRDFResource</emphasis>
 1955: is a minimalist interface. Here are the functions and the property
 1956: available in a resource from the <emphasis>nsIRDFResource</emphasis>
 1957: interface:
 1958: </para>
 1959: 
 1960: <programlisting>resource = RDF.GetAnonymousResource( );
 1961: // get the resource value, something like 'rdf:#$44RG7'
 1962: resourceIdentifierString = resource.Value; 
 1963: // compare the resource to an identifier
 1964: isTrue = resourceEqualsString(resourceIdentifierString);
 1965: // Give the resource a real name.
 1966: resource.Init('Eric');</programlisting>
 1967: 
 1968: </sect3>
 1969: 
 1970: <sect3 role="" id="mozilla-CHP-10-SECT-3.8.2" label="10.3.8.2">
 1971: <title>nsIRDFLiteral</title>
 1972: 
 1973: <para>A literal's <indexterm id="IXT-10-1012"><primary>nsIRDFLiteral
 1974: interface</primary></indexterm><indexterm id="IXT-10-1013"><primary>RDF (Resource
 1975: Description
 1976: Framework)</primary><secondary>interfaces</secondary><tertiary>nsIRDFLiteral</tertiary></indexterm><indexterm id="IXT-10-1014"><primary>interfaces</primary><secondary>RDF</secondary><tertiary>nsIRDFLiteral</tertiary></indexterm>value
 1977: can be read but not written. To change the value of a literal, make a
 1978: new literal and set it properly:
 1979: </para>
 1980: 
 1981: <programlisting>aValue = literal.Value;</programlisting>
 1982: 
 1983: <para>Note that <literal>aValue</literal> could be a string or an integer
 1984: in this case. The base type conversion, based on the
 1985: data's format, is done automatically.
 1986: </para>
 1987: 
 1988: </sect3>
 1989: </sect2>
 1990: <sect2 role="" id="mozilla-CHP-10-SECT-3.9" label="10.3.9">
 1991: <title>nsIRDFContainerUtils</title>
 1992: 
 1993: <para>This interface<indexterm id="IXT-10-1015"><primary>nsIRDFContainerUtils
 1994: interface</primary></indexterm><indexterm id="IXT-10-1016"><primary>RDF (Resource
 1995: Description
 1996: Framework)</primary><secondary>interfaces</secondary><tertiary>nsIRDFContainerUtils</tertiary></indexterm><indexterm id="IXT-10-1017"><primary>interfaces</primary><secondary>RDF</secondary><tertiary>nsIRDFContainerUtils</tertiary></indexterm>
 1997: facilitates the creation of containers and provides other
 1998: container-related functions. It provides functions that make and work
 1999: with a <literal>sequence</literal>, <literal>bag</literal>, and
 2000: <literal>alternative</literal>. (The functions work the same way for
 2001: all types of containers, so only <literal>sequence</literal> is
 2002: covered here.) To create an instance of
 2003: <emphasis>nsIRDFContainerUtils</emphasis>, use the following:
 2004: </para>
 2005: 
 2006: <programlisting>containerUtils = Components.classes['@mozilla.org/rdf/container-utils;1']. 
 2007:                                  getService(Components.interfaces.nsIRDFContainerUtils);</programlisting>
 2008: 
 2009: <para>Once you create an anonymous resource, you can create a sequence from
 2010: it. Then you can test the type of the container and see whether
 2011: it's empty:
 2012: </para>
 2013: 
 2014: <programlisting>// create an anonymous resource
 2015: anonResource = RDF.GetAnonymousResource( );
 2016: // create a sequence from that resource
 2017: aSequence = containerUtils.MakeSeq(datasource,anonResource);
 2018: // test the resource
 2019: // (all of these are true)
 2020: isContainer = containerUtils.isContainer(datasource,anonResource);
 2021: isSequence = containerUtils.isSequence(datasource,anonResource);
 2022: isEmpty = containerUtils.isEmpty(datasource,anonResource);</programlisting>
 2023: 
 2024: <para>Note that the sequence object is not passed into the functions
 2025: performing the test in the previous example; the resource containing
 2026: the sequence is passed in. Although <literal>aSequence</literal> and
 2027: <literal>anonResource</literal> are basically the same resource,
 2028: their data types are different. <literal>isContainer</literal>,
 2029: <literal>isSequence</literal>, and <literal>isEmpty</literal> can be
 2030: used more easily with other RDF functions when a resource is used as
 2031: a parameter:
 2032: </para>
 2033: 
 2034: <programlisting>object = datasource.GetTarget(subject,predicate,true);
 2035: if(RDF.isAnonymousResource(object))
 2036: {
 2037:   isSeq = containerUtils.IsSeq(datasource,object);
 2038: }</programlisting>
 2039: 
 2040: <para>The RDF container utilities also provide an indexing function.
 2041: <literal>indexOf</literal> is useful for checking if an element
 2042: exists in a container resource:
 2043: </para>
 2044: 
 2045: <programlisting>indexNumber = 
 2046:    containerUtils.indexOf(datasource,object,RDF.GetLiteral('Eric'));
 2047: if(index != -1)
 2048:    alert('Eric exists in this container');</programlisting>
 2049: 
 2050: </sect2>
 2051: <sect2 role="" id="mozilla-CHP-10-SECT-3.10" label="10.3.10">
 2052: <title>nsIRDFContainer</title>
 2053: 
 2054: <para>This interface <indexterm id="IXT-10-1018"><primary>nsIRDFContainer
 2055: interface</primary></indexterm><indexterm id="IXT-10-1019"><primary>RDF (Resource
 2056: Description
 2057: Framework)</primary><secondary>interfaces</secondary><tertiary>nsIRDFContainer</tertiary></indexterm><indexterm id="IXT-10-1020"><primary>interfaces</primary><secondary>RDF</secondary><tertiary>nsIRDFContainer</tertiary></indexterm>provides
 2058: vector-like access to an RDF container's
 2059: elements.<footnote label="1"> <para>A vector, for those who
 2060: don't know, is a flexible and more accessible
 2061: version of the array data structure.</para> </footnote> The
 2062: <emphasis>nsIRDFContainer</emphasis> interface allows you to add,
 2063: look up, and remove elements from a container once you create it.
 2064: </para>
 2065: 
 2066: <sect3 role="" id="mozilla-CHP-10-SECT-3.10.1" label="10.3.10.1">
 2067: <title>Adding an element to a container</title>
 2068: 
 2069: <para>You can add
 2070: an<indexterm id="IXT-10-1021"><primary>containers</primary><secondary>elements,
 2071: adding</secondary></indexterm><indexterm id="IXT-10-1022"><primary>elements</primary><secondary>containers,
 2072: adding to</secondary></indexterm> element to a container in two ways.
 2073: You can append it to the end of the list with
 2074: <literal>Append</literal> or insert it at a specific place in the
 2075: container:
 2076: </para>
 2077: 
 2078: <programlisting>newLiteral = RDF.GetLiteral('Ian');
 2079: aSequence.AppendElement(newLiteral);
 2080: // or
 2081: aSequence.InsertElementAt(newLiteral,3,true);</programlisting>
 2082: 
 2083: <para>The second attribute in <literal>InsertElementAt</literal> is where
 2084: the element should be placed. The third attribute specifies that the
 2085: list can be reordered. This method is useful for working with ordered
 2086: containers such as sequences. If this locking parameter is set to
 2087: false and an element already exists at that location, then the
 2088: existing element is overwritten.
 2089: </para>
 2090: 
 2091: </sect3>
 2092: 
 2093: <sect3 role="" id="mozilla-CHP-10-SECT-3.10.2" label="10.3.10.2">
 2094: <title>Removing an element from a container</title>
 2095: 
 2096: <para>Removing an element from a container works much the same as adding
 2097: one. The difference is that a reordering attribute is included on
 2098: <literal>RemoveElement</literal>. If this attribute is set to false,
 2099: you may have holes in the container, which can create problems when
 2100: enumerating or indexing elements within.
 2101: </para>
 2102: 
 2103: <programlisting>newLiteral = RDF.GetLiteral('Ian');
 2104: aSequence.RemoveElement(newLiteral,true);
 2105: // or
 2106: aSequence.RemoveElementAt(newLiteral,3,true);</programlisting>
 2107: 
 2108: <para>If you use the <literal>indexOf</literal> property of
 2109: <literal>nsIRDFContainer</literal>, you can also use
 2110: <literal>GetCount</literal> to learn how many elements are in the
 2111: container. The count starts at 0 when the container is initialized:
 2112: </para>
 2113: 
 2114: <programlisting>numberOfElements = aSequence.GetCount( );</programlisting>
 2115: 
 2116: <para>Once you have the sequence, the datasource and resource the sequence
 2117: resides in can be retrieved. In effect, these properties look outward
 2118: instead of toward the data:
 2119: </para>
 2120: 
 2121: <programlisting>seqDatasource = aSequence.DataSource;
 2122: seqResource = aSequence.Resource;</programlisting>
 2123: 
 2124: <para>Like many methods in the RDF interfaces, this one allows you to
 2125: traverse and retrieve any part of the RDF graph.
 2126: </para>
 2127: 
 2128: </sect3>
 2129: </sect2>
 2130: <sect2 role="" id="mozilla-CHP-10-SECT-3.11" label="10.3.11">
 2131: <title>nsIRDFXML Interfaces</title>
 2132: 
 2133: <para>The RDF/XML interfaces are covered only briefly here. Besides being
 2134: abstract and confusing, these interfaces require a lot of error
 2135: handling to work correctly. Fortunately, a library on mozdev.org
 2136: called <filename>JSLib</filename> handles RDF file access. The
 2137: <filename>JSLib</filename> XML library does the dirty work in a
 2138: friendly manner. See the section <link linkend="mozilla-CHP-10-SECT-5">Section 10.5</link>, later in this chapter, for
 2139: more information.
 2140: </para>
 2141: 
 2142: <sect3 role="" id="mozilla-CHP-10-SECT-3.11.1" label="10.3.11.1">
 2143: <title>nsIRDFXMLParser and nsIRDFXMLSink</title>
 2144: 
 2145: <para><emphasis>nsIRDFXML</emphasis> <indexterm id="IXT-10-1023"><primary>nsIRDFXMLParser
 2146: interface</primary></indexterm><indexterm id="IXT-10-1024"><primary>RDF (Resource
 2147: Description
 2148: Framework)</primary><secondary>interfaces</secondary><tertiary>nsIRDFXMLParser</tertiary></indexterm><indexterm id="IXT-10-1025"><primary>interfaces</primary><secondary>RDF</secondary><tertiary>nsIRDFXMLParser</tertiary></indexterm>is
 2149: the raw RDF/XML parser of Mozilla. Used by Mozilla, its main purpose
 2150: is to parse an RDF file
 2151: <indexterm id="IXT-10-1026"><primary>parsing</primary><secondary>RDF
 2152: files</secondary></indexterm>asynchronously as a stream listener.
 2153: Though this subject is beyond the scope of this book, the interface
 2154: provides something interesting and useful. The
 2155: <literal>parseString</literal> function allows you to feed
 2156: <emphasis>nsIRDFXMLParser</emphasis> a string and have it parse that
 2157: data as RDF and put it into a datasource, as <link linkend="mozilla-CHP-10-EX-9">Example 10-9</link> demonstrates.
 2158: </para>
 2159: 
 2160: <example id="mozilla-CHP-10-EX-9" label="10-9">
 2161: <title>Parse an RDF/XML string into a datasource </title>
 2162: <programlisting>RDF = Components.classes['@mozilla.org/rdf/rdf-service;1'].
 2163:         getService(Components.interfaces.nsIRDFService);
 2164: // Used to create a URI below
 2165: ios = Components.classes["@mozilla.org/network/io-service;1"].
 2166:       getService(Components.interfaces.nsIIOService);
 2167: xmlParser = '@mozilla.org/rdf/xml-parser;1';
 2168: parser = Components.classes[xmlParser].
 2169:          createInstance(Components.interfaces.nsIRDFXMLParser);
 2170: uri = ios.newURI("http://books.mozdev.org/rdf#", null);
 2171: // Entire RDF File stored in a string
 2172: rdfString = 
 2173:   '&lt;rdf:RDF xmlns:rdf=http://www.w3.org/1999/02/22-rdf-syntax-ns#' +
 2174:   'xmlns:b="http://books.mozdev.org/rdf#"&gt;' +
 2175:   '&lt;rdf:Description about="urn:root"&gt;' + // Rest of file ...
 2176: parser.parseString(datasource,uri,rdfString);
 2177: // Parsed string data now resides in the datasource</programlisting>
 2178: </example>
 2179: 
 2180: <para>The RDF/XML data that was in the string is a part of the datasource
 2181: and ready for use (just like any other RDF data in a datasource). The
 2182: <literal>uri</literal> acts as a base reference for the RDF in case
 2183: of relative links.
 2184: </para>
 2185: 
 2186: <para><emphasis>nsIRDFXMLParser</emphasis> uses
 2187: <emphasis>nsIRDFXMLSink</emphasis> <indexterm id="IXT-10-1027"><primary>nsIRDFXMLSink
 2188: interface</primary></indexterm><indexterm id="IXT-10-1028"><primary>RDF (Resource
 2189: Description
 2190: Framework)</primary><secondary>interfaces</secondary><tertiary>nsIRDFXMLSink</tertiary></indexterm><indexterm id="IXT-10-1029"><primary>interfaces</primary><secondary>RDF</secondary><tertiary>nsIRDFXMLsink</tertiary></indexterm>for
 2191: event <indexterm id="IXT-10-1030"><primary>event handling</primary><secondary>RDF
 2192: files</secondary></indexterm>handling. The interfaces are totally
 2193: separate, but behind the scenes, they work together with the incoming
 2194: data. <link linkend="mozilla-CHP-10-EX-10">Example 10-10</link> shows how a series of events is
 2195: created in an object and then used to handle parser events.
 2196: </para>
 2197: 
 2198: <example id="mozilla-CHP-10-EX-10" label="10-10">
 2199: <title>Setup nsIRDFXMLSink with event handlers </title>
 2200: <programlisting>var Observer = {
 2201:    onBeginLoad: function(aSink)
 2202:    {
 2203:      alert("Beginning to load the RDF/XML...");
 2204:    },
 2205:    onInterrupt: function(aSink) {},
 2206:    onResume: function(aSink) {},
 2207:    onEndLoad: function(aSink)
 2208:    {
 2209:      doneLoading( ); // A function that does something with the datasource
 2210:    },
 2211:   onError: function(aSink, aStatus, aErrorMsg)
 2212:   {
 2213:     alert("Error: " + aErrorMsg);
 2214:   }
 2215: };</programlisting>
 2216: </example>
 2217: 
 2218: <para>Once the event handlers are set up, you can use
 2219: <emphasis>nsIRDFXMLSink</emphasis>:
 2220: </para>
 2221: 
 2222: <programlisting>sink = datasource.QueryInterface(Components.interfaces.nsIRDFXMLSink);
 2223: sink.addXMLSinkObserver(observer);</programlisting>
 2224: 
 2225: <para>The events are then triggered automatically when the datasource is
 2226: loaded up with data, allowing you to create handlers that manipulate
 2227: the data as it appears.
 2228: </para>
 2229: 
 2230: </sect3>
 2231: 
 2232: <sect3 role="" id="mozilla-CHP-10-SECT-3.11.2" label="10.3.11.2">
 2233: <title>nsIRDFXMLSerializer and nsIRDFXMLSource</title>
 2234: 
 2235: <para>These two<indexterm id="IXT-10-1031"><primary>nsIRDFXMLSerializer
 2236: interface</primary></indexterm><indexterm id="IXT-10-1032"><primary>RDF (Resource
 2237: Description
 2238: Framework)</primary><secondary>interfaces</secondary><tertiary>nsIRDFXMLSerializer</tertiary></indexterm><indexterm id="IXT-10-1033"><primary>interfaces</primary><secondary>RDF</secondary><tertiary>nsIRDFXMLSerializer</tertiary></indexterm>
 2239: interfaces are meant to work together.
 2240: <emphasis>nsIRDFXMLSerializer</emphasis> lets you
 2241: <literal>init</literal> a datasource into the
 2242: <literal>xml-serializer</literal> module that outputs RDF. However,
 2243: <emphasis>nsIRDFXMLSource</emphasis><indexterm id="IXT-10-1034"><primary>nsIRDFXMLSource
 2244: interface</primary></indexterm><indexterm id="IXT-10-1035"><primary>RDF (Resource
 2245: Description
 2246: Framework)</primary><secondary>interfaces</secondary><tertiary>nsIRDFXMLSource</tertiary></indexterm><indexterm id="IXT-10-1036"><primary>interfaces</primary><secondary>RDF</secondary><tertiary>nsIRDFXMLSource</tertiary></indexterm>
 2247: actually contains the <literal>Serialize</literal> function.
 2248: Here's how to serialize a datasource into an alert:
 2249: </para>
 2250: 
 2251: <programlisting>serializer = '@mozilla.org/rdf/xml-serializer;1';
 2252: s = Components.classes[serializer].
 2253: createInstance(Components.interfaces.nsIRDFXMLSerializer);
 2254: s.init(datasource);
 2255: output = new Object( );
 2256: output.write = new function(buf,count)
 2257: {
 2258:   alert(buf); // Show the serialized syntax
 2259:   return count;
 2260: }
 2261:    s.QueryInterface(Components.interfaces.nsIRDFXMLSource).Serialize(output);</programlisting>
 2262: 
 2263: <para>As in the previous example with <emphasis>nsIRDFXMLParser</emphasis>,
 2264: <link linkend="mozilla-CHP-10-EX-10">Example 10-10</link> does not use RDF data from a file. The
 2265: serialized data is passed directly to an alert, which then displays
 2266: the generated RDF.
 2267: </para>
 2268: 
 2269: </sect3>
 2270: </sect2>
 2271: </sect1>
 2272: 
 2273: <sect1 role="" id="mozilla-CHP-10-SECT-4" label="10.4">
 2274: <title>Template Dynamics</title>
 2275: 
 2276: <para>Once you learn how to create templates and modify datasources, the
 2277: ultimate in template mastery is to apply datasources to a template
 2278: dynamically.
 2279: </para>
 2280: 
 2281: <para>This process is done through the <literal>database</literal> property
 2282: of a XUL element that contains a template. The object returned by
 2283: this property has only two methods, <literal>AddDataSource</literal>
 2284: and <literal>RemoveDataSource</literal>. A separate
 2285: <literal>builder.rebuild</literal> function is also available for
 2286: refreshing the template's display, but you probably
 2287: won't need it once the template automatically
 2288: updates itself. The addition and removal of a datasource to a
 2289: <literal>&lt;tree&gt;</literal> template is demonstrated here:
 2290: </para>
 2291: 
 2292: <programlisting>tree = document.getElementById('tree-template');
 2293: tree.database.AddDataSource(someDatasource);
 2294: // tree will now update its display to show contents
 2295: tree.database.RemoveDataSource(someDatasource);
 2296: // tree will now be empty
 2297: // Optional, use only when tree is not updating for some reason
 2298: tree.builder.rebuild( );</programlisting>
 2299: 
 2300: <para>You can add and remove any datasource as long as the template
 2301: actually matches the data inside it. Also, multiple datasources can
 2302: be applied to the same template with no problems, which allows you to
 2303: aggregate data from different places, such as contact data, work
 2304: information, and computer hardware information (e.g.,
 2305: "Eric uses a Compaq with the serial number
 2306: 1223456-1091 to write his book and he sits on the fourth floor of the
 2307: Acme Building, which is the Bay Area branch of Acme Enterprises.)
 2308: </para>
 2309: 
 2310: <sect2 role="" id="mozilla-CHP-10-SECT-4.1" label="10.4.1">
 2311: <title>Template Dynamics in XBL</title>
 2312: 
 2313: <para>Putting templates <indexterm id="IXT-10-1037"><primary>XBL (eXtensible Binding
 2314: Language)</primary><secondary>templates</secondary></indexterm><indexterm id="IXT-10-1038"><primary>templates</primary><secondary>XBL</secondary></indexterm><indexterm id="IXT-10-1039"><primary>datasources</primary><secondary>templates</secondary></indexterm>inside
 2315: XBL can be a useful organizational scheme. Here is a basic
 2316: implementation of a widget that creates a list of people based on
 2317: names listed in an attribute:
 2318: </para>
 2319: 
 2320: <programlisting>&lt;people names="Brian King,Eric Murphy,Ian Oeschger,Pete Collins,David Boswell"/&gt;</programlisting>
 2321: 
 2322: <para>Obviously, the comma is used as the delimiter for this list. The
 2323: constructor element in <link linkend="mozilla-CHP-10-EX-11">Example 10-11</link> uses JavaScript
 2324: to break up this string.
 2325: </para>
 2326: 
 2327: <example id="mozilla-CHP-10-EX-11" label="10-11">
 2328: <title>Binding with in-memory datasource and &lt;listbox&gt; template </title>
 2329: <programlisting>&lt;?xml version="1.0"?&gt;
 2330: &lt;bindings xmlns ="http://www.mozilla.org/xbl"      
 2331: xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"&gt;
 2332:   &lt;binding id="people"&gt;
 2333:     &lt;implementation&gt;
 2334:       &lt;constructor&gt;
 2335:       &lt;![CDATA[
 2336:         // Read the Names into an Array
 2337:         names = document.getAnonymousNodes(this)[0].getAttribute('names');
 2338:         names = new String(names);
 2339:         namesArray= names.split(',');
 2340:         // Initialize the RDF Service
 2341:         rdf = Components
 2342:              .classes['@mozilla.org/rdf/rdf-service;1']
 2343:              .getService(Components.interfaces.nsIRDFService);
 2344:         // Initialize a Datasource in Memory
 2345:              inMemory = '@mozilla.org/rdf/datasource;1?name=in-memory-datasource';
 2346:         datasource = Components.classes[inMemory].
 2347:            createInstance(Components.interfaces.nsIRDFDataSource);
 2348:         // Create the Root Node and an Anonymous Resource to Start With
 2349:         root   = rdf.GetResource('urn:root');
 2350:         people = rdf.GetAnonymousResource( );
 2351:         // Insert the People resource into the RDF graph
 2352:         datasource.Assert
 2353:           (root,
 2354:            rdf.GetResource('http://www.mozdev.org/rdf#people'),
 2355:            people,true);
 2356:         // Initialize Methods needed for Containers
 2357:         rdfc = Components
 2358:               .classes['@mozilla.org/rdf/container-utils;1']
 2359:               .getService(Components.interfaces.nsIRDFContainerUtils);
 2360:         // For the People resource, make a Sequence of people
 2361:         peopleSequence = rdfc.MakeSeq(datasource, people);
 2362:         for(i=0;i&lt;namesArray.length;i++)
 2363:         {
 2364:           // Create a Person, with a Unique Number, for example
 2365:           person = rdf.GetResource(i);
 2366:           // Insert the Person's name into the RDF graph underneath number
 2367:           datasource.Assert
 2368:             (person,
 2369:              rdf.GetResource('http://www.mozdev.org/rdf#name'),
 2370:              rdf.GetLiteral(namesArray[i]),true);
 2371:           peopleSequence.AppendElement(person);
 2372:         }
 2373:         list = document.getAnonymousNodes(this)[1];
 2374:         list.database.AddDataSource(datasource);
 2375:       ]]&gt;
 2376:       &lt;/constructor&gt;
 2377:     &lt;/implementation&gt;
 2378:     &lt;content&gt;
 2379:       &lt;xul:box id="names" inherits="names" flex="0"/&gt;
 2380:       &lt;xul:listbox datasources="rdf:null" ref="urn:root" flex="1"&gt;
 2381:         &lt;xul:template&gt;
 2382:           &lt;xul:rule&gt;
 2383:             &lt;xul:conditions&gt;
 2384:               &lt;xul:content uri="?uri"/&gt;
 2385:               &lt;xul:triple subject="?uri"
 2386:                        predicate="http://www.mozdev.org/rdf#people"     
 2387:                          object="?people"/&gt;
 2388:               &lt;xul:member container="?people" child="?person"/&gt;
 2389:               &lt;xul:triple subject="?person"
 2390:                        predicate="http://www.mozdev.org/rdf#name"
 2391:                          object="?name"/&gt;
 2392:             &lt;/xul:conditions&gt;
 2393:             &lt;xul:action&gt;
 2394:               &lt;xul:listitem uri="?person"&gt;
 2395:                 &lt;xul:listcell&gt;
 2396:                   &lt;xul:description value="?person "/&gt;
 2397:                   &lt;xul:description value="?name"/&gt;
 2398:                 &lt;/xul:listcell&gt;
 2399:               &lt;/xul:listitem&gt;
 2400:             &lt;/xul:action&gt;
 2401:           &lt;/xul:rule&gt;
 2402:         &lt;/xul:template&gt;
 2403:       &lt;/xul&gt;
 2404:     &lt;/content&gt;
 2405:   &lt;/binding&gt;
 2406: &lt;/bindings&gt;</programlisting>
 2407: </example>
 2408: 
 2409: <para>In <link linkend="mozilla-CHP-10-EX-11">Example 10-11</link>, everything you need to display a
 2410: datasource dynamically is present. The only difference between this
 2411: dynamically generated version and a static RDF-based template is the
 2412: <literal>datasources="rdf:null"</literal>, which specifies that the
 2413: template does not refer to an actual datasource. Data that is edited,
 2414: rearranged, or changed in a different way is often displayed
 2415: dynamically in the UI with templates in this manner.
 2416: </para>
 2417: 
 2418: </sect2>
 2419: </sect1>
 2420: 
 2421: <sect1 role="" id="mozilla-CHP-10-SECT-5" label="10.5">
 2422: <title>JSLib RDF Files</title>
 2423: 
 2424: <para>Working <indexterm class="startofrange" id="mozilla-IDXTERM-1410"><primary>RDF (Resource Description
 2425: Framework)</primary><secondary>files</secondary><tertiary>JSLib</tertiary></indexterm><indexterm class="startofrange" id="mozilla-IDXTERM-1411"><primary>JSLib
 2426: libraries</primary><secondary>RDF
 2427: files</secondary></indexterm><indexterm class="startofrange" id="mozilla-IDXTERM-1412"><primary>files</primary><secondary>RDF</secondary><tertiary>JSLib</tertiary></indexterm>with
 2428: actual RDF files is not easy. However, JSLib (<systemitem role="url">http://jslib.mozdev.org</systemitem>) provides an RDF file
 2429: library that can help you develop an RDF-based application. The
 2430: library provides many types of error checking, as well as a friendly
 2431: abstraction away from the RDF/XML interfaces of Mozilla (see <link linkend="mozilla-CHP-10-SECT-3.11">Section 10.3.11</link>, later in this chapter).
 2432: <link linkend="mozilla-CHP-10-EX-12">Example 10-12</link> shows some common uses of the
 2433: <literal>RDFFile</literal> class in JSLib. This functionality can be
 2434: used in situations in which you have data in RDF that you want to
 2435: pull out "manually" and use piece
 2436: by piece (rather than as a whole datasource in a template).
 2437: </para>
 2438: 
 2439: <example id="mozilla-CHP-10-EX-12" label="10-12">
 2440: <title>Creating and modifying an RDF file using JSLib </title>
 2441: <programlisting>var rdfFileURL = 'chrome://jarfly/content/jar.rdf';
 2442: var gTreeBody = null;
 2443: var gListbox = null;
 2444: var gRDF = null;
 2445: function onload( )
 2446: {
 2447:   fileUtils = new FileUtils( );
 2448:   path = fileUtils.chrome_to_path(rdfFileURL);
 2449:   if(navigator.platform == "Win32") {
 2450:     path = path.replace(/\//g,"\\"); 
 2451:     // Only needed on Windows, until JSLib is fixed
 2452:   }
 2453:   gRDF = new RDFFile(path,'jar:flies','http://mozdev.org/fly-rdf#');
 2454:   gTreeBody = document.getElementById('tb');
 2455:   gTreeBody.database.AddDataSource(gRDF.dsource);
 2456:   gListbox  = document.getElementById('list');
 2457:   gListbox.database.AddDataSource(gRDF.dsource);
 2458:   rebuildLists( );
 2459: }
 2460: function rebuildLists( )
 2461: {
 2462:   gTreeBody.builder.rebuild( );
 2463:   gListbox.builder.rebuild( );
 2464: }
 2465: function update( )
 2466: {
 2467:   name      = document.getElementById('nameField').value;
 2468:   color     = document.getElementById('colorField').value;
 2469:   quantity  = document.getElementById('quantityField').value;
 2470:   seqNumber = -1;
 2471:   del       = false;
 2472:   replace   = false;
 2473:   if(document.getElementById('delete').checked)
 2474:     del = true;
 2475:   if(document.getElementById('replace').checked)
 2476:     replace = true;
 2477:   var seqLength = 0;
 2478:   if(gRDF.doesSeqExist('types'))
 2479:   {
 2480:     seqLength = gRDF.getSeqSubNodes('types').length;
 2481:     //if(del)gRDF.removeSeq('types',false);
 2482:   }
 2483:   else
 2484:     gRDF.addSeq('types');
 2485:   for(i=0;i&lt;seqLength;i++)
 2486:   {
 2487:     tempItem = 'types:_' + (i+1);
 2488:     if(gRDF.getAttribute(tempItem,'name')==name)
 2489:       seqNumber = gRDF.getAttribute(tempItem,'number');
 2490:   }
 2491:   if(seqNumber == -1)
 2492:   {
 2493:     item = 'types:_' + (seqLength+1);
 2494:     gRDF.setAttribute(item,'name',name);
 2495:     gRDF.setAttribute(item,'number',seqLength+1);
 2496:   }
 2497:   else
 2498:   {
 2499:     item = 'types:_' + seqNumber;
 2500:     gRDF.setAttribute(item,'number',seqNumber);
 2501:   }
 2502:   if(color!='')
 2503:     gRDF.setAttribute(item,'color',color);
 2504:   if(quantity!='')
 2505:   {
 2506:     gRDF.setAttribute(item,'quantity',quantity);
 2507:     gRDF.setAttribute(item,'dead',calcDead(quantity,replace));
 2508:   }
 2509:   if(!del)
 2510:     gRDF.addNode(item);
 2511:   else
 2512:     gRDF.removeNode(item);
 2513:   gRDF.flush( );
 2514:   onload( );
 2515: }
 2516: function calcDead(quantity,replace)
 2517: {
 2518:   if(!replace)
 2519:   {
 2520:     v = parseInt( (quantity * Math.random( )) * 0.13 );
 2521:     return (v.toString( ));
 2522:   }
 2523:   else
 2524:     return 0;
 2525: }
 2526: function changeC(color)
 2527: {
 2528:   document.getElementById('colorField').value=color;
 2529: }
 2530: function changeQ(quantity)
 2531: {
 2532:   document.getElementById('quantityField').value=quantity;
 2533: }</programlisting>
 2534: </example>
 2535: 
 2536: <para>This example contains a datasource that represents a collection of
 2537: flies. These flies are built up dynamically with JavaScript objects
 2538: from the RDF library, which represent the datasource itself
 2539: (<literal>gRDF = new RDFFile</literal>), methods that view and update
 2540: the data
 2541: (<literal>if(gRDF.getAttribute(tempItem,'name')==name</literal>), and
 2542: utilities that make work with RDF files easier (<literal>path =
 2543: fileUtils.chrome_to_path(rdfFileURL)</literal>).
 2544: </para>
 2545: 
 2546: <para><link linkend="mozilla-CHP-10-EX-13">Example 10-13</link> initializes and updates a file after it
 2547: changes.
 2548: </para>
 2549: 
 2550: <example id="mozilla-CHP-10-EX-13" label="10-13">
 2551: <title>Initialization </title>
 2552: <programlisting>var rdfFileURL = 'chrome://jarfly/content/jar.rdf';
 2553: var gTreeBody = null;
 2554: var gListbox = null;
 2555: var gRDF = null;
 2556: function onload( )
 2557: {
 2558:   fileUtils = new FileUtils( );
 2559:   path = fileUtils.chrome_to_path(rdfFileURL);
 2560:   if(navigator.platform == "Win32") {
 2561:     path = path.replace(/\//g,"\\"); 
 2562:     // Only needed on Windows, until JSLib is fixed
 2563:   }
 2564:   gRDF = new RDFFile(path,'jar:flies','http://mozdev.org/fly-rdf#');</programlisting>
 2565: </example>
 2566: 
 2567: <para>In <link linkend="mozilla-CHP-10-EX-13">Example 10-13</link>, the file URL is set to an RDF file
 2568: in the chrome area. Note that both a <literal>&lt;tree&gt;</literal>
 2569: and a <literal>&lt;listbox&gt;</literal>, which display the same data
 2570: in different ways, will be updated with the same datasource. The
 2571: <literal>onload</literal> function is called after the main XUL
 2572: document is loaded. A class called <literal>FileUtils</literal> is
 2573: initialized, which will create a path to the RDF file. If the file
 2574: doesn't already exist, JSLib automatically creates
 2575: it.
 2576: </para>
 2577: 
 2578: <para>Finally, the <literal>RDFFile</literal> is created by using the path
 2579: and a root resource identifier, and the
 2580: "xFly" namespace is used for the
 2581: data references. <link linkend="mozilla-CHP-10-EX-14">Example 10-14</link> shows that the RDF file
 2582: is ready to have its data added and deleted.
 2583: </para>
 2584: 
 2585: <example id="mozilla-CHP-10-EX-14" label="10-14">
 2586: <title>Data updating </title>
 2587: <programlisting>function update( )
 2588: {
 2589:   ...
 2590:   var seqLength = 0;
 2591:   if(gRDF.doesSeqExist('types'))
 2592:   {
 2593:     seqLength = gRDF.getSeqSubNodes('types').length;
 2594:   }
 2595:   else
 2596:     gRDF.addSeq('types');
 2597:   for(i=0;i&lt;seqLength;i++)
 2598:   {
 2599:     tempItem = 'types:_' + (i+1);
 2600:     if(gRDF.getAttribute(tempItem,'name')==name)
 2601:       seqNumber = gRDF.getAttribute(tempItem,'number');
 2602:   }
 2603:   if(seqNumber == -1)
 2604:   {
 2605:     item = 'types:_' + (seqLength+1);
 2606:     gRDF.setAttribute(item,'name',name);
 2607:     gRDF.setAttribute(item,'number',seqLength+1);
 2608:   }
 2609:   else
 2610:   {
 2611:     item = 'types:_' + seqNumber;
 2612:     gRDF.setAttribute(item,'number',seqNumber);
 2613:   }
 2614:   if(color!='')
 2615:     gRDF.setAttribute(item,'color',color);
 2616:   if(quantity!='')
 2617:   {
 2618:     gRDF.setAttribute(item,'quantity',quantity);
 2619:     gRDF.setAttribute(item,'dead',calcDead(quantity,replace));
 2620:   }
 2621:   if(!del)
 2622:     gRDF.addNode(item);
 2623:   else
 2624:     gRDF.removeNode(item);
 2625:   gRDF.flush( );
 2626:   onload( );</programlisting>
 2627: </example>
 2628: 
 2629: <para><link linkend="mozilla-CHP-10-EX-14">Example 10-14</link> contains a modified version of the
 2630: <literal>update</literal> function. First, the function checks to see
 2631: if a sequence called <literal>types</literal> is in the RDF file. If
 2632: not, it creates one. Next, it appends an item to the sequence using
 2633: <literal>type:_+(seqLength+1)</literal>. The same type of container
 2634: setup was described in the section <link linkend="mozilla-CHP-10-SECT-3.10">Section 10.3.10</link>, earlier in this chapter.
 2635: </para>
 2636: 
 2637: <para>The <literal>update</literal> function then adds the color, quantity,
 2638: and "dead" properties of that new
 2639: item in the sequence. Next, it ensures that you actually want to add
 2640: the item to the RDF file and flushes it out if not. It then recalls
 2641: the <literal>onload</literal> function to update the template
 2642: display.
 2643: </para>
 2644: 
 2645: <para>These are the basics of using <literal>RDFFile</literal>. As you can
 2646: see, using JSLib for RDF is often much easier than trying to
 2647: implement a similar setup on your own. More information about
 2648: <literal>RDFFile</literal> and the other JSLib libraries can
 2649: <indexterm id="IXT-10-1040"><primary>web
 2650: sites</primary><secondary>JSLib</secondary></indexterm>be<indexterm id="IXTR3-1046" class="endofrange" startref="mozilla-IDXTERM-1410"/><indexterm id="IXTR3-1047" class="endofrange" startref="mozilla-IDXTERM-1411"/><indexterm id="IXTR3-1048" class="endofrange" startref="mozilla-IDXTERM-1412"/> found at
 2651: <systemitem role="url">http://jslib.mozdev.org/</systemitem>.
 2652: </para>
 2653: 
 2654: </sect1>
 2655: 
 2656: <sect1 role="" id="mozilla-CHP-10-SECT-6" label="10.6">
 2657: <title>Manifests</title>
 2658: 
 2659: <para>The package <indexterm id="IXT-10-1041"><primary>RDF (Resource Description
 2660: Framework)</primary><secondary>manifest
 2661: files</secondary></indexterm><indexterm id="IXT-10-1042"><primary>manifests</primary><secondary>RDF</secondary></indexterm>descriptions,
 2662: generally called <emphasis>manifests</emphasis>, use RDF to describe
 2663: new packages and files to Mozilla. They can be added seamlessly
 2664: because RDF provides a platform-like environment that facilitates the
 2665: installation and use of new Mozilla software.
 2666: </para>
 2667: 
 2668: <para>All packages, including the ones that come preinstalled with Mozilla
 2669: (such as the browser, the MailNews component, and the en-US language
 2670: pack), have manifests describing them in terms of their relation to
 2671: other packages. The manifests are typically files called
 2672: <filename>contents.rdf</filename>, but they may also be called
 2673: <filename>manifest.rdf</filename>. <link linkend="mozilla-CHP-10-EX-15">Example 10-15</link>
 2674: presents a <filename>contents.rdf</filename> file that describes a
 2675: new skin for Mozilla.
 2676: </para>
 2677: 
 2678: <example id="mozilla-CHP-10-EX-15" label="10-15">
 2679: <title>Skin manifest </title>
 2680: <programlisting>&lt;?xml version="1.0"?&gt;
 2681: &lt;RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 2682:   xmlns:chrome="http://www.mozilla.org/rdf/chrome#"&gt;
 2683: &lt;!-- List all the skins being supplied by this theme --&gt;
 2684: &lt;RDF:Seq about="urn:mozilla:skin:root"&gt;
 2685:   &lt;RDF:li resource="urn:mozilla:skin:modern/1.0" /&gt;
 2686: &lt;/RDF:Seq&gt;
 2687: &lt;!-- Modern Information --&gt;
 2688: &lt;RDF:Description about="urn:mozilla:skin:modern/1.0"
 2689:   chrome:displayName="Modern"
 2690:   chrome:author="themes@mozilla.org"
 2691:   chrome:name="themes@mozilla.org/modern/1.0"&gt;
 2692: &lt;chrome:packages&gt;
 2693:   &lt;RDF:Seq about="urn:mozilla:skin:modern/1.0:packages"&gt;
 2694:     &lt;--RDF:li resource="urn:mozilla:skin:modern/1.0:aim"/ --&gt;
 2695:     &lt;RDF:li resource="urn:mozilla:skin:modern/1.0:communicator"/&gt;
 2696:     &lt;RDF:li resource="urn:mozilla:skin:modern/1.0:editor"/&gt;
 2697:     &lt;RDF:li resource="urn:mozilla:skin:modern/1.0:global"/&gt;
 2698:     &lt;RDF:li resource="urn:mozilla:skin:modern/1.0:messenger"/&gt;
 2699:     &lt;RDF:li resource="urn:mozilla:skin:modern/1.0:navigator"/&gt;
 2700:   &lt;/RDF:Seq&gt;
 2701: &lt;/chrome:packages&gt;
 2702: &lt;/RDF:Description&gt;
 2703: &lt;/RDF:RDF&gt;</programlisting>
 2704: </example>
 2705: 
 2706: <para>As you can see, the manifest is divided up into sections. After the
 2707: preamble, where the XML processing instruction and the namespace
 2708: declarations are made, an RDF sequence lists all the themes defined
 2709: or supplemented (since you can create a package updated for only one
 2710: Mozilla component, such as the browser) by this package. This section
 2711: contains only one <literal>RDF:li</literal> -- the modern theme.
 2712: </para>
 2713: 
 2714: <para>The next section gives more information on the theme, such as the
 2715: author, the theme name, and a description. The
 2716: <literal>chrome:packages</literal> structure that completes the
 2717: manifest describes the packages to which this theme should be
 2718: applied. All major components of the Netscape browser are listed in
 2719: this example -- including the AIM client that is not a part of
 2720: Mozilla -- but is skinned by themes such as Modern.
 2721: </para>
 2722: 
 2723: <sect2 role="" id="mozilla-CHP-10-SECT-6.1" label="10.6.1">
 2724: <title>RDF and Dynamic Overlays</title>
 2725: 
 2726: <para>Manifests can<indexterm id="IXT-10-1043"><primary>dynamic
 2727: overlays</primary><secondary>RDF</secondary></indexterm><indexterm id="IXT-10-1044"><primary>overlays</primary><secondary>RDF</secondary></indexterm><indexterm id="IXT-10-1045"><primary>RDF
 2728: (Resource Description Framework)</primary><secondary>manifest
 2729: files</secondary><tertiary>dynamic overalys
 2730: and</tertiary></indexterm><indexterm id="IXT-10-1046"><primary>manifests</primary><secondary>RDF</secondary><tertiary>dynamic
 2731: overlays and</tertiary></indexterm> also add new menu items to
 2732: existing Mozilla menus. When you add a new package to Mozilla, you
 2733: should make it accessible from within the browser application, where
 2734: users can access it easily. This is where RDF and dynamic overlays
 2735: come in.
 2736: </para>
 2737: 
 2738: <para>The RDF you provide in your package makes it possible for the chrome
 2739: registry, discussed in <link linkend="mozilla-CHP-6">Chapter 6</link>, to find,
 2740: understand, and register your new files. Packages must be registered
 2741: if they are to be skinned, localized, or accessed using the special
 2742: tools Mozilla provides (e.g., the chrome URL or XPConnect to the
 2743: XPCOM libraries). If you do not register your package by providing
 2744: the necessary RDF manifests, it cannot be accessed except as a
 2745: disparate collection of files in the browser's main
 2746: content window, which is not what you want.
 2747: </para>
 2748: 
 2749: <para>You can add overlays in Mozilla in two ways: import them explicitly
 2750: by using an overlay processing instruction at the top of the XUL file
 2751: into which items in the overlay file are to be
 2752: "composed," or use RDF to register
 2753: and load overlay files at runtime. This latter method will be used
 2754: here to add an "xFly" item to the
 2755: Tools menu of the Mozilla suite of applications.
 2756: </para>
 2757: 
 2758: <para><link linkend="mozilla-CHP-10-EX-16">Example 10-16</link> shows the
 2759: <filename>contents.rdf</filename> manifest format that alerts Mozilla
 2760: of the presence of an overlay, its target in the Mozilla application,
 2761: and the package of which it is a part.
 2762: </para>
 2763: 
 2764: <example id="mozilla-CHP-10-EX-16" label="10-16">
 2765: <title>Overlay for a sample application menu </title>
 2766: <programlisting>&lt;?xml version="1.0"?&gt;
 2767: &lt;RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 2768:          xmlns:chrome="http://www.mozilla.org/rdf/chrome#"&gt;
 2769:   &lt;RDF:Seq about="urn:mozilla:package:root"&gt;
 2770:     &lt;RDF:li resource="urn:mozilla:package:help"/&gt;
 2771:   &lt;/RDF:Seq&gt;
 2772:   &lt;RDF:Description about="urn:mozilla:package:help"
 2773:         chrome:displayName="xFly Application"
 2774:         chrome:author="xfly.mozdev.org"
 2775:         chrome:name="xfly"&gt;
 2776:   &lt;/RDF:Description&gt; 
 2777:   &lt;!-- Declare overlay points used in this package --&gt;
 2778:   &lt;RDF:Seq about="urn:mozilla:overlays"&gt;
 2779:     &lt;RDF:li resource="chrome://communicator/content/tasksOverlay.xul" /&gt;
 2780:   &lt;/RDF:Seq&gt;
 2781:   <emphasis role="bold">&lt;RDF:Seq about="chrome://communicator/content/tasksOverlay.xul"&gt;</emphasis>
 2782:     <emphasis role="bold">&lt;RDF:li&gt;chrome://xfly/content/xflyOverlay.xul&lt;/RDF:li&gt;</emphasis>
 2783:   <emphasis role="bold">&lt;/RDF:Seq&gt;</emphasis>
 2784: &lt;/RDF:RDF&gt;</programlisting>
 2785: </example>
 2786: 
 2787: <para>The manifest in <link linkend="mozilla-CHP-10-EX-16">Example 10-16</link> names the file
 2788: <filename>xflyOverlay.xul</filename> as an overlay. Then it names
 2789: <filename>tasksOverlay.xul</filename> as the base file into which the
 2790: contents are placed. In this case, the overlays can overlay other
 2791: overlay files arbitrarily. An overlay can define new content anywhere
 2792: in the application. Overlays are often responsible for putting new
 2793: items in menus. As long as the target and overlay
 2794: <literal>id</literal>s match, any two RDF datasources are merged. You
 2795: can try this example by putting a single new menu item in an overlay
 2796: structure like the one shown in <link linkend="mozilla-CHP-10-EX-17">Example 10-17</link>. Save it
 2797: as <emphasis>xflyOverlay.xul</emphasis> in the
 2798: <emphasis>xfly</emphasis> content subdirectory and use the manifest
 2799: information in <link linkend="mozilla-CHP-10-EX-16">Example 10-16</link> as part of the packaging
 2800: process described in <link linkend="mozilla-CHP-6">Chapter 6</link>.
 2801: </para>
 2802: 
 2803: <example id="mozilla-CHP-10-EX-17" label="10-17">
 2804: <title>Overlay for an xFly menu item in the browser </title>
 2805: <programlisting>&lt;?xml version="1.0"?&gt;
 2806: &lt;overlay id="xflyMenuID"
 2807:         xmlns:html="http://www.w3.org/1999/xhtml"
 2808:         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"&gt;
 2809:   
 2810:   &lt;menupopup id="tools_menu"&gt;
 2811:     &lt;menuitem label="xfly xml editor" 
 2812:         oncommand="toOpenWindowByType('mozilla:xfly, 'chrome://xfly/content/');" /&gt;
 2813:   
 2814: &lt;/menupopup&gt;
 2815:   
 2816: &lt;/overlay&gt;</programlisting>
 2817: </example>
 2818: 
 2819: <para>The <literal>menupopup</literal> in Mozilla with the ID
 2820: "tools_menu" gets a new menu item
 2821: when this overlay is processed and its content included.
 2822: </para>
 2823: 
 2824: 
 2825: 
 2826: </sect2>
 2827: </sect1>
 2828: </chapter>

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>