File:  [mozdev] / books / www / chapters / ch10.html
Revision 1.18: download - view: text, annotated - select for diffs - revision graph
Fri Apr 4 16:27:40 2003 UTC (17 years, 2 months ago) by cdn
Branches: MAIN
CVS tags: HEAD
ahem

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

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