Annotation of books/www/chapters/ch10.html, revision 1.12

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

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