[dna-commits] DNA SVN: r505 - in trunk/docs/gettingstarted/src/main/docbook/en-US: content and 1 other directories.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Fri Sep 5 16:01:50 EDT 2008


Author: rhauch
Date: 2008-09-05 16:01:49 -0400 (Fri, 05 Sep 2008)
New Revision: 505

Added:
   trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_for_sequencing.xml
   trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_repositories.xml
   trunk/docs/gettingstarted/src/main/docbook/en-US/images/example-sequencer-client.png
Removed:
   trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna.xml
   trunk/docs/gettingstarted/src/main/docbook/en-US/images/example-sequencer-cli-client.png
Modified:
   trunk/docs/gettingstarted/src/main/docbook/en-US/content/downloading_and_running.xml
   trunk/docs/gettingstarted/src/main/docbook/en-US/master.xml
Log:
DNA-214 Update documentation to describe the repository, federation, JCR and other 0.2 features
https://jira.jboss.org/jira/browse/DNA-214

Changed the Getting Started document to add the new repository example.

Modified: trunk/docs/gettingstarted/src/main/docbook/en-US/content/downloading_and_running.xml
===================================================================
--- trunk/docs/gettingstarted/src/main/docbook/en-US/content/downloading_and_running.xml	2008-09-05 19:59:46 UTC (rev 504)
+++ trunk/docs/gettingstarted/src/main/docbook/en-US/content/downloading_and_running.xml	2008-09-05 20:01:49 UTC (rev 505)
@@ -24,7 +24,7 @@
   -->
 <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
 <chapter id="downloading_and_running">
-	<title>Running the example application</title>
+	<title>Running the example applications</title>
 	<para>
     This chapter provides instructions for downloading and running a sample application that demonstrates how JBoss DNA works
     with a JCR repository to automatically sequence changing content to extract useful information. So read on to get the simple
@@ -105,9 +105,17 @@
                             /resources
                        /test/java
                             /resources
+         repository/pom.xml
+                   /src/main/assembly
+                            /config
+                            /java
+                            /resources
+                       /test/java
+                            /resources
 ]]></programlisting>
-		<para>There are essentially two Maven projects: a <code>sequencers</code> project and a parent project.  All of the source
-      for the example is located in the <code>sequencers</code> subdirectory.  And you may have noticed that none
+		<para>There are essentially three Maven projects: a <code>sequencers</code> project, a <code>repository</code> project, 
+		  and a parent project.  All of the source for the sequencing example is located in the <code>sequencers</code> subdirectory,
+		  while all of the source for the federation example is located in the <code>repository</code> subdirectory.  And you may have noticed that none
       of the JBoss DNA libraries are there.  This is where Maven comes in.  The two <code>pom.xml</code> files tell
       Maven everything it needs to know about what libraries are required and how to build the example.</para>
 		<para>In a terminal, go to the <code>examples</code> directory and run <emphasis role="strong"><code>mvn install</code></emphasis>.  
@@ -136,10 +144,11 @@
 		<para>If there are errors, check whether you have the correct version of Maven installed and that you've correctly updated
       your Maven settings as described above.</para>
 		<para>If you've successfully built the examples, there will be a new <code>examples/sequencers/target/</code> directory that contains
-			all of the generated output, including a <code>dna-example-sequencers-basic.dir/</code> subdirectory that contains the following:
+			all of the generated output for the sequencers example, including a <code>dna-example-sequencers-basic.dir/</code> subdirectory 
+			that contains the following:
 			<itemizedlist>
 				<listitem>
-					<para><emphasis role="strong"><code>run.sh</code></emphasis> is the *nix shell script that will run the example.</para>
+					<para><emphasis role="strong"><code>run.sh</code></emphasis> is the *nix shell script that will run the sequencer example application.</para>
 				</listitem>
 				<listitem>
 					<para><emphasis role="strong"><code>log4j.properties</code></emphasis>
@@ -167,26 +176,42 @@
 			      </para>
 				</listitem>
 				<listitem>
-					<para><emphasis role="strong"><code>lib</code></emphasis>
-			        subdirectory contains the JARs for all of the JBoss DNA artifacts as well as those for other libraries required
-			    by JBoss DNA and the example.
+					<para><emphasis role="strong"><code>lib</code></emphasis> subdirectory contains the JARs for all of the JBoss DNA artifacts 
+					  as well as those for other libraries required by JBoss DNA and the sequencer example.
 			      </para>
 				</listitem>
 			</itemizedlist>
-    </para>
+		</para>
     <note>
-			<para>JBoss DNA 0.1 and the examples are currently tested with <ulink url="http://jackrabbit.apache.org/">Apache Jackrabbit</ulink> version 1.3.3.  
-      	This version is stable and used by a number of other projects and applications.  However, you should be able to use a newer
-      	version of Jackrabbit, as long as that version uses the same JCR API.  For example, version 1.4.2 was released on March 26, 2008 and
-      	should be compatible.</para>
+			<para>JBoss DNA &versionNumber; and the sequencer example uses <ulink url="http://jackrabbit.apache.org/">Apache Jackrabbit</ulink> version 1.4.5.  
+      	This version is stable and used by a number of other projects and applications.  However, you should be able to use any
+      	version of Jackrabbit, as long as that version uses the same JCR API.</para>
 			<para>Just remember, if the version of Jackrabbit you want to use for these examples is not in the Maven repository,
       	you'll have to either add it or add it locally.  For more information, see the <ulink url="http://maven.apache.org/">Maven documentation</ulink>.
       </para>
 		</note>
+		<para>Similarly, the <code>examples/repository/target/</code> directory contains all of the generated output for the repository example, including
+			a <code>dna-example-repository-basic.dir/</code> subdirectory that contains the following:
+			<itemizedlist>
+				<listitem>
+					<para><emphasis role="strong"><code>run.sh</code></emphasis> is the *nix shell script that will run the repository example application.</para>
+				</listitem>
+				<listitem>
+					<para><emphasis role="strong"><code>log4j.properties</code></emphasis>
+			        is the Log4J configuration file.
+			      </para>
+				</listitem>
+				<listitem>
+					<para><emphasis role="strong"><code>lib</code></emphasis> subdirectory contains the JARs for all of the JBoss DNA artifacts
+					  as well as those for other libraries required by JBoss DNA and the repository example.
+			      </para>
+				</listitem>
+			</itemizedlist>
+    </para>
 	</sect1>
-	<sect1 id="running">
-		<title>Running the example</title>
-		<para>This example consists of a client application that sets up an in-memory JCR repository and that allows a user to
+	<sect1 id="running_sequencer_example">
+		<title>Running the sequencing example</title>
+		<para>The sequencing example consists of a client application that sets up an in-memory JCR repository and that allows a user to
       upload files into that repository. The client also sets up the DNA services with two sequencers so that if any of the
       uploaded files are PNG, JPEG, GIF, BMP or other images, DNA will automatically extract the image's metadata (e.g., image
       format, physical size, pixel density, etc.) and store that in the repository.  Alternatively, if the uploaded file 
@@ -196,8 +221,8 @@
       To run the client application, go to the <code>examples/sequencers/target/dna-example-sequencers-basic.dir/</code>
       directory and type <code>./run.sh</code>. You should see the command-line client and its menus in your terminal:
       <figure id="xample-sequencer-cli-client">
-				<title>Example Client</title>
-				<graphic align="center" scale="100" fileref="example-sequencer-cli-client.png"/>
+				<title>Example client</title>
+				<graphic align="center" scale="100" fileref="example-sequencer-client.png"/>
 			</figure>
       From this menu, you can upload a file into the repository, search for media in the repository, print sequencing statistics,
       or quit the application.</para>
@@ -207,7 +232,7 @@
       <code>examples/sequencers/target/dna-example-sequencers-basic.dir/</code> directory, you can specify any of the files 
 			in that directory without specifying the path:
       <figure id="example-sequencer-upload">
-				<title>Uploading an image using the Example Client</title>
+				<title>Uploading an image using the example client</title>
 				<graphic align="center" scale="100" fileref="example-sequencer-upload.png"/>
 			</figure>
       You can specify any fully-qualified or relative path. The application will notify you if it cannot find the file you
@@ -245,17 +270,17 @@
     	activities.</para>
 		<para>So, after the file is uploaded, you can search the repository for the image metadata using the "s" menu option:
     	<figure id="example-sequencer-search">
-				<title>Searching for media using the Example Client</title>
+				<title>Searching for media using the example client</title>
 				<graphic align="center" scale="100" fileref="example-sequencer-search.png"/>
 			</figure>
     	Here are the search results after the <code>sample1.mp3</code> audio file has been uploaded (to the <code>/a/b/sample1.mp3</code> location):
     	<figure id="example-sequencer-search-with-mp3">
-				<title>Searching for media using the Example Client</title>
+				<title>Searching for media using the example client</title>
 				<graphic align="center" scale="100" fileref="example-sequencer-search-with-mp3.png"/>
 			</figure>
     	You can also display the sequencing statistics using the "d" menu option:
     	<figure id="example-sequencer-statistics">
-				<title>Sequencing statistics using the Example Client</title>
+				<title>Sequencing statistics using the example client</title>
 				<graphic align="center" scale="100" fileref="example-sequencer-statistics.png"/>
 			</figure>
     	These stats show how many nodes were sequenced, and how many nodes were skipped because they didn't apply to the sequencer's
@@ -268,14 +293,52 @@
 		<para>You can repeat this process with other files. Any file that isn't an image or MP3 files (as recognized by the sequencing configurations
     	that we'll describe later) will not be sequenced.</para>
 	</sect1>
+	<sect1 id="running_repository_example">
+		<title>Running the repository example</title>
+		<para>The repository example consists of a client application that sets up several DNA repositories, including one that 
+			is a federation of several of the others, and then allows you to navigate those repositories.</para>
+		<para>
+      To run the client application, go to the <code>examples/repository/target/dna-example-repository-basic.dir/</code>
+      directory and type <code>./run.sh</code>. You should see the command-line client and its menus in your terminal:
+      <figure id="example-repository-client">
+				<title>Example Client</title>
+				<graphic align="center" scale="100" fileref="example-repository-client.png"/>
+			</figure>
+      From this menu, you can see the list of repositories, select one, and navigate through that repository in a manner similar
+      to a *nix command-line shell (although the client itself uses the JCR API to interact with the repositories).
+      Here are some of the commands you can use:</para>
+			<table frame='all'>
+				<title>Repository client commands to navigate a repository</title>
+				<tgroup cols='2' align='left' colsep='1' rowsep='1'>
+		      <colspec colname='c1' colwidth="1*"/>
+		      <colspec colname='c2' colwidth="1*"/>
+					<thead>
+						<row><entry>Command</entry><entry>Description</entry></row>
+					</thead>
+					<tbody>
+						<row><entry>pwd</entry><entry>Print the path of the current node (e.g., the "working directory")</entry></row>
+						<row><entry>ls [<emphasis>path</emphasis>]</entry><entry>List the children and properties of the node at the supplied path,
+						     where "<emphasis>path</emphasis>" can be any relative path or absolute path.  If "<emphasis>path</emphasis>" is not supplied,
+						     the current working node's path is used.</entry></row>
+						<row><entry>cd <emphasis>path</emphasis></entry><entry>Change to the specified node, where "<emphasis>path</emphasis>"
+						     can be any relative path or absolute path.  For example, "<code>cd alpha</code>" changes the current node to be a child named
+						     "<code>alpha</code>"; "<code>cd ..</code>" changes the current node to the parent node; "<code>cd /a/b</code>" changes 
+						     the current node to be the "<code>/a/b</code>" node.</entry></row>
+						<row><entry>exit</entry><entry>Exit this repository and return the list of repositories.</entry></row>
+					</tbody>
+				</tgroup>
+			</table>
+			<para>Try using the client to walk the different repositories.  And while this is a contrived application, it does demonstrate
+				the use of JBoss DNA to federate repositories and provide access through JCR.</para>
+  </sect1>
 	<sect1 id="downloading_and_running_review">
 		<title>Summarizing what we just did</title>
-		<para>In this chapter you downloaded and installed the example application and used it to upload files into a
-    	JCR repository.  JBoss DNA automatically sequenced the image and/or MP3 files you uploaded, extracted the metadata from the
-    	files, and stored that metadata inside the repository.  The application allowed you to see this metadata
-    	and the sequencing statistics.</para>
-		<para>This application was very simplistic.  In fact, running through the example probably only took you a minute or two.
-    	So while this application won't win any awards, it does show the basics of what JBoss DNA can do.</para>
+		<para>In this chapter you downloaded, installed, and built the example applications.  With the sequencer client, you could upload files into a
+    	JCR repository, while JBoss DNA automatically sequenced the image, MP3, or Java source files you uploaded, extracted the metadata from the
+    	files, and stored that metadata inside the repository.  The repository client allowed you to walk through multiple repositories,
+      including one whose content was federated from multiple other repositories.</para>
+		<para>These example applications were very simplistic.  In fact, running through the examples probably only took you a few minutes.
+    	So while these applications won't win any awards, they hopefully showed you the basics of what JBoss DNA can do.</para>
 		<para>In the <link linkend="using_dna">next chapter</link> we'll venture into the code to get an understanding
    		of how JBoss DNA actually works and how you can use it in your own applications.</para>
 	</sect1>

Deleted: trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna.xml
===================================================================
--- trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna.xml	2008-09-05 19:59:46 UTC (rev 504)
+++ trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna.xml	2008-09-05 20:01:49 UTC (rev 505)
@@ -1,485 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ JBoss, Home of Professional Open Source.
-  ~
-  ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
-  ~ indicated by the @author tags or express copyright attribution
-  ~ statements applied by the authors.  All third-party contributions are
-  ~ distributed under license by Red Hat Middleware LLC.
-  ~
-  ~ This copyrighted material is made available to anyone wishing to use, modify,
-  ~ copy, or redistribute it subject to the terms and conditions of the GNU
-  ~ Lesser General Public License, as published by the Free Software Foundation.
-  ~
-  ~ This program is distributed in the hope that it will be useful,
-  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
-  ~ for more details.
-  ~
-  ~ You should have received a copy of the GNU Lesser General Public License
-  ~ along with this distribution; if not, write to:
-  ~ Free Software Foundation, Inc.
-  ~ 51 Franklin Street, Fifth Floor
-  ~ Boston, MA  02110-1301  USA
-  -->
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="using_dna">
-	<title>Using JBoss DNA</title>
-	<para>As we've mentioned before, JBoss DNA is able to work with existing JCR repositories.  Your client applications
-  	make changes to the information in those repositories, and JBoss DNA automatically uses its sequencers to extract
-  	additional information from the uploaded files.</para>
-	<note>
-		<para>Configuring JBoss DNA sequencers is a bit more manual than is ideal. As you'll see, JBoss DNA uses dependency
-      injection to allow a great deal of flexibility in how it can be configured and customized. However, the next release will
-      provide a much easier mechanism for configuring not only the sequencer service but also the upcoming federation engine and
-      JCR implementation.</para>
-	</note>
-	<sect1 id="sequencing_service">
-		<title>Configuring the Sequencing Service</title>
-		<para>The JBoss DNA <emphasis>sequencing service</emphasis> is the component that manages the <emphasis>sequencers</emphasis>, 
-			reacting to changes in JCR repositories and then running the appropriate sequencers.
-      This involves processing the changes on a node, determining which (if any) sequencers should be run on that node,
-      and for each sequencer constructing the execution environment, calling the sequencer, and saving the information
-      generated by the sequencer.</para>
-		<para>To set up the sequencing service, an instance is created, and dependent components are injected into
-      the object.  This includes among other things:
-			<itemizedlist>
-				<listitem>
-					<para>An <emphasis>execution context</emphasis> that defines the context in which the service runs, including
-			        a factory for JCR sessions given names of the repository and workspace.  This factory must be configured,
-			        and is how JBoss DNA knows about your JCR repositories and how to connect to them.  More on this a bit later.</para>
-				</listitem>
-				<listitem>
-					<para>An optional <emphasis>factory for class loaders</emphasis> used to load sequencers.  If no factory is supplied,
-			        the service uses the current thread's context class loader (or if that is null, the class loader that loaded the
-			        sequencing service class).</para>
-				</listitem>
-				<listitem>
-					<para>An <code>java.util.concurrent.ExecutorService</code> used to execute the sequencing activites.  If none
-			        is supplied, a new single-threaded executor is created by calling <code>Executors.newSingleThreadExecutor()</code>.
-			        (This can easily be changed by subclassing and overriding the <code>SequencerService.createDefaultExecutorService()</code> method.)</para>
-				</listitem>
-				<listitem>
-					<para>Filters for sequencers and events.  By default, all sequencers are considered for "node added", "property added"
-			        and "property changed" events.</para>
-				</listitem>
-			</itemizedlist>
-    </para>
-		<para>As mentioned above, the <code>ExecutionContext</code> provides access to a <code>SessionFactory</code> that is used
-      by JBoss DNA to establish sessions to your JCR repositories.  Two implementations are available:
-			<itemizedlist>
-				<listitem>
-					<para>The <code>JndiSessionFactory</code> looks up JCR <code>Repository</code> instances in JNDI using
-			          names that are supplied when creating sessions.  This implementation also has methods to set the
-			          JCR <code>Credentials</code> for a given workspace name.</para>
-				</listitem>
-				<listitem>
-					<para>The <code>SimpleSessionFactory</code> has methods to register the JCR <code>Repository</code> instances
-			          with names, as well as methods to set the JCR <code>Credentials</code> for a given workspace name.</para>
-				</listitem>
-			</itemizedlist>
-      You can use the <code>SimpleExecutionContext</code> implementation of <code>ExecutionContext</code> and supply
-      a <code>SessionFactory</code> instance, or you can provide your own implementation.</para>
-		<para>Here's an example of how to instantiate and configure the SequencingService:</para>
-    <programlisting role="JAVA"><![CDATA[
-SimpleSessionFactory sessionFactory = new SimpleSessionFactory();
-sessionFactory.registerRepository("Main Repository", this.repository);
-Credentials credentials = new SimpleCredentials("jsmith", "secret".toCharArray());
-sessionFactory.registerCredentials("Main Repository/Workspace1", credentials);
-ExecutionContext executionContext = new SimpleExecutionContext(sessionFactory);
-
-// Create the sequencing service, passing in the execution context ...
-SequencingService sequencingService = new SequencingService();
-sequencingService.setExecutionContext(executionContext);
-  ]]></programlisting>
-		<para>After the sequencing service is created and configured, it must be started.  The SequencingService
-      has an <emphasis>administration object</emphasis> (that is an instance of <code>ServiceAdministrator</code>)
-      with <code>start()</code>, <code>pause()</code>, and <code>shutdown()</code> methods.  The latter method will 
-      close the queue for sequencing, but will allow sequencing operations already running to complete normally.
-      To wait until all sequencing operations have completed, simply call the <code>awaitTermination</code> method
-      and pass it the maximum amount of time you want to wait.</para>
-		<programlisting role="JAVA"><![CDATA[sequencingService.getAdministrator().start();
-]]></programlisting>
-		<para>The sequencing service must also be configured with the sequencers that it will use.  This is done using the
-      <code>addSequencer(SequencerConfig)</code> method and passing a <code>SequencerConfig</code> instance that
-      you create.  Here's an example:</para>
-    <programlisting role="JAVA"><![CDATA[
-String name = "Image Sequencer";
-String desc = "Sequences image files to extract the characteristics of the image";
-String classname = "org.jboss.dna.sequencer.images.ImageMetadataSequencer";
-String[] classpath = null; // Use the current classpath
-String[] pathExpressions = {"//(*.(jpg|jpeg|gif|bmp|pcx|png)[*])/jcr:content[@jcr:data] => /images/$1"};
-SequencerConfig imageSequencerConfig = new SequencerConfig(name, desc, classname, 
-                                                           classpath, pathExpressions);
-sequencingService.addSequencer(imageSequencerConfig);
-
-name = "Mp3 Sequencer";
-desc = "Sequences mp3 files to extract the id3 tags of the audio file";
-classname = "org.jboss.dna.sequencer.mp3.Mp3MetadataSequencer";
-String[] mp3PathExpressions = {"//(*.mp3[*])/jcr:content[@jcr:data] =&gt; /mp3s/$1"};
-SequencerConfig mp3SequencerConfig = new SequencerConfig(name, desc, classname, 
-                                                         classpath, mp3PathExpressions);
-sequencingService.addSequencer(mp3SequencerConfig);
-  ]]></programlisting>
-		<para>This code fragment is pretty self-explanatory, except for the <code>classpath</code> and <code>pathExpression</code> parameters.
-      The classpath parameter defines the classpath that is passed to the class loader factory mentioned above.
-      Our sequencer is on the classpath, so we can simply use <code>null</code> here.</para>
-		<para>The path expression is more complicated.  Sequencer path expressions are used by the sequencing service to
-      determine whether a particular changed node should be sequenced.  The expressions consist of two parts: a selection
-      criteria and an output expression:</para>
-    <programlisting><![CDATA[  inputPath => outputPath ]]></programlisting>
-		<para>The <emphasis>inputPath</emphasis> part defines an expression for the path that is to change and that should be sequenced.
-		  Input paths consist of '<code>/</code>' separated segments, where each segment represents a pattern for a single node's
-		  name (including the same-name-sibling indexes) and '<code>@</code>' signifies a property name.</para>
-		<para>Before getting into the details, let's look at some simple examples:</para>
-		<table frame='all'>
-			<title>Simple Input Path Examples</title>
-			<tgroup cols='2' align='left' colsep='1' rowsep='1'>
-	      <colspec colname='c1' colwidth="1*"/>
-	      <colspec colname='c2' colwidth="1*"/>
-				<thead>
-					<row>
-			  		<entry>Input Path</entry>
-			  		<entry>Description</entry>
-					</row>
-				</thead>
-				<tbody>
-					<row><entry>/a/b</entry><entry>Match node "<code>b</code>" that is a child of the top level node "<code>a</code>". Neither node
-					     may have any same-name-sibilings.</entry></row>
-					<row><entry>/a/*</entry><entry>Match any child node of the top level node "<code>a</code>".</entry></row>
-					<row><entry>/a/*.txt</entry><entry>Match any child node of the top level node "<code>a</code>" that also has a name ending in "<code>.txt</code>".</entry></row>
-					<row><entry>/a/*.txt</entry><entry>Match any child node of the top level node "<code>a</code>" that also has a name ending in "<code>.txt</code>".</entry></row>
-					<row><entry>/a/b at c</entry><entry>Match the property "<code>c</code>" of node "<code>/a/b</code>".</entry></row>
-					<row><entry>/a/b[2]</entry><entry>The second child named "<code>b</code>" below the top level node "<code>a</code>".</entry></row>
-					<row><entry>/a/b[2,3,4]</entry><entry>The second, third or fourth child named "<code>b</code>" below the top level node "<code>a</code>".</entry></row>
-					<row><entry>/a/b[*]</entry><entry>Any (and every) child named "<code>b</code>" below the top level node "<code>a</code>".</entry></row>
-					<row><entry>//a/b</entry><entry>Any node named "<code>b</code>" that exists below a node named "<code>a</code>", regardless 
-					     of where node "<code>a</code>" occurs.  Again, neither node may have any same-name-sibilings.</entry></row>
-				</tbody>
-			</tgroup>
-		</table>
-		<para>With these simple examples, you can probably discern the most important rules.  First, the '<code>*</code>' is a wildcard character
-		  that matches any character or sequence of characters in a node's name (or index if appearing in between square brackets), and
-		  can be used in conjunction with other characters (e.g., "<code>*.txt</code>").</para>
-		<para>Second, square brackets (i.e., '<code>[</code>' and '<code>]</code>') are used to match a node's same-name-sibiling index.
-		  You can put a single non-negative number or a comma-separated list of non-negative numbers.  Use '0' to match a node that has no
-		  same-name-sibilings, or any positive number to match the specific same-name-sibling.</para>
-		<para>Third, combining two delimiters (e.g., "<code>//</code>") matches any sequence of nodes, regardless of what their names are 
-		  or how many nodes.  Often used with other patterns to identify nodes at any level matching other patterns. 
-			Three or more sequential slash characters are treated as two.</para>
-		<para>Many input paths can be created using just these simple rules.  However, input paths can be more complicated.  Here are some
-			more examples:</para>
-			<table frame='all'>
-				<title>More Complex Input Path Examples</title>
-				<tgroup cols='2' align='left' colsep='1' rowsep='1'>
-		      <colspec colname='c1' colwidth="1*"/>
-		      <colspec colname='c2' colwidth="1*"/>
-					<thead>
-						<row>
-				  		<entry>Input Path</entry>
-				  		<entry>Description</entry>
-						</row>
-					</thead>
-					<tbody>
-						<row><entry>/a/(b|c|d)</entry><entry>Match children of the top level node "<code>a</code>" that are named "<code>a</code>", 
-								 "<code>b</code>" or "<code>c</code>". None of the nodes may have same-name-sibling indexes.</entry></row>
-						<row><entry>/a/b[c/d]</entry><entry>Match node "<code>b</code>" child of the top level node "<code>a</code>", when node
-						     "<code>b</code>" has a child named "<code>c</code>", and "<code>c</code>" has a child named "<code>d</code>".
-								 Node "<code>b</code>" is the selected node, while nodes "<code>b</code>" and "<code>b</code>" are used as criteria but are not
-								 selected.</entry></row>
-						<row><entry>/a(/(b|c|d|)/e)[f/g/@something]</entry><entry>Match node "<code>/a/b/e</code>", "<code>/a/c/e</code>", "<code>/a/d/e</code>",
-						     or "<code>/a/e</code>" when they also have a child "<code>f</code>" that itself has a child "<code>g</code>" with property
-						     "<code>something</code>". None of the nodes may have same-name-sibling indexes.</entry></row>
-					</tbody>
-				</tgroup>
-			</table>
-			<para>These examples show a few more advanced rules.  Parentheses (i.e., '<code>(</code>' and '<code>)</code>') can be used
-			  to define a set of options for names, as shown in the first and third rules.  Whatever part of the selected node's path
-			  appears between the parentheses is captured for use within the output path.  Thus, the first input path in the previous table
-			  would match node "<code>/a/b</code>", and "b" would be captured and could be used within the output path using "<code>$1</code>",
-			  where the number used in the output path identifies the parentheses.</para>
-			<para>Square brackets can also be used to specify criteria on a node's properties or children.  Whatever appears in between the square
-				brackets does not appear in the selected node.</para>
-		  <para>Let's go back to the previous code fragment and look at the first path expression:</para>
-		  <programlisting><![CDATA[  //(*.(jpg|jpeg|gif|bmp|pcx|png)[*])/jcr:content[@jcr:data] => /images/$1 ]]></programlisting>
-		  <para>This matches a node named "<code>jcr:content</code>" with property "<code>jcr:data</code>" but no siblings with the same name,
-		    and that is a child of a node whose name ends with "<code>.jpg</code>", "<code>.jpeg</code>", "<code>.gif</code>", "<code>.bmp</code>", "<code>.pcx</code>", 
-		    or  "<code>.png</code>" that may have any same-name-sibling index.  These nodes can appear at any level in the repository.
-			  Note how the input path capture the filename (the segment containing the file extension), including any same-name-sibling index.
-			  This filename is then used in the output path, which is where the sequenced content is placed.</para>
-			<para>Now that we've covered path expressions, let's get back to the <code>SequencingService</code>. 
-			  After the service is started, it is ready to start reacting to changes in the repository.  But it first
-	      must be wired to the repositories using a listener.  This is accomplished using the <code>ObservationService</code>
-	      described in the <link linkend="observation_service">next section</link>.</para>
-	</sect1>
-	<sect1 id="observation_service">
-		<title>Configuring the Observation Service</title>
-		<para>The JBoss DNA <code>ObservationService</code> is responsible for listening to one or more JCR repositories
-	    and multiplexing the events to its listeners.  Unlike JCR events, this framework embeds in the events the
-	    name of the repository and workspace that can be passed to a <code>SessionFactory</code> to obtain a session
-	    to the repository in which the change occurred.  This simple design makes it very easy for JBoss DNA to
-	    concurrently work with multiple JCR repositories.</para>
-		<para>Configuring an observation service is pretty easy, especially if you reuse the same <code>SessionFactory</code>
-	    supplied to the sequencing service.  Here's an example:</para>
-    <programlisting role="JAVA"><![CDATA[
-  this.observationService = new ObservationService(sessionFactory);
-  this.observationService.getAdministrator().start();
-  ]]></programlisting>
-		<note>
-			<para>Both <code>ObservationService</code> and <code>SequencingService</code> implement
-    		<code>AdministeredService</code>, which has a <code>ServiceAdministrator</code> used to start, pause, and shutdown the
-    		service.  In other words, the lifecycle of the services are managed in the same way.</para>
-		</note>
-		<para>After the observation service is started, listeners can be added.  The <code>SequencingService</code> implements the required
-    interface, and so it may be registered directly:</para>
-    <programlisting role="JAVA"><![CDATA[
-  observationService.addListener(sequencingService);
-  ]]></programlisting>
-		<para>Finally, the observation service must be wired to monitor one of your JCR repositories.  This is done with
-    	one of the <code>monitor(...)</code> methods:</para>
-    <programlisting role="JAVA"><![CDATA[
-  int eventTypes = Event.NODE_ADDED | Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED;
-  observationService.monitor("Main Repository/Workspace1", eventTypes);
-  ]]></programlisting>
-		<para>At this point, the observation service is listening to a JCR repository and forwarding the appropriate events
-    	to the sequencing service, which will asynchronously process the changes and sequence the information added to or changed in the repository.
-    </para>
-	</sect1>
-	<sect1 id="shutting_down">
-		<title>Shutting down JBoss DNA services</title>
-		<para>The JBoss DNA services are utilizing resources and threads that must be released before your application is ready to shut down.
-    	The safe way to do this is to simply obtain the <code>ServiceAdministrator</code> for each service (via the <code>getServiceAdministrator()</code> method)
-    	and call <code>shutdown()</code>.  As previously mentioned, the shutdown method will simply prevent new work from being processed
-    	and will not wait for existing work to be completed.  If you want to wait until the service completes all its work, you must wait
-    	until the service terminates.  Here's an example that shows how this is done:</para>
-    <programlisting role="JAVA"><![CDATA[
-// Shut down the service and wait until it's all shut down ...
-sequencingService.getAdministrator().shutdown();
-sequencingService.getAdministrator().awaitTermination(5, TimeUnit.SECONDS);
-
-// Shut down the observation service ...
-observationService.getAdministrator().shutdown();
-observationService.getAdministrator().awaitTermination(5, TimeUnit.SECONDS);
-  ]]></programlisting>
-		<para>At this point, we've covered how to configure and use the JBoss DNA services in your application.
-    	The next chapter goes back to the <link linkend="downloading_and_running">sample application</link> to show how all 
-			these pieces fit together.</para>
-	</sect1>
-	<sect1 id="example_application_review">
-		<title>Reviewing the example application</title>
-		<para>Recall that the example application consists of a client application that sets up an in-memory JCR repository and
-      that allows a user to upload files into that repository. The client also sets up the DNA services with an image sequencer so
-      that if any of the uploaded files are PNG, JPEG, GIF, BMP or other images, DNA will automatically extract the image's
-      metadata (e.g., image format, physical size, pixel density, etc.) and store that in the repository.  Or, if the client uploads
-      MP3 audio files, the title, author, album, year, and comment are extracted from the audio file and stored in the repository.</para>
-		<para>
-      The example is comprised of 3 classes and 1 interface, located in the <code>src/main/java</code> directory:</para>
-    <programlisting><![CDATA[
-  org/jboss/example/dna/sequencers/ConsoleInput.java
-                                  /MediaInfo.java
-                                  /SequencingClient.java
-                                  /UserInterface.java
-  ]]></programlisting>
-		<para><code>SequencingClient</code> is the class that contains the main application.  <code>MediaInfo</code> is a simple Java object 
-			that encapsulates metadata about a media file (as generated by the sequencer), and used by the client to
-      pass information to the <code>UserInterface</code>, which is an interface with methods that will be called at runtime to 
-			request data from the user.  <code>ConsoleInput</code> is an implementation of this that creates a text user interface, 
-			allowing the user to operate the client from the command-line.  We can easily create a graphical implementation of
-      <code>UserInterface</code> at a later date. We can also create a mock implementation for testing purposes that simulates 
-			a user entering data. This allows us to check the behavior of the client automatically using conventional JUnit test cases, 
-			as demonstrated by the code in the <code>src/test/java</code> directory:</para>
-    <programlisting><![CDATA[
-  org/jboss/example/dna/sequencers/SequencingClientTest.java
-                                  /MockUserInterface.java
-  ]]></programlisting>
-		<para>If we look at the <code>SequencingClient</code> code, there are a handful of methods that encapsulate the various activities.</para>
-		<note>
-			<para>To keep the code shown in this book as readable as possible, some of the comments and error handling have been removed.</para>
-		</note>
-		<para>The <code>startRepository()</code> method starts up an in-memory Jackrabbit JCR repository. The bulk of this method is simply 
-			gathering and passing the information required by Jackrabbit. Because Jackrabbit's <code>TransientRepository</code>
-      implementation shuts down after the last session is closed, the application maintains a session to ensure that the
-      repository remains open throughout the application's lifetime. And finally, the node type needed by the image sequencer is
-      registered with Jackrabbit.</para>
-		<programlisting role="JAVA"><![CDATA[
-public void startRepository() throws Exception {
-    if (this.repository == null) {
-        try {
-
-            // Load the Jackrabbit configuration ...
-            File configFile = new File(this.jackrabbitConfigPath);
-            String pathToConfig = configFile.getAbsolutePath();
-
-            // Find the directory where the Jackrabbit repository data will be stored ...
-            File workingDirectory = new File(this.workingDirectory);
-            String workingDirectoryPath = workingDirectory.getAbsolutePath();
-
-            // Get the Jackrabbit custom node definition (CND) file ...
-            URL cndFile = Thread.currentThread().getContextClassLoader().getResource("jackrabbitNodeTypes.cnd");
-
-            // Create the Jackrabbit repository instance and establish a session to keep the repository alive ...
-            this.repository = new TransientRepository(pathToConfig, workingDirectoryPath);
-            if (this.username != null) {
-                Credentials credentials = new SimpleCredentials(this.username, this.password);
-                this.keepAliveSession = this.repository.login(credentials, this.workspaceName);
-            } else {
-                this.keepAliveSession = this.repository.login();
-            }
-
-            try {
-                // Register the node types (only valid the first time) ...
-                Workspace workspace = this.keepAliveSession.getWorkspace();
-                JackrabbitNodeTypeManager mgr = (JackrabbitNodeTypeManager)workspace.getNodeTypeManager();
-                mgr.registerNodeTypes(cndFile.openStream(), JackrabbitNodeTypeManager.TEXT_X_JCR_CND);
-            } catch (RepositoryException e) {
-                if (!e.getMessage().contains("already exists")) throw e;
-            }
-
-        } catch (Exception e) {
-            this.repository = null;
-            this.keepAliveSession = null;
-            throw e;
-        }
-    }
-}
-  ]]></programlisting>
-		<para>As you can see, this method really has nothing to do with JBoss DNA, other than setting up a JCR repository that JBoss
-      DNA will use.</para>
-		<para>The <code>shutdownRepository()</code> method shuts down the Jackrabbit transient repository by closing the "keep-alive session". 
-			Again, this method really does nothing specifically with JBoss DNA, but is needed to manage the JCR repository that JBoss DNA uses.</para>
-    <programlisting role="JAVA"><![CDATA[
-public void shutdownRepository() throws Exception {
-    if (this.repository != null) {
-        try {
-            this.keepAliveSession.logout();
-        } finally {
-            this.repository = null;
-            this.keepAliveSession = null;
-        }
-    }
-}
-  ]]></programlisting>
-		<para>The <code>startDnaServices()</code> method first starts the JCR repository (if it was not already started), and proceeds 
-			to create and configure the <code>SequencingService</code> as described <link linkend="sequencing_service">earlier</link>.
-      This involes setting up the <code>SessionFactory</code> and <code>ExecutionContext</code>, creating the
-      <code>SequencingService</code> instance, and configuring the image sequencer. The method then continues by setting up the
-      <code>ObservationService</code> as described <link linkend="observation_service">earlier</link> and starting the service.</para>
-		<programlisting role="JAVA"><![CDATA[
-public void startDnaServices() throws Exception {
-    if (this.repository == null) this.startRepository();
-    if (this.sequencingService == null) {
-
-        SimpleSessionFactory sessionFactory = new SimpleSessionFactory();
-        sessionFactory.registerRepository(this.repositoryName, this.repository);
-        if (this.username != null) {
-            Credentials credentials = new SimpleCredentials(this.username, this.password);
-            sessionFactory.registerCredentials(this.repositoryName + "/" + this.workspaceName, credentials);
-        }
-        this.executionContext = new SimpleExecutionContext(sessionFactory);
-
-        // Create the sequencing service, passing in the execution context ...
-        this.sequencingService = new SequencingService();
-        this.sequencingService.setExecutionContext(executionContext);
-
-        // Configure the sequencers.
-        String name = "Image Sequencer";
-        String desc = "Sequences image files to extract the characteristics of the image";
-        String classname = "org.jboss.dna.sequencer.images.ImageMetadataSequencer";
-        String[] classpath = null; // Use the current classpath
-        String[] pathExpressions = {"//(*.(jpg|jpeg|gif|bmp|pcx|png|iff|ras|pbm|pgm|ppm|psd))[*]/jcr:content[@jcr:data] => /images/$1"};
-        SequencerConfig imageSequencerConfig = new SequencerConfig(name, desc, classname, classpath, pathExpressions);
-        this.sequencingService.addSequencer(imageSequencerConfig);
-
-        // Set up the MP3 sequencer ...
-        name = "Mp3 Sequencer";
-        desc = "Sequences mp3 files to extract the id3 tags of the audio file";
-        classname = "org.jboss.dna.sequencer.mp3.Mp3MetadataSequencer";
-        String[] mp3PathExpressions = {"//(*.mp3)[*]/jcr:content[@jcr:data] =&gt; /mp3s/$1"};
-        SequencerConfig mp3SequencerConfig = new SequencerConfig(name, desc, classname, classpath, mp3PathExpressions);
-        this.sequencingService.addSequencer(mp3SequencerConfig);
-
-        // Use the DNA observation service to listen to the JCR repository (or multiple ones), and
-        // then register the sequencing service as a listener to this observation service...
-        this.observationService = new ObservationService(this.executionContext.getSessionFactory());
-        this.observationService.getAdministrator().start();
-        this.observationService.addListener(this.sequencingService);
-        this.observationService.monitor(this.repositoryName + "/" + this.workspaceName, Event.NODE_ADDED | Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED);
-    }
-    // Start up the sequencing service ...
-    this.sequencingService.getAdministrator().start();
-}
-  ]]></programlisting>
-		<para>The <code>shutdownDnaServices()</code> method is pretty straightforward: it just calls shutdown on each of the services
-			and waits until they terminate.</para>
-    <programlisting role="JAVA"><![CDATA[
-public void shutdownDnaServices() throws Exception {
-    if (this.sequencingService == null) return;
-
-    // Shut down the service and wait until it's all shut down ...
-    this.sequencingService.getAdministrator().shutdown();
-    this.sequencingService.getAdministrator().awaitTermination(5, TimeUnit.SECONDS);
-
-    // Shut down the observation service ...
-    this.observationService.getAdministrator().shutdown();
-    this.observationService.getAdministrator().awaitTermination(5, TimeUnit.SECONDS);
-}
-  ]]></programlisting>
-		<para>None of the other methods really do anything with JBoss DNA <emphasis>per se</emphasis>. Instead, they merely work with the repository
-      using the JCR API.</para>
-		<para>The <code>main</code> method of the <code>SequencingClient</code> class creates a <code>SequencingClient</code> instance,
-      and passes a new <code>ConsoleInput</code> instance:</para>
-    <programlisting role="JAVA"><![CDATA[
-public static void main( String[] args ) throws Exception {
-    SequencingClient client = new SequencingClient();
-    client.setRepositoryInformation("repo", "default", "jsmith", "secret".toCharArray());
-    client.setUserInterface(new ConsoleInput(client));
-}
-  ]]></programlisting>
-		<para>If we look at the <code>ConsoleInput</code> constructor, it starts the repository, the DNA services, and a thread 
-			for the user interface. At this point, the constructor returns, but the main application continues under the user interface thread.  
-			When the user requests to quit, the user interface thread also shuts down the DNA services and JCR repository.</para>
-    <programlisting role="JAVA"><![CDATA[
-public ConsoleInput( SequencerClient client ) {
-  try {
-      client.startRepository();
-      client.startDnaServices();
-  
-      System.out.println(getMenu());
-      Thread eventThread = new Thread(new Runnable() {
-          private boolean quit = false;
-          public void run() {
-              try {
-                  while (!quit) {
-                      // Display the prompt and process the requested operation ...
-                  }
-              } finally {
-                  try {
-                      // Terminate ...
-                      client.shutdownDnaServices();
-                      client.shutdownRepository();
-                  } catch (Exception err) {
-                      System.out.println("Error shutting down sequencing service and repository: " 
-                                         + err.getLocalizedMessage());
-                      err.printStackTrace(System.err);
-                  }
-              }
-          }
-      });
-      eventThread.start();
-  } catch (Exception err) {
-      System.out.println("Error: " + err.getLocalizedMessage());
-      err.printStackTrace(System.err);
-  }
-}
-  ]]></programlisting>
-		<para>At this point, we've reviewed all of the interesting code in the example application.  However, feel free
-    to play with the application, trying different things.</para>
-	</sect1>
-	<sect1 id="using_dna_review">
-		<title>Summarizing what we just did</title>
-		<para>In this chapter we covered the different JBoss DNA components and how they can be used in your application.
-      Specifically, we described how the <code>SequencingService</code> and <code>ObservationService</code> can 
-      be configured and used.  And we ended the chapter by reviewing the example application, which not only uses
-      JBoss DNA, but also the repository via the JCR API.</para>
-	</sect1>
-</chapter>

Copied: trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_for_sequencing.xml (from rev 499, trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna.xml)
===================================================================
--- trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_for_sequencing.xml	                        (rev 0)
+++ trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_for_sequencing.xml	2008-09-05 20:01:49 UTC (rev 505)
@@ -0,0 +1,553 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~
+  ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+  ~ indicated by the @author tags or express copyright attribution
+  ~ statements applied by the authors.  All third-party contributions are
+  ~ distributed under license by Red Hat Middleware LLC.
+  ~
+  ~ This copyrighted material is made available to anyone wishing to use, modify,
+  ~ copy, or redistribute it subject to the terms and conditions of the GNU
+  ~ Lesser General Public License, as published by the Free Software Foundation.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+  ~ for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public License
+  ~ along with this distribution; if not, write to:
+  ~ Free Software Foundation, Inc.
+  ~ 51 Franklin Street, Fifth Floor
+  ~ Boston, MA  02110-1301  USA
+  -->
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="using_dna_for_sequencing">
+	<title>Using JBoss DNA for Sequencing</title>
+	<para>As we've mentioned before, JBoss DNA is able to work with existing JCR repositories.  Your client applications
+  	make changes to the information in those repositories, and JBoss DNA automatically uses its sequencers to extract
+  	additional information from the uploaded files.</para>
+	<note>
+		<para>Configuring JBoss DNA sequencers is a bit more manual than is ideal. As you'll see, JBoss DNA uses dependency
+      injection to allow a great deal of flexibility in how it can be configured and customized. However, the next release will
+      provide a much easier mechanism for configuring the services using DNA repositories and configuration files.  Current
+      plans are to use the <a href="http://www.jboss.org/jbossmc">JBoss Microcontainer</a>.</para>
+	</note>
+	<sect1 id="sequencing_service">
+		<title>Configuring the Sequencing Service</title>
+		<para>The JBoss DNA <emphasis>sequencing service</emphasis> is the component that manages the <emphasis>sequencers</emphasis>, 
+			reacting to changes in JCR repositories and then running the appropriate sequencers.
+      This involves processing the changes on a node, determining which (if any) sequencers should be run on that node,
+      and for each sequencer constructing the execution environment, calling the sequencer, and saving the information
+      generated by the sequencer.</para>
+		<para>To set up the sequencing service, an instance is created, and dependent components are injected into
+      the object.  This includes among other things:
+			<itemizedlist>
+				<listitem>
+					<para>An <emphasis>execution context</emphasis> that defines the context in which the service runs, including
+			        a factory for JCR sessions given names of the repository and workspace.  This factory must be configured,
+			        and is how JBoss DNA knows about your JCR repositories and how to connect to them.  More on this a bit later.</para>
+				</listitem>
+				<listitem>
+					<para>An optional <emphasis>factory for class loaders</emphasis> used to load sequencers.  If no factory is supplied,
+			        the service uses the current thread's context class loader (or if that is null, the class loader that loaded the
+			        sequencing service class).</para>
+				</listitem>
+				<listitem>
+					<para>An <code>java.util.concurrent.ExecutorService</code> used to execute the sequencing activites.  If none
+			        is supplied, a new single-threaded executor is created by calling <code>Executors.newSingleThreadExecutor()</code>.
+			        (This can easily be changed by subclassing and overriding the <code>SequencerService.createDefaultExecutorService()</code> method.)</para>
+				</listitem>
+				<listitem>
+					<para>Filters for sequencers and events.  By default, all sequencers are considered for "node added", "property added"
+			        and "property changed" events.</para>
+				</listitem>
+			</itemizedlist>
+    </para>
+		<para>As mentioned above, the <code>ExecutionContext</code> provides access to a <code>SessionFactory</code> that is used
+      by JBoss DNA to establish sessions to your JCR repositories.  Two implementations are available:
+			<itemizedlist>
+				<listitem>
+					<para>The <code>JndiSessionFactory</code> looks up JCR <code>Repository</code> instances in JNDI using
+			          names that are supplied when creating sessions.  This implementation also has methods to set the
+			          JCR <code>Credentials</code> for a given workspace name.</para>
+				</listitem>
+				<listitem>
+					<para>The <code>SimpleSessionFactory</code> has methods to register the JCR <code>Repository</code> instances
+			          with names, as well as methods to set the JCR <code>Credentials</code> for a given workspace name.</para>
+				</listitem>
+			</itemizedlist>
+      You can use the <code>SimpleExecutionContext</code> implementation of <code>ExecutionContext</code> and supply
+      a <code>SessionFactory</code> instance, or you can provide your own implementation.</para>
+		<para>Here's an example of how to instantiate and configure the SequencingService:</para>
+    <programlisting role="JAVA"><![CDATA[
+SimpleSessionFactory sessionFactory = new SimpleSessionFactory();
+sessionFactory.registerRepository("Main Repository", this.repository);
+Credentials credentials = new SimpleCredentials("jsmith", "secret".toCharArray());
+sessionFactory.registerCredentials("Main Repository/Workspace1", credentials);
+ExecutionContext executionContext = new SimpleExecutionContext(sessionFactory);
+
+// Create the sequencing service, passing in the execution context ...
+SequencingService sequencingService = new SequencingService();
+sequencingService.setExecutionContext(executionContext);
+  ]]></programlisting>
+		<para>After the sequencing service is created and configured, it must be started.  The SequencingService
+      has an <emphasis>administration object</emphasis> (that is an instance of <code>ServiceAdministrator</code>)
+      with <code>start()</code>, <code>pause()</code>, and <code>shutdown()</code> methods.  The latter method will 
+      close the queue for sequencing, but will allow sequencing operations already running to complete normally.
+      To wait until all sequencing operations have completed, simply call the <code>awaitTermination</code> method
+      and pass it the maximum amount of time you want to wait.</para>
+		<programlisting role="JAVA"><![CDATA[sequencingService.getAdministrator().start();
+]]></programlisting>
+		<para>The sequencing service must also be configured with the sequencers that it will use.  This is done using the
+      <code>addSequencer(SequencerConfig)</code> method and passing a <code>SequencerConfig</code> instance that
+      you create.  Here's the code that defines 3 sequencer configurations: 1 that places image metadata into
+      "<code><![CDATA[/images/<filename>]]></code>", another that places MP3 metadata into "<code><![CDATA[/mp3s/<filename>]]></code>",
+      and a third that places a structure that represents the classes, methods, and attributes found within Java source into 
+      "<code><![CDATA[/java/<filename>]]></code>".</para>
+    <programlisting role="JAVA"><![CDATA[
+String name = "Image Sequencer";
+String desc = "Sequences image files to extract the characteristics of the image";
+String classname = "org.jboss.dna.sequencer.images.ImageMetadataSequencer";
+String[] classpath = null; // Use the current classpath
+String[] pathExpressions = {"//(*.(jpg|jpeg|gif|bmp|pcx|png)[*])/jcr:content[@jcr:data] => /images/$1"};
+SequencerConfig imageSequencerConfig = new SequencerConfig(name, desc, classname, 
+                                                           classpath, pathExpressions);
+sequencingService.addSequencer(imageSequencerConfig);
+
+name = "Mp3 Sequencer";
+desc = "Sequences mp3 files to extract the id3 tags of the audio file";
+classname = "org.jboss.dna.sequencer.mp3.Mp3MetadataSequencer";
+pathExpressions = {"//(*.mp3[*])/jcr:content[@jcr:data] =&gt; /mp3s/$1"};
+SequencerConfig mp3SequencerConfig = new SequencerConfig(name, desc, classname, 
+                                                         classpath, pathExpressions);
+sequencingService.addSequencer(mp3SequencerConfig);
+
+name = "Java Sequencer";
+desc = "Sequences java files to extract the characteristics of the Java source";
+classname = "org.jboss.dna.sequencer.java.JavaMetadataSequencer";
+pathExpressions = {"//(*.java[*])/jcr:content[@jcr:data] => /java/$1"};
+SequencerConfig javaSequencerConfig = new SequencerConfig(name, desc, classname, 
+                                                          classpath, pathExpressions);
+this.sequencingService.addSequencer(javaSequencerConfig);
+  ]]></programlisting>
+    <para>Each configuration defines several things, including the name, description, and sequencer implementation class.
+	    The configuration also defines the classpath information, which can be passed to the class loader factory to get
+	    a Java classloader with which the sequencer class can be loaded.  (If no classpath information is provided, as is done
+	    in the code above, the application class loader is used.)  The configuration also specifies the path expressions that
+	    identify the nodes that should be sequenced with the sequencer and where to store the output generated by the sequencer.
+	    Path expressions are pretty straightforward but are quite powerful, so before we go any further with the example,
+	    let's dive into path expressions in more detail.</para>
+		<sect2 id="path_expressions">
+			<title>Path Expressions</title>
+			<para>Path expressions consist of two parts: a selection criteria (or an input path) and an output path:</para>
+	    <programlisting><![CDATA[  inputPath => outputPath ]]></programlisting>
+			<para>The <emphasis>inputPath</emphasis> part defines an expression for the path of a node that is to be sequenced.
+			  Input paths consist of '<code>/</code>' separated segments, where each segment represents a pattern for a single node's
+			  name (including the same-name-sibling indexes) and '<code>@</code>' signifies a property name.</para>
+			<para>Let's first look at some simple examples:</para>
+			<table frame='all'>
+				<title>Simple Input Path Examples</title>
+				<tgroup cols='2' align='left' colsep='1' rowsep='1'>
+		      <colspec colname='c1' colwidth="1*"/>
+		      <colspec colname='c2' colwidth="1*"/>
+					<thead>
+						<row>
+				  		<entry>Input Path</entry>
+				  		<entry>Description</entry>
+						</row>
+					</thead>
+					<tbody>
+						<row><entry>/a/b</entry><entry>Match node "<code>b</code>" that is a child of the top level node "<code>a</code>". Neither node
+						     may have any same-name-sibilings.</entry></row>
+						<row><entry>/a/*</entry><entry>Match any child node of the top level node "<code>a</code>".</entry></row>
+						<row><entry>/a/*.txt</entry><entry>Match any child node of the top level node "<code>a</code>" that also has a name ending in "<code>.txt</code>".</entry></row>
+						<row><entry>/a/*.txt</entry><entry>Match any child node of the top level node "<code>a</code>" that also has a name ending in "<code>.txt</code>".</entry></row>
+						<row><entry>/a/b at c</entry><entry>Match the property "<code>c</code>" of node "<code>/a/b</code>".</entry></row>
+						<row><entry>/a/b[2]</entry><entry>The second child named "<code>b</code>" below the top level node "<code>a</code>".</entry></row>
+						<row><entry>/a/b[2,3,4]</entry><entry>The second, third or fourth child named "<code>b</code>" below the top level node "<code>a</code>".</entry></row>
+						<row><entry>/a/b[*]</entry><entry>Any (and every) child named "<code>b</code>" below the top level node "<code>a</code>".</entry></row>
+						<row><entry>//a/b</entry><entry>Any node named "<code>b</code>" that exists below a node named "<code>a</code>", regardless 
+						     of where node "<code>a</code>" occurs.  Again, neither node may have any same-name-sibilings.</entry></row>
+					</tbody>
+				</tgroup>
+			</table>
+			<para>With these simple examples, you can probably discern the most important rules.  First, the '<code>*</code>' is a wildcard character
+			  that matches any character or sequence of characters in a node's name (or index if appearing in between square brackets), and
+			  can be used in conjunction with other characters (e.g., "<code>*.txt</code>").</para>
+			<para>Second, square brackets (i.e., '<code>[</code>' and '<code>]</code>') are used to match a node's same-name-sibiling index.
+			  You can put a single non-negative number or a comma-separated list of non-negative numbers.  Use '0' to match a node that has no
+			  same-name-sibilings, or any positive number to match the specific same-name-sibling.</para>
+			<para>Third, combining two delimiters (e.g., "<code>//</code>") matches any sequence of nodes, regardless of what their names are 
+			  or how many nodes.  Often used with other patterns to identify nodes at any level matching other patterns. 
+				Three or more sequential slash characters are treated as two.</para>
+			<para>Many input paths can be created using just these simple rules.  However, input paths can be more complicated.  Here are some
+				more examples:</para>
+			<table frame='all'>
+				<title>More Complex Input Path Examples</title>
+				<tgroup cols='2' align='left' colsep='1' rowsep='1'>
+		      <colspec colname='c1' colwidth="1*"/>
+		      <colspec colname='c2' colwidth="1*"/>
+					<thead>
+						<row>
+				  		<entry>Input Path</entry>
+				  		<entry>Description</entry>
+						</row>
+					</thead>
+					<tbody>
+						<row><entry>/a/(b|c|d)</entry><entry>Match children of the top level node "<code>a</code>" that are named "<code>a</code>", 
+								 "<code>b</code>" or "<code>c</code>". None of the nodes may have same-name-sibling indexes.</entry></row>
+						<row><entry>/a/b[c/d]</entry><entry>Match node "<code>b</code>" child of the top level node "<code>a</code>", when node
+						     "<code>b</code>" has a child named "<code>c</code>", and "<code>c</code>" has a child named "<code>d</code>".
+								 Node "<code>b</code>" is the selected node, while nodes "<code>b</code>" and "<code>b</code>" are used as criteria but are not
+								 selected.</entry></row>
+						<row><entry>/a(/(b|c|d|)/e)[f/g/@something]</entry><entry>Match node "<code>/a/b/e</code>", "<code>/a/c/e</code>", "<code>/a/d/e</code>",
+						     or "<code>/a/e</code>" when they also have a child "<code>f</code>" that itself has a child "<code>g</code>" with property
+						     "<code>something</code>". None of the nodes may have same-name-sibling indexes.</entry></row>
+					</tbody>
+				</tgroup>
+			</table>
+			<para>These examples show a few more advanced rules.  Parentheses (i.e., '<code>(</code>' and '<code>)</code>') can be used
+			  to define a set of options for names, as shown in the first and third rules.  Whatever part of the selected node's path
+			  appears between the parentheses is captured for use within the output path.  Thus, the first input path in the previous table
+			  would match node "<code>/a/b</code>", and "b" would be captured and could be used within the output path using "<code>$1</code>",
+			  where the number used in the output path identifies the parentheses.</para>
+			<para>Square brackets can also be used to specify criteria on a node's properties or children.  Whatever appears in between the square
+				brackets does not appear in the selected node.</para>
+		  <para>Let's go back to the previous code fragment and look at the first path expression:</para>
+		  <programlisting><![CDATA[  //(*.(jpg|jpeg|gif|bmp|pcx|png)[*])/jcr:content[@jcr:data] => /images/$1 ]]></programlisting>
+		  <para>This matches a node named "<code>jcr:content</code>" with property "<code>jcr:data</code>" but no siblings with the same name,
+		    and that is a child of a node whose name ends with "<code>.jpg</code>", "<code>.jpeg</code>", "<code>.gif</code>", "<code>.bmp</code>", "<code>.pcx</code>", 
+		    or  "<code>.png</code>" that may have any same-name-sibling index.  These nodes can appear at any level in the repository.
+			  Note how the input path capture the filename (the segment containing the file extension), including any same-name-sibling index.
+			  This filename is then used in the output path, which is where the sequenced content is placed.</para>
+		</sect2>
+		<sect2 id="path_expressions_in_example">
+			<title>Path Expressions Used in the Example</title>
+			<para>Now that we've covered path expressions, let's go back to the three sequencer configuration in the example.
+				Here they are again, with a description of what each path means:</para>
+			<table frame='all'>
+				<title>Path Expressions for the 3 Sequencers</title>
+				<tgroup cols='3' align='left' colsep='1' rowsep='1'>
+		      <colspec colname='c1' colwidth="1*"/>
+		      <colspec colname='c2' colwidth="1*"/>
+		      <colspec colname='c2' colwidth="1*"/>
+					<thead>
+						<row>
+				  		<entry>Input Path</entry>
+				  		<entry>Output Path</entry>
+				  		<entry>Description</entry>
+						</row>
+					</thead>
+					<tbody>
+						<row>
+							<entry><![CDATA[//(*.(jpg|jpeg|gif|bmp|pcx|png)[*])/jcr:content[@jcr:data]]]></entry>
+							<entry><![CDATA[/images/$1]]></entry>
+							<entry>Any node with a name ending in "<code>.jpg</code>", "<code>.jpeg</code>", "<code>.gif</code>", "<code>.bmp</code>", 
+							  "<code>.pcx</code>", or "<code>.png</code>", whether or not it has a same-name-sibling index, but that has a child named 
+								"<code>jcr:content</code>" with "<code>jcr:data</code>" property.  The node name representing the filename (including any
+								same-name-sibling index) is captured, and used to place the output in "<code><![CDATA[/images/<filename>]]></code>".</entry>
+						</row>
+						<row>
+							<entry><![CDATA[//(*.mp3[*])/jcr:content[@jcr:data]]]></entry>
+							<entry><![CDATA[/mp3s/$1]]></entry>
+							<entry>Any node with a name ending in "<code>.mp3</code>", whether or not it has a same-name-sibling index, but that has a child named 
+								"<code>jcr:content</code>" with "<code>jcr:data</code>" property.  The node name representing the filename (including any
+								same-name-sibling index) is captured, and used to place the output in "<code><![CDATA[/mp3s/<filename>]]></code>".</entry>
+						</row>
+						<row>
+							<entry><![CDATA[//(*.java[*])/jcr:content[@jcr:data]]]></entry>
+							<entry><![CDATA[/java/$1]]></entry>
+							<entry>Any node with a name ending in "<code>.java</code>", whether or not it has a same-name-sibling index, but that has a child named 
+								"<code>jcr:content</code>" with "<code>jcr:data</code>" property.  The node name representing the filename (including any
+								same-name-sibling index) is captured, and used to place the output in "<code><![CDATA[/java/<filename>]]></code>".</entry>
+						</row>
+					</tbody>
+				</tgroup>
+			</table>
+			<para>After these sequencer configurations are defined and added to the <code>SequencingService</code>,
+				the service is now ready to start reacting to changes in the repository and automatically looking for nodes to sequence.  
+				But we first need to wire the service into the repository to receive those change events.
+	      This is accomplished using the <code>ObservationService</code>
+	      described in the <link linkend="observation_service">next section</link>.</para>
+		</sect2>
+	</sect1>
+	<sect1 id="observation_service">
+		<title>Configuring the Observation Service</title>
+		<para>The JBoss DNA <code>ObservationService</code> is responsible for listening to one or more JCR repositories
+	    and multiplexing the events to its listeners.  Unlike JCR events, this framework embeds in the events the
+	    name of the repository and workspace that can be passed to a <code>SessionFactory</code> to obtain a session
+	    to the repository in which the change occurred.  This simple design makes it very easy for JBoss DNA to
+	    concurrently work with multiple JCR repositories.</para>
+		<para>Configuring an observation service is pretty easy, especially if you reuse the same <code>SessionFactory</code>
+	    supplied to the sequencing service.  Here's an example:</para>
+    <programlisting role="JAVA"><![CDATA[
+  this.observationService = new ObservationService(sessionFactory);
+  this.observationService.getAdministrator().start();
+  ]]></programlisting>
+		<note>
+			<para>Both <code>ObservationService</code> and <code>SequencingService</code> implement
+    		<code>AdministeredService</code>, which has a <code>ServiceAdministrator</code> used to start, pause, and shutdown the
+    		service.  In other words, the lifecycle of the services are managed in the same way.</para>
+		</note>
+		<para>After the observation service is started, listeners can be added.  The <code>SequencingService</code> implements the required
+    interface, and so it may be registered directly:</para>
+    <programlisting role="JAVA"><![CDATA[
+  observationService.addListener(sequencingService);
+  ]]></programlisting>
+		<para>Finally, the observation service must be wired to monitor one of your JCR repositories.  This is done with
+    	one of the <code>monitor(...)</code> methods:</para>
+    <programlisting role="JAVA"><![CDATA[
+  int eventTypes = Event.NODE_ADDED | Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED;
+  observationService.monitor("Main Repository/Workspace1", eventTypes);
+  ]]></programlisting>
+		<para>At this point, the observation service is listening to a JCR repository and forwarding the appropriate events
+    	to the sequencing service, which will asynchronously process the changes and sequence the information added to or changed in the repository.
+    </para>
+	</sect1>
+	<sect1 id="shutting_down">
+		<title>Shutting down JBoss DNA services</title>
+		<para>The JBoss DNA services are utilizing resources and threads that must be released before your application is ready to shut down.
+    	The safe way to do this is to simply obtain the <code>ServiceAdministrator</code> for each service (via the <code>getServiceAdministrator()</code> method)
+    	and call <code>shutdown()</code>.  As previously mentioned, the shutdown method will simply prevent new work from being processed
+    	and will not wait for existing work to be completed.  If you want to wait until the service completes all its work, you must wait
+    	until the service terminates.  Here's an example that shows how this is done:</para>
+    <programlisting role="JAVA"><![CDATA[
+// Shut down the service and wait until it's all shut down ...
+sequencingService.getAdministrator().shutdown();
+sequencingService.getAdministrator().awaitTermination(5, TimeUnit.SECONDS);
+
+// Shut down the observation service ...
+observationService.getAdministrator().shutdown();
+observationService.getAdministrator().awaitTermination(5, TimeUnit.SECONDS);
+  ]]></programlisting>
+		<para>At this point, we've covered how to configure and use the JBoss DNA services in your application.
+    	The next chapter goes back to the <link linkend="downloading_and_running">sample application</link> to show how all 
+			these pieces fit together.</para>
+	</sect1>
+	<sect1 id="example_application_review">
+		<title>Reviewing the example application</title>
+		<para>Recall that the example application consists of a client application that sets up an in-memory JCR repository and
+      that allows a user to upload files into that repository. The client also sets up the DNA services with an image sequencer so
+      that if any of the uploaded files are PNG, JPEG, GIF, BMP or other images, DNA will automatically extract the image's
+      metadata (e.g., image format, physical size, pixel density, etc.) and store that in the repository.  Or, if the client uploads
+      MP3 audio files, the title, author, album, year, and comment are extracted from the audio file and stored in the repository.</para>
+		<para>
+      The example is comprised of 3 classes and 1 interface, located in the <code>src/main/java</code> directory:</para>
+    <programlisting><![CDATA[
+  org/jboss/example/dna/sequencers/ConsoleInput.java
+                                  /MediaInfo.java
+                                  /SequencingClient.java
+                                  /UserInterface.java
+  ]]></programlisting>
+		<para><code>SequencingClient</code> is the class that contains the main application.  <code>MediaInfo</code> is a simple Java object 
+			that encapsulates metadata about a media file (as generated by the sequencer), and used by the client to
+      pass information to the <code>UserInterface</code>, which is an interface with methods that will be called at runtime to 
+			request data from the user.  <code>ConsoleInput</code> is an implementation of this that creates a text user interface, 
+			allowing the user to operate the client from the command-line.  We can easily create a graphical implementation of
+      <code>UserInterface</code> at a later date. We can also create a mock implementation for testing purposes that simulates 
+			a user entering data. This allows us to check the behavior of the client automatically using conventional JUnit test cases, 
+			as demonstrated by the code in the <code>src/test/java</code> directory:</para>
+    <programlisting><![CDATA[
+  org/jboss/example/dna/sequencers/SequencingClientTest.java
+                                  /MockUserInterface.java
+  ]]></programlisting>
+		<para>If we look at the <code>SequencingClient</code> code, there are a handful of methods that encapsulate the various activities.</para>
+		<note>
+			<para>To keep the code shown in this book as readable as possible, some of the comments and error handling have been removed.</para>
+		</note>
+		<para>The <code>startRepository()</code> method starts up an in-memory Jackrabbit JCR repository. The bulk of this method is simply 
+			gathering and passing the information required by Jackrabbit. Because Jackrabbit's <code>TransientRepository</code>
+      implementation shuts down after the last session is closed, the application maintains a session to ensure that the
+      repository remains open throughout the application's lifetime. And finally, the node type needed by the image sequencer is
+      registered with Jackrabbit.</para>
+		<programlisting role="JAVA"><![CDATA[
+public void startRepository() throws Exception {
+    if (this.repository == null) {
+        try {
+
+            // Load the Jackrabbit configuration ...
+            File configFile = new File(this.jackrabbitConfigPath);
+            String pathToConfig = configFile.getAbsolutePath();
+
+            // Find the directory where the Jackrabbit repository data will be stored ...
+            File workingDirectory = new File(this.workingDirectory);
+            String workingDirectoryPath = workingDirectory.getAbsolutePath();
+
+            // Get the Jackrabbit custom node definition (CND) file ...
+            URL cndFile = Thread.currentThread().getContextClassLoader().getResource("jackrabbitNodeTypes.cnd");
+
+            // Create the Jackrabbit repository instance and establish a session to keep the repository alive ...
+            this.repository = new TransientRepository(pathToConfig, workingDirectoryPath);
+            if (this.username != null) {
+                Credentials credentials = new SimpleCredentials(this.username, this.password);
+                this.keepAliveSession = this.repository.login(credentials, this.workspaceName);
+            } else {
+                this.keepAliveSession = this.repository.login();
+            }
+
+            try {
+                // Register the node types (only valid the first time) ...
+                Workspace workspace = this.keepAliveSession.getWorkspace();
+                JackrabbitNodeTypeManager mgr = (JackrabbitNodeTypeManager)workspace.getNodeTypeManager();
+                mgr.registerNodeTypes(cndFile.openStream(), JackrabbitNodeTypeManager.TEXT_X_JCR_CND);
+            } catch (RepositoryException e) {
+                if (!e.getMessage().contains("already exists")) throw e;
+            }
+
+        } catch (Exception e) {
+            this.repository = null;
+            this.keepAliveSession = null;
+            throw e;
+        }
+    }
+}
+  ]]></programlisting>
+		<para>As you can see, this method really has nothing to do with JBoss DNA, other than setting up a JCR repository that JBoss
+      DNA will use.</para>
+		<para>The <code>shutdownRepository()</code> method shuts down the Jackrabbit transient repository by closing the "keep-alive session". 
+			Again, this method really does nothing specifically with JBoss DNA, but is needed to manage the JCR repository that JBoss DNA uses.</para>
+    <programlisting role="JAVA"><![CDATA[
+public void shutdownRepository() throws Exception {
+    if (this.repository != null) {
+        try {
+            this.keepAliveSession.logout();
+        } finally {
+            this.repository = null;
+            this.keepAliveSession = null;
+        }
+    }
+}
+  ]]></programlisting>
+		<para>The <code>startDnaServices()</code> method first starts the JCR repository (if it was not already started), and proceeds 
+			to create and configure the <code>SequencingService</code> as described <link linkend="sequencing_service">earlier</link>.
+      This involes setting up the <code>SessionFactory</code> and <code>ExecutionContext</code>, creating the
+      <code>SequencingService</code> instance, and configuring the image sequencer. The method then continues by setting up the
+      <code>ObservationService</code> as described <link linkend="observation_service">earlier</link> and starting the service.</para>
+		<programlisting role="JAVA"><![CDATA[
+public void startDnaServices() throws Exception {
+    if (this.repository == null) this.startRepository();
+    if (this.sequencingService == null) {
+
+        SimpleSessionFactory sessionFactory = new SimpleSessionFactory();
+        sessionFactory.registerRepository(this.repositoryName, this.repository);
+        if (this.username != null) {
+            Credentials credentials = new SimpleCredentials(this.username, this.password);
+            sessionFactory.registerCredentials(this.repositoryName + "/" + this.workspaceName, credentials);
+        }
+        this.executionContext = new SimpleExecutionContext(sessionFactory);
+
+        // Create the sequencing service, passing in the execution context ...
+        this.sequencingService = new SequencingService();
+        this.sequencingService.setExecutionContext(executionContext);
+
+        // Configure the sequencers.
+        String name = "Image Sequencer";
+        String desc = "Sequences image files to extract the characteristics of the image";
+        String classname = "org.jboss.dna.sequencer.images.ImageMetadataSequencer";
+        String[] classpath = null; // Use the current classpath
+        String[] pathExpressions = {"//(*.(jpg|jpeg|gif|bmp|pcx|png|iff|ras|pbm|pgm|ppm|psd))[*]/jcr:content[@jcr:data] => /images/$1"};
+        SequencerConfig imageSequencerConfig = new SequencerConfig(name, desc, classname, classpath, pathExpressions);
+        this.sequencingService.addSequencer(imageSequencerConfig);
+
+        // Set up the MP3 sequencer ...
+        name = "Mp3 Sequencer";
+        desc = "Sequences mp3 files to extract the id3 tags of the audio file";
+        classname = "org.jboss.dna.sequencer.mp3.Mp3MetadataSequencer";
+        pathExpressions = {"//(*.mp3)[*]/jcr:content[@jcr:data] =&gt; /mp3s/$1"};
+        SequencerConfig mp3SequencerConfig = new SequencerConfig(name, desc, classname, classpath, pathExpressions);
+        this.sequencingService.addSequencer(mp3SequencerConfig);
+
+				name = "Java Sequencer";
+				desc = "Sequences java files to extract the characteristics of the Java source";
+				classname = "org.jboss.dna.sequencer.java.JavaMetadataSequencer";
+				pathExpressions = {"//(*.java[*])/jcr:content[@jcr:data] => /java/$1"};
+				SequencerConfig javaSequencerConfig = new SequencerConfig(name, desc, classname,classpath, pathExpressions);
+				this.sequencingService.addSequencer(javaSequencerConfig);
+
+        // Use the DNA observation service to listen to the JCR repository (or multiple ones), and
+        // then register the sequencing service as a listener to this observation service...
+        this.observationService = new ObservationService(this.executionContext.getSessionFactory());
+        this.observationService.getAdministrator().start();
+        this.observationService.addListener(this.sequencingService);
+        this.observationService.monitor(this.repositoryName + "/" + this.workspaceName, Event.NODE_ADDED | Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED);
+    }
+    // Start up the sequencing service ...
+    this.sequencingService.getAdministrator().start();
+}
+  ]]></programlisting>
+		<para>The <code>shutdownDnaServices()</code> method is pretty straightforward: it just calls shutdown on each of the services
+			and waits until they terminate.</para>
+    <programlisting role="JAVA"><![CDATA[
+public void shutdownDnaServices() throws Exception {
+    if (this.sequencingService == null) return;
+
+    // Shut down the service and wait until it's all shut down ...
+    this.sequencingService.getAdministrator().shutdown();
+    this.sequencingService.getAdministrator().awaitTermination(5, TimeUnit.SECONDS);
+
+    // Shut down the observation service ...
+    this.observationService.getAdministrator().shutdown();
+    this.observationService.getAdministrator().awaitTermination(5, TimeUnit.SECONDS);
+}
+  ]]></programlisting>
+		<para>None of the other methods really do anything with JBoss DNA <emphasis>per se</emphasis>. Instead, they merely work with the repository
+      using the JCR API.</para>
+		<para>The <code>main</code> method of the <code>SequencingClient</code> class creates a <code>SequencingClient</code> instance,
+      and passes a new <code>ConsoleInput</code> instance:</para>
+    <programlisting role="JAVA"><![CDATA[
+public static void main( String[] args ) throws Exception {
+    SequencingClient client = new SequencingClient();
+    client.setRepositoryInformation("repo", "default", "jsmith", "secret".toCharArray());
+    client.setUserInterface(new ConsoleInput(client));
+}
+  ]]></programlisting>
+		<para>If we look at the <code>ConsoleInput</code> constructor, it starts the repository, the DNA services, and a thread 
+			for the user interface. At this point, the constructor returns, but the main application continues under the user interface thread.  
+			When the user requests to quit, the user interface thread also shuts down the DNA services and JCR repository.</para>
+    <programlisting role="JAVA"><![CDATA[
+public ConsoleInput( SequencerClient client ) {
+  try {
+      client.startRepository();
+      client.startDnaServices();
+  
+      System.out.println(getMenu());
+      Thread eventThread = new Thread(new Runnable() {
+          private boolean quit = false;
+          public void run() {
+              try {
+                  while (!quit) {
+                      // Display the prompt and process the requested operation ...
+                  }
+              } finally {
+                  try {
+                      // Terminate ...
+                      client.shutdownDnaServices();
+                      client.shutdownRepository();
+                  } catch (Exception err) {
+                      System.out.println("Error shutting down sequencing service and repository: " 
+                                         + err.getLocalizedMessage());
+                      err.printStackTrace(System.err);
+                  }
+              }
+          }
+      });
+      eventThread.start();
+  } catch (Exception err) {
+      System.out.println("Error: " + err.getLocalizedMessage());
+      err.printStackTrace(System.err);
+  }
+}
+  ]]></programlisting>
+		<para>At this point, we've reviewed all of the interesting code in the example application.  However, feel free
+    to play with the application, trying different things.</para>
+	</sect1>
+	<sect1 id="using_dna_review">
+		<title>Summarizing what we just did</title>
+		<para>In this chapter we covered the different JBoss DNA components and how they can be used in your application.
+      Specifically, we described how the <code>SequencingService</code> and <code>ObservationService</code> can 
+      be configured and used.  And we ended the chapter by reviewing the example application, which not only uses
+      JBoss DNA, but also the repository via the JCR API.</para>
+	</sect1>
+</chapter>

Added: trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_repositories.xml
===================================================================
--- trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_repositories.xml	                        (rev 0)
+++ trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_repositories.xml	2008-09-05 20:01:49 UTC (rev 505)
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~
+  ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+  ~ indicated by the @author tags or express copyright attribution
+  ~ statements applied by the authors.  All third-party contributions are
+  ~ distributed under license by Red Hat Middleware LLC.
+  ~
+  ~ This copyrighted material is made available to anyone wishing to use, modify,
+  ~ copy, or redistribute it subject to the terms and conditions of the GNU
+  ~ Lesser General Public License, as published by the Free Software Foundation.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+  ~ for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public License
+  ~ along with this distribution; if not, write to:
+  ~ Free Software Foundation, Inc.
+  ~ 51 Franklin Street, Fifth Floor
+  ~ Boston, MA  02110-1301  USA
+  -->
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="using_dna_repositories">
+	<title>Using JBoss DNA Repositories</title>
+	<para>As we've mentioned before, one of the capabilities of JBoss DNA is to provide access through JCR to different kinds 
+		of repositories.  You're applications work with the JCR API, but JBoss DNA accesses the content from the underlying systems,
+		including able to work with existing JCR repositories.</para>
+</chapter>
+	

Deleted: trunk/docs/gettingstarted/src/main/docbook/en-US/images/example-sequencer-cli-client.png
===================================================================
(Binary files differ)

Copied: trunk/docs/gettingstarted/src/main/docbook/en-US/images/example-sequencer-client.png (from rev 497, trunk/docs/gettingstarted/src/main/docbook/en-US/images/example-sequencer-cli-client.png)
===================================================================
(Binary files differ)

Modified: trunk/docs/gettingstarted/src/main/docbook/en-US/master.xml
===================================================================
--- trunk/docs/gettingstarted/src/main/docbook/en-US/master.xml	2008-09-05 19:59:46 UTC (rev 504)
+++ trunk/docs/gettingstarted/src/main/docbook/en-US/master.xml	2008-09-05 20:01:49 UTC (rev 505)
@@ -53,7 +53,8 @@
 	<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/introduction.xml"/>
 	<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/understanding_dna.xml"/>
 	<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/downloading_and_running.xml"/>
-	<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/using_dna.xml"/>
+	<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/using_dna_for_sequencing.xml"/>
+	<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/using_dna_repositories.xml"/>
 	<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/custom_sequencers.xml"/>
 	<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/future.xml"/>
 </book>




More information about the dna-commits mailing list