DNA SVN: r144 - trunk/dna-repository.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2008-05-12 16:02:42 -0400 (Mon, 12 May 2008)
New Revision: 144
Removed:
trunk/dna-repository/.settings/
Log:
Removing Eclipse settings folder
15 years, 12 months
DNA SVN: r143 - trunk/dna-maven-classloader.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2008-05-12 16:02:22 -0400 (Mon, 12 May 2008)
New Revision: 143
Removed:
trunk/dna-maven-classloader/.settings/
Log:
Removing Eclipse settings folder
15 years, 12 months
DNA SVN: r142 - trunk/dna-integration-tests.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2008-05-12 16:01:56 -0400 (Mon, 12 May 2008)
New Revision: 142
Removed:
trunk/dna-integration-tests/.settings/
Log:
Removing Eclipse settings folder
15 years, 12 months
DNA SVN: r141 - trunk/dna-common.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2008-05-12 16:00:42 -0400 (Mon, 12 May 2008)
New Revision: 141
Removed:
trunk/dna-common/.settings/
Log:
Removing Eclipse settings folder
15 years, 12 months
DNA SVN: r140 - trunk/docs/gettingstarted/en.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2008-05-09 19:01:47 -0400 (Fri, 09 May 2008)
New Revision: 140
Modified:
trunk/docs/gettingstarted/en/master.xml
Log:
Updated with additional sections.
Modified: trunk/docs/gettingstarted/en/master.xml
===================================================================
--- trunk/docs/gettingstarted/en/master.xml 2008-05-09 23:00:40 UTC (rev 139)
+++ trunk/docs/gettingstarted/en/master.xml 2008-05-09 23:01:47 UTC (rev 140)
@@ -174,7 +174,7 @@
</chapter>
<chapter id="jboss_dna">
<title>JBoss DNA</title>
- <sect1>
+ <sect1 id="jboss_dna_overview">
<title>Overview</title>
<para>JBoss DNA is a repository and set of tools that make it easy to capture, version, analyze, and understand the
fundamental building blocks of information. As models, service and process definitions, schemas, source code, and other
@@ -197,10 +197,10 @@
of other DNA components or third-party systems that support the standard APIs.</para>
<mediaobject>
<imageobject role="fo">
- <imagedata align="center" fileref="images/dna-architecture.png"/>
+ <imagedata align="center" fileref="images/dna-architecture.png" />
</imageobject>
<imageobject role="html">
- <imagedata align="center" fileref="images/dna-architecture.png"/>
+ <imagedata align="center" fileref="images/dna-architecture.png" />
</imageobject>
</mediaobject>
<para>
@@ -658,22 +658,32 @@
==================================================================================================== -->
<chapter id="downloading_and_running">
<title>Example application</title>
- <para>JBoss DNA is built using Maven 2, so it's much easier to following along with the examples in this document if you
- install and configure Maven. Once this is done, you can very easily build the examples or even create a maven project that
- depends on the JBoss DNA JARs. Maven will automatically download the right versions of the JARs, including those other
- libraries on which JBoss DNA depends. Maven also makes it very easy to create an assembly of your final application so that
- you can package into a distributable form.</para>
+ <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
+ application running, and then in the
+ <link linkend="using_dna">next chapter</link>
+ we'll we'll dive into the source code for the example and show how to use JBoss DNA in your own applications.
+ </para>
+ <para>JBoss DNA uses Maven 2 for its build system, as is this example. Using Maven 2 has several advantages, including
+ the ability to manage dependencies. If a library is needed, Maven automatically finds and downloads that library, plus
+ everything that library needs. This means that its very easy to build the examples - or even create a maven project that
+ depends on the JBoss DNA JARs.</para>
<note>
<para>
- To use Maven with JBoss DNA, you'll first need to install
- <ulink url="http://java.sun.com/javase/downloads/index_jdk5.jsp">JDK 5</ulink>
- and Maven 2.0.7 (or higher), which is available from
- <ulink url="http://maven.apache.org/">http://maven.apache.org/</ulink>
- .
+ To use Maven with JBoss DNA, you'll need to have
+ <ulink url="http://java.sun.com/javase/downloads/index_jdk5.jsp">JDK 5 or 6</ulink>
+ and Maven 2.0.7 (or higher).
</para>
<para>
- Maven is installed by downloading and unzipping the maven-2.0.7-bin.zip file to a convenient location on your local disk.
- Configuration consists of adding $MAVEN_HOME/bin to your path and adding the following profile to your ~/.m2/settings.xml
+ Maven can be downloaded from
+ <ulink url="http://maven.apache.org/">http://maven.apache.org/</ulink>
+ , and is installed by unzipping the
+ <code>maven-2.0.7-bin.zip</code>
+ file to a convenient location on your local disk. Simply add
+ <code>$MAVEN_HOME/bin</code>
+ to your path and adding the following profile to your
+ <code>~/.m2/settings.xml</code>
file:
<programlisting role="XML" language="xml"><settings>
<profiles>
@@ -962,121 +972,596 @@
<para>You can repeat this process with other files. Any file that isn't an image (as recognized by the sequencing configuration
that we'll describe later) will not be sequenced.</para>
</sect1>
+ <sect1 id="downloading_and_running_review">
+ <title>Review</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 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 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>
</chapter>
-
-
-
-
<!-- ====================================================================================================
Chapter
==================================================================================================== -->
<chapter id="using_dna">
<title>Using JBoss DNA</title>
- <para></para>
-
-
- <para>This 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 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.
- </para>
- <para>The example is comprised of 3 classes and 1 interface, located in the <code>src/main/java</code> directory:
- <programlisting>
-org/jboss/example/dna/sequencers/ConsoleInput.java
- /ImageInfo.java
- /SequencingClient.java
- /UserInterface.java
- </programlisting>
- </para>
- <para><code>SequencingClient</code> is the class that contains the main application. <code>ImageInfo</code> is a simple
- Java object that encapsulates metadata about an image (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 behaviour of the client automatically using conventional
- JUnit test cases, as demonstrated by the code in the <code>src/test/java</code> directory:
- <programlisting>
-org/jboss/example/dna/sequencers/SequencingClientTest.java
- /MockUserInterface.java
- </programlisting>
- </para>
+ <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>Sequencing Service</title>
+ <para>
+ The JBoss DNA <emphasis>sequencing service</emphasis> is the component that manages the <emphasis>sequencers</emphasis>
+ and that reacts to changes in JCR repositories and then running the appropriate sequencers.
+ This involves processing the changes on a node, determinine which (if any) sequencer 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:
+ <programlisting>
+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);
-<!-- Reviewing the code -->
- <para>The example application you just used demonstrated how JBoss DNA sequencing responds
- to the changes in a repository. This example doesn't do much, but the con </para>
-
- <para>The example application you just used demonstrated how JBoss DNA sequencing responds
- to the changes in a repository. This example was pretty simple, but </para>
-
- <para>The example you just ran demonstrated that JBoss DNA does sequence image files. It does everything
- necessary to set up and configure JBoss DNA to use a JCR repository, so reviewing that code can help understand
- what's involved.
+// Create the sequencing service, passing in the execution context ...
+SequencingService sequencingService = new SequencingService();
+sequencingService.setExecutionContext(executionContext);</programlisting>
+ </para>
+ <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>
+ <para>
+ <programlisting>
+sequencingService.getAdministrator().start();</programlisting>
+ </para>
+ <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
+ can create. Here's an example:
+ <programlisting>
+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);
+SesequencingService.addSequencer(imageSequencerConfig);</programlisting>
+ This 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. Here's a simple example:
+ <programlisting>
+/a/b/c@title => /d/e/f</programlisting>
+ Here, the <code>/a/b/c@title</code> is the selection criteria that applies when the <code>/a/b/c</code> node has a <code>title</code> property
+ that is added or changed. When the selection criteria matches a change event, the sequencer will be run
+ and any generated output will be inserted into the repository described by the output expression. In this example,
+ the generated output would be placed at the <code>/d/e/f</code> node.
+ </para>
+ <note>
+ <para>Sequencer path expressions can be fairly complex and may use wildcards, specificy same-name sibling indexes,
+ provide optional and choice elements, and may capture parts of the selection criteria for use in the output expression.
+ The path expression used in the sequencer configuration example above shows a more complex example:
+ <programlisting>
+//(*.(jpg|jpeg|gif|bmp|pcx|png))[*]/jcr:content[@jcr:data] => /images/$1</programlisting>
+ This uses "//" to select any node at any level in the repository whose name ends with "." and one of the extensions (e.g., ".jpg", ".jpeg", etc.)
+ and that has a child node named "jcr:content" that has a "jcr:data" property. It also selects the file name
+ as the first capture group (the first set of parentheses) for use in the output expression.
+ In this example, any sequencer output is placed on a node with that same file name under the "/images" node.
+ </para>
+ <para></para>
+ <para>Other things are possible, too. For example, the name of the repository/workspace (as used by the <code>SessionFactory</code>)
+ may be specified at the beginning of the select criteria and/or the output expression. This means it's possible to place
+ the sequencer output in a different repository than the node being sequenced.</para>
+ <para>For more detail about sequencer path expressions, see the <code>org.jboss.dna.repository.sequencer.SequencerPathExpression</code>
+ class and the corresponding <code>org.jboss.dna.repository.sequencer.SequencerPathExpressionTest</code> test case.</para>
+ </note>
+ <para>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 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>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 ObservationService is pretty easy, especially if you reuse the same <code>SessionFactory</code>
+ supplied to the SequencingService. Here's an example:
+ <programlisting>
+this.observationService = new ObservationService(sessionFactory);
+this.observationService.getAdministrator().start();</programlisting>
+ </para>
+ <note>
+ <para>Both the ObservationService 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:
+ <programlisting>
+observationService.addListener(sequencingService);</programlisting>
</para>
+ <para>Finally, the observation service must be wired to monitor one or your JCR repositories. This is done with
+ one of the <code>monitor(...)</code> methods:
+ <programlisting>
+int eventTypes = Event.NODE_ADDED | Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED;
+observationService.monitor("Main Repository/Workspace1", eventTypes);</programlisting>
+ </para>
+ <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 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 process
+ 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:
+ <programlisting>
+// 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>
+ <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>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.</para>
<para>
- Most of the Java classes in the example really have nothing in particular to do with JBoss DNA. The <code>UserInterface</code>,
- <code>ConsoleInput</code>, and <code>ImageInfo</code> classes are there to just make the example easy to run.
- The interesting code is in <code>SequencingClient</code>.
+ The example is comprised of 3 classes and 1 interface, located in the
+ <code>src/main/java</code>
+ directory:
+ <programlisting>
+ org/jboss/example/dna/sequencers/ConsoleInput.java
+ /ImageInfo.java
+ /SequencingClient.java
+ /UserInterface.java</programlisting>
</para>
<para>
- The <code>SequencingClient</code> class contains several methods that work with the JBoss DNA components.
- One of these is the <code>ObservationService</code> that monitors JCR workspaces and serves as a broker
- for events describing sets of changes to those JCR workspaces.
+ <code>SequencingClient</code>
+ is the class that contains the main application.
+ <code>ImageInfo</code>
+ is a simple Java object that encapsulates metadata about an image (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 behaviour of the client automatically using conventional JUnit test cases, as demonstrated by the
+ code in the
+ <code>src/test/java</code>
+ directory:
+ <programlisting>
+ org/jboss/example/dna/sequencers/SequencingClientTest.java
+ /MockUserInterface.java</programlisting>
</para>
+ <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>
+public void startRepository() throws Exception {
+ if (this.repository == null) {
+ try {
-
- <para>Three of the most important concepts in the JCR API are the <emphasis>repository</emphasis> (represented
- by the <code>javax.jcr.Repository</code> interface), the <emphasis>workspace</emphasis> (represented by the
- <code>javax.jcr.Workspace</code> interface), and a <emphasis>session</emphasis> (represented by the
- <code>javax.jcr.Session</code> interface). A single repository can contain multiple workspaces, each of which
- contains a tree of nodes with properties and relationships that form a graph. A client connects to the repository
- by providing credentials and the name of the workspace they wish to use. If the client's credentials are
- authenticated, the repository returns a session that provides access to all the nodes in the workspace and
- methods for adding, changing or deleting nodes.
- </para>
- <para>A session in the JCR API is not thread-safe. In other words, it is designed to be used by a single thread.
- If multiple threads in an application are to concurrently use a single session, that application is responsible
- for ensuring that all access to the session is properly synchronized and controlled. Separate sessions,
- on the other hand, may be used concurrently and in isolation, although all committed changes to the workspace's
- nodes are immediately visible to all sessions using that workspace.</para>
- <note>
- <para>This design follows a very common pattern: establish a connection to a resource, use that connection,
- then close the connection. If you need to use the resource again, you must establish a new connection, use it,
- and close the connection. The Java Database Connectivity (JDBC) API uses a similar pattern
- with it's <code>java.sql.Connection</code> interface.
- </para>
- </note>
- <para>The challenge with this approach in JCR, however, is that the credentials must be used every time a
- session is to be created.
- session</para>
+ // 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) ...
+ JackrabbitNodeTypeManager mgr = (JackrabbitNodeTypeManager)this.keepAliveSession.getWorkspace().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.
+ <programlisting>
+public void shutdownRepository() throws Exception {
+ if (this.repository != null) {
+ try {
+ this.keepAliveSession.logout();
+ } finally {
+ this.repository = null;
+ this.keepAliveSession = null;
+ }
+ }
+}</programlisting>
+ </para>
+ <para>
+ The
+ <code>startDnaServices()</code>
+ method first starts the JCR repository (if it were 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>
+ ,
+ <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.
+ <programlisting>
+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);
+
+ // 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>
+ <para>
+ The
+ <code>shutdownDnaServices()</code>
+ method is pretty straightforward: it just calls shutdown on each of the services and waits until they terminate.
+ <programlisting>
+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>
+ <para>None of the other methods really do anything with JBoss DNA per se. 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:
+ <programlisting>
+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>
+ <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.
+ <programlisting>
+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>
+ <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>Review</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>
+
+<!-- ====================================================================================================
+ Chapter
+ ==================================================================================================== -->
<chapter id="custom_sequencers">
<title>Custom sequencers</title>
- <para></para>
+ <para>The current release of JBoss DNA comes with a single sequencer that extracts metadata from image files.
+ If you create your own sequencer implementation,
+ </para>
+ <note>
+ <para>The <code>dna-sequencer-images</code> project is a small, self-contained sequencer implementation that
+ has only the minimal dependencies. Starting with the source can modifying it may be the easiest way to get started.
+ See the subversion repository: <ulink url="http://anonsvn.jboss.org/repos/dna/trunk/sequencers/dna-sequencer-images/">http://anonsvn.jboss.org/repos/dna/trunk/sequencers/dna-sequencer-images/</ulink>
+ </para>
+ </note>
+ <para>The first step is to <ulink url="http://maven.apache.org/guides/getting-started/index.html#How_do_I_make_m...">create a new Maven 2 project</ulink>
+ for your sequencer, and specify the following in your project's <code>pom.xml</code> dependencies section:
+ <programlisting>
+<dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-common</artifactId>
+ <version>0.1</version>
+</dependency>
+<dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-spi</artifactId>
+ <version>0.1</version>
+</dependency>
+<dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+</dependency>
+</programlisting>
+ These are minimum dependencies required for compiling a sequencer. Of course, you'll have to add
+ other dependencies that your sequencer needs.</para>
+ <para>As for testing, you probably will want to add more dependencies. Here are some dependencies you may need,
+ depending upon how you want to test:
+<programlisting>
+<dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.4</version>
+ <scope>test</scope>
+</dependency>
+<dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-library</artifactId>
+ <version>1.1</version>
+ <scope>test</scope>
+</dependency>
+<!-- Logging with Log4J -->
+<dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.4.3</version>
+ <scope>test</scope>
+</dependency>
+<dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.14</version>
+ <scope>test</scope>
+</dependency>
+</programlisting>
+ If you want to test with JCR and with JBoss DNA, you'll need additional dependencies for these libraries.
+ Strictly speaking, the sequencers do not actually use JCR. Instead, they use interfaces defined in the <code>dna-spi</code> project.
+ This not only simplifies the sequencer implementation, it also dramatically simplifies testing.
+<programlisting>
+<dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-repository</artifactId>
+ <version>0.1</version>
+ <scope>test</scope>
+</dependency>
+<!-- Java Content Repository API -->
+<dependency>
+ <groupId>javax.jcr</groupId>
+ <artifactId>jcr</artifactId>
+ <version>1.0.1</version>
+ <scope>test</scope>
+</dependency>
+<!-- Apache Jackrabbit (JCR Implementation) -->
+<dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-api</artifactId>
+ <version>1.3.3</version>
+ <scope>test</scope>
+ <!-- Exclude these since they are included in JDK 1.5 -->
+ <exclusions>
+ <exclusion>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>xerces</groupId>
+ <artifactId>xercesImpl</artifactId>
+ </exclusion>
+ </exclusions>
+</dependency>
+<dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-core</artifactId>
+ <version>1.3.3</version>
+ <scope>test</scope>
+ <!-- Exclude these since they are included in JDK 1.5 -->
+ <exclusions>
+ <exclusion>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>xerces</groupId>
+ <artifactId>xercesImpl</artifactId>
+ </exclusion>
+ </exclusions>
+</dependency>
+</programlisting>
+ </para>
+ <sect1 id="custom_sequencer_implementation">
+ <title>Implementing the StreamSequencer interface</title>
+ <para></para>
+ </sect1>
</chapter>
+
+<!-- ====================================================================================================
+ Chapter
+ ==================================================================================================== -->
<chapter id="future_directions">
<title>Future directions</title>
- <para>What's next for JBoss DNA? Well, sequencers are just the beginning.
- Remember our <link linkend="architecture">architecture</link>?
- There are a lot of components on our roadmap, including federating
-
+ <para>What's next for JBoss DNA? Well, the sequencing system is just the beginning. With this release, the sequencing system
+ is stable enough so that more <link linkend="sequencers">sequencers</link> can be developed and used within your own applications.
+ If you're interested in getting involved with the JBoss DNA project, consider picking up one of the sequencers on our
+ <ulink url="http://jira.jboss.org/jira/browse/DNA?report=com.atlassian.jira.plugin.sy...">roadmap</ulink>.
+ Or, check out <ulink url="http://jira.jboss.org/jira/secure/IssueNavigator.jspa?reset=true&mode...">JIRA</ulink>
+ for the list of sequencers we've thought of. If you think of one that's not there, please add it to JIRA!
</para>
- <para> Roadmap: We'll start on the federation engine as soon as 0.1 is out. The 0.1 release will contain the sequencing
- system, and while there will be one sequencer, we hope the community will help build the ones they need. Serge has started
- on a Java sequencer, and MetaMatrix is starting on a sequencer for MetaMatrix models. Check out JIRA for the list of the
- ones we've thought of.</para>
- <para> Your need for a web UI is very typical, which is why we also want to create a web interface (and RESTful service) that
- presents data using "domain-specific" views - that is, views that are specific to the type of data and user role. For
- example, if a user is viewing database information, the views should be structured to show all the information for a table
- and its columns, keys, and indexes. (This is in contrast with a "generic" node-based view where there is one page that shows
- the table and only links to the other columns, keys, etc. See http://www.jcr-explorer.org/screenshots.html for an example of
- a "generic" web UI.)</para>
+ <para>
+ Other components on our roadmap include a web user interface, a REST-ful server, and a view system that allows domain-specific
+ views of information in the repository. These components are farter out on our roadmap, and at this time have not been
+ targeted to a particular release. If any of these are of interest to you, please get involved in the community.
+ </para>
+ <para>
+ Finally, during the early part of the next release, the JBoss DNA project will switch to use JDK 6. Java 5 is being
+ end-of-lifed, so we want to move to a supported JDK. However, a number of JBoss projects and products continue to
+ require Java 5, so our next release will most likely use JDK 6 with Java 5 compatibility.</para>
</chapter>
</book>
\ No newline at end of file
16 years
DNA SVN: r139 - trunk/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2008-05-09 19:00:40 -0400 (Fri, 09 May 2008)
New Revision: 139
Modified:
trunk/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/SequencingClient.java
Log:
Changed the example application to be more clear.
Modified: trunk/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/SequencingClient.java
===================================================================
--- trunk/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/SequencingClient.java 2008-05-09 23:00:12 UTC (rev 138)
+++ trunk/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/SequencingClient.java 2008-05-09 23:00:40 UTC (rev 139)
@@ -49,6 +49,7 @@
import org.jboss.dna.repository.util.JcrTools;
import org.jboss.dna.repository.util.SessionFactory;
import org.jboss.dna.repository.util.SimpleExecutionContext;
+import org.jboss.dna.repository.util.SimpleSessionFactory;
/**
* @author Randall Hauch
@@ -64,7 +65,7 @@
public static void main( String[] args ) throws Exception {
SequencingClient client = new SequencingClient();
- client.setRepositoryInformation(DEFAULT_REPOSITORY_NAME, DEFAULT_WORKSPACE_NAME, "jsmith", "secret".toCharArray());
+ client.setRepositoryInformation(DEFAULT_REPOSITORY_NAME, DEFAULT_WORKSPACE_NAME, DEFAULT_USERNAME, DEFAULT_PASSWORD);
client.setUserInterface(new ConsoleInput(client));
}
@@ -197,13 +198,13 @@
// for the DNA services which knows about the JCR repositories, workspaces, and credentials used to
// establish sessions to these workspaces. This example uses the SimpleExecutionContext, but there is
// implementation for use with JCR repositories registered in JNDI.
- SimpleExecutionContext executionContext = new SimpleExecutionContext();
- executionContext.registerRepository(this.repositoryName, this.repository);
+ SimpleSessionFactory sessionFactory = new SimpleSessionFactory();
+ sessionFactory.registerRepository(this.repositoryName, this.repository);
if (this.username != null) {
Credentials credentials = new SimpleCredentials(this.username, this.password);
- executionContext.registerCredentials(this.repositoryName + "/" + this.workspaceName, credentials);
+ sessionFactory.registerCredentials(this.repositoryName + "/" + this.workspaceName, credentials);
}
- this.executionContext = executionContext;
+ this.executionContext = new SimpleExecutionContext(sessionFactory);
// Create the sequencing service, passing in the execution context ...
this.sequencingService = new SequencingService();
16 years
DNA SVN: r138 - trunk/docs/examples/gettingstarted/sequencers/src/test/resources.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2008-05-09 19:00:12 -0400 (Fri, 09 May 2008)
New Revision: 138
Modified:
trunk/docs/examples/gettingstarted/sequencers/src/test/resources/log4j.properties
Log:
Added test Log4J properties file.
Property changes on: trunk/docs/examples/gettingstarted/sequencers/src/test/resources/log4j.properties
___________________________________________________________________
Name: svn:mime-type
+ text/plain
16 years
DNA SVN: r137 - trunk/dna-repository/src/main/java/org/jboss/dna/repository/util.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2008-05-09 18:59:25 -0400 (Fri, 09 May 2008)
New Revision: 137
Modified:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleExecutionContext.java
Log:
Changed the SimpleExecutionContext to not extend SimpleSessionFactory but to instead delegate to a SessionFactory supplied in the constructor.
Modified: trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleExecutionContext.java
===================================================================
--- trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleExecutionContext.java 2008-05-09 22:58:33 UTC (rev 136)
+++ trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleExecutionContext.java 2008-05-09 22:59:25 UTC (rev 137)
@@ -21,22 +21,26 @@
*/
package org.jboss.dna.repository.util;
+import org.jboss.dna.common.util.ArgCheck;
+
/**
* @author Randall Hauch
*/
-public class SimpleExecutionContext extends SimpleSessionFactory implements ExecutionContext {
+public class SimpleExecutionContext implements ExecutionContext {
private final JcrTools tools = new JcrTools();
+ private final SessionFactory sessionFactory;
- public SimpleExecutionContext() {
- super();
+ public SimpleExecutionContext( SessionFactory sessionFactory ) {
+ ArgCheck.isNotNull(sessionFactory, "session factory");
+ this.sessionFactory = sessionFactory;
}
/**
* {@inheritDoc}
*/
public SessionFactory getSessionFactory() {
- return this;
+ return this.sessionFactory;
}
/**
16 years
DNA SVN: r136 - trunk/sequencers/dna-sequencer-images.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2008-05-09 18:58:33 -0400 (Fri, 09 May 2008)
New Revision: 136
Modified:
trunk/sequencers/dna-sequencer-images/pom.xml
Log:
Eliminated unused dependencies.
Modified: trunk/sequencers/dna-sequencer-images/pom.xml
===================================================================
--- trunk/sequencers/dna-sequencer-images/pom.xml 2008-05-09 03:47:36 UTC (rev 135)
+++ trunk/sequencers/dna-sequencer-images/pom.xml 2008-05-09 22:58:33 UTC (rev 136)
@@ -26,13 +26,6 @@
</dependency>
<dependency>
<groupId>org.jboss.dna</groupId>
- <artifactId>dna-common</artifactId>
- <version>0.1-SNAPSHOT</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.jboss.dna</groupId>
<artifactId>dna-spi</artifactId>
</dependency>
<!--
@@ -46,14 +39,6 @@
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
</dependency>
- <dependency>
- <groupId>org.jmock</groupId>
- <artifactId>jmock</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jmock</groupId>
- <artifactId>jmock-junit4</artifactId>
- </dependency>
<!--
Logging (require SLF4J API for compiling, but use Log4J and its SLF4J binding for testing)
-->
@@ -76,24 +61,6 @@
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
</dependency>
- <!--
- Java Content Repository API
- -->
- <dependency>
- <groupId>javax.jcr</groupId>
- <artifactId>jcr</artifactId>
- </dependency>
- <!--
- Apache Jackrabbit (JCR Implementation) for testing purposes
- -->
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>jackrabbit-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>jackrabbit-core</artifactId>
- </dependency>
</dependencies>
<reporting>
<plugins>
16 years
DNA SVN: r135 - trunk/docs/gettingstarted/en.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2008-05-08 23:47:36 -0400 (Thu, 08 May 2008)
New Revision: 135
Modified:
trunk/docs/gettingstarted/en/master.xml
Log:
Changes and additional copy
Modified: trunk/docs/gettingstarted/en/master.xml
===================================================================
--- trunk/docs/gettingstarted/en/master.xml 2008-05-08 22:00:44 UTC (rev 134)
+++ trunk/docs/gettingstarted/en/master.xml 2008-05-09 03:47:36 UTC (rev 135)
@@ -162,10 +162,10 @@
<link linkend="jboss_dna">next chapter</link>
in this book goes into more detail about JBoss DNA and its architecture, the different components, what's available now, and
what's coming in future releases.
- <link linkend="downloading">Chapter 3</link>
- then provides instructions for downloading and compiling the sequencer examples for the current release.
+ <link linkend="downloading_and_running">Chapter 3</link>
+ then provides instructions for downloading and running the sequencer examples for the current release.
<link linkend="using_dna">Chapter 4</link>
- walks through these examples, while
+ walks through how to use JBoss DNA in your applications, while
<link linkend="custom_sequencers">Chapter 5</link>
goes over how to create custom sequencers. Finally,
<link linkend="future_directions">Chapter 6</link>
@@ -195,15 +195,14 @@
<para>The architecture for JBoss DNA consists of several major components that will be built on top of standard APIs,
including JCR, JDBC, JNDI and HTTP. The goal is to allow these components to be assembled as needed and add value on top
of other DNA components or third-party systems that support the standard APIs.</para>
- <!-- mediaobject>
- <imageobject>
+ <mediaobject>
+ <imageobject role="fo">
<imagedata align="center" fileref="images/dna-architecture.png"/>
</imageobject>
- </mediaobject -->
- <figure id="dna-architecture">
- <title>JBoss DNA Architecture</title>
- <graphic align="center" scale="60" fileref="images/dna-architecture.png" />
- </figure>
+ <imageobject role="html">
+ <imagedata align="center" fileref="images/dna-architecture.png"/>
+ </imageobject>
+ </mediaobject>
<para>
As shown in the diagram above, the major components are (starting at the top):
<itemizedlist>
@@ -304,8 +303,20 @@
</listitem>
</itemizedlist>
</para>
+ <para>
+ Continue reading the rest of this chapter for more detail about the
+ <link linkend="sequencers">sequencing framework</link>
+ available in this release, or the
+ <link linkend="federation">federation engine</link>
+ and
+ <link linkend="federation_connectors">connectors</link>
+ that will be the focus of the next release. Or, skip to the
+ <link linkend="downloading_and_running">examples</link>
+ to see how to start using JBoss DNA &versionNumber;
+ today.
+ </para>
</sect1>
- <sect1>
+ <sect1 id="sequencers">
<title>Sequencers</title>
<para> The current JBoss DNA release contains a sequencing framework that is designed to sequence data (typically files)
stored in a JCR repository to automatically extract meaningful and useful information. This additional information is then
@@ -451,7 +462,7 @@
goes into detail about how to write custom sequencers.
</para>
</sect1>
- <sect1>
+ <sect1 id="federation">
<title>Federation</title>
<para>There is a lot of information stored in many of different places: databases, repositories, SCM systems,
registries, file systems, services, etc. The purpose of the federation engine is to allow applications to use the JCR API
@@ -474,7 +485,7 @@
changes, client applications using JCR observation will be notified of the changes. If a JBoss DNA federated repository is
configured to allow updates, client applications can change the information in the repository and JBoss DNA will propagate
those changes down to the original source.</para>
- <sect2>
+ <sect2 id="federation_connectors">
<title>Connectors</title>
<para>
The JBoss DNA federation engine will use connectors to interact with different information sources to get at the content
@@ -553,7 +564,7 @@
provide an implementation.
</para>
</sect2>
- <sect2>
+ <sect2 id="federation_sources">
<title>Sources</title>
<para>
Each JBoss DNA federated repository is configured to federate and integrate information from one or more
@@ -564,7 +575,7 @@
federated repository.
</para>
</sect2>
- <sect2>
+ <sect2 id="federation_graph">
<title>Building the unified graph</title>
<para> The federation engine works by effectively building up a single graph by querying each source and merging or
unifying the responses. This information is cached, which improves performance, reduces the number of (potentially
@@ -593,7 +604,7 @@
or the frequent checking with the source.
</para>
</sect2>
- <sect2>
+ <sect2 id="federation_queries">
<title>Queries</title>
<para> The JBoss DNA federated repository will also support queries against the integrated and unified graph. In some
situations the query can be determined to apply to a single source, but in most situations the query must be planned
@@ -604,7 +615,7 @@
implements sophisticated query planning and optimization techniques for working efficiently with multiple sources.
</para>
</sect2>
- <sect2>
+ <sect2 id="federation_updates">
<title>Updates</title>
<para>
The JBoss DNA federated repositories also make it possible for client applications to make changes to the unified graph
@@ -627,7 +638,7 @@
changes to other clients.)
</para>
</sect2>
- <sect2>
+ <sect2 id="federation_events">
<title>Events</title>
<para> The JCR API supports observing a repository to receive notifications of additions, changes and deletions of nodes
and properties. The JBoss DNA federated repository will support this API through two primary means.</para>
@@ -645,27 +656,26 @@
<!-- ====================================================================================================
Chapter
==================================================================================================== -->
- <chapter id="downloading">
- <title>Downloading the examples</title>
+ <chapter id="downloading_and_running">
+ <title>Example application</title>
<para>JBoss DNA is built using Maven 2, so it's much easier to following along with the examples in this document if you
install and configure Maven. Once this is done, you can very easily build the examples or even create a maven project that
depends on the JBoss DNA JARs. Maven will automatically download the right versions of the JARs, including those other
libraries on which JBoss DNA depends. Maven also makes it very easy to create an assembly of your final application so that
you can package into a distributable form.</para>
- <para>
- The examples created for this User Guide use Maven2 to achieve exactly this so it is highly recommended that you
- <ulink url="http://www.jboss.org/file-access/default/members/dna/downloads/0.1/jboss-...">download</ulink>
- these first and take a look at how they work.
- </para>
<note>
<para>
- To build and run the examples you first need to install and configure Maven 2.0.7 (or higher), available from
+ To use Maven with JBoss DNA, you'll first need to install
+ <ulink url="http://java.sun.com/javase/downloads/index_jdk5.jsp">JDK 5</ulink>
+ and Maven 2.0.7 (or higher), which is available from
<ulink url="http://maven.apache.org/">http://maven.apache.org/</ulink>
+ .
</para>
- <para>Installation is performed by downloading and unzipping the maven-2.0.7-bin.zip file to a convenient
- location on your local disk. Configuration consists of adding $MAVEN_HOME/bin to your path and adding the following
- profile to your ~/.m2/settings.xml file:</para>
- <programlisting role="XML" language="xml"><settings>
+ <para>
+ Maven is installed by downloading and unzipping the maven-2.0.7-bin.zip file to a convenient location on your local disk.
+ Configuration consists of adding $MAVEN_HOME/bin to your path and adding the following profile to your ~/.m2/settings.xml
+ file:
+ <programlisting role="XML" language="xml"><settings>
<profiles>
<profile>
<id>jboss.repository</id>
@@ -709,14 +719,35 @@
</profile>
</profiles>
</settings></programlisting>
- <para>This profile informs Maven of the two JBoss repositories (snapshots and releases) that are needed to download the JARs for JBoss DNA and all dependent libraries.</para>
+ This profile informs Maven of the two JBoss repositories (snapshots and releases) that contain
+ all of the JARs for JBoss DNA and all dependent libraries.</para>
</note>
- <para>After you have configured Maven and extracted the examples to a working folder, you can go to the <code>examples</code>
- subdirectory and enter <code>mvn install</code> to perform a build. Maven will automatically download all of the libraries
- that are needed by the build, saving them to your local machine. (This means the next time you run <code>mvn install</code>,
- all the libraries will be local, and the build will run much faster.)
+ <sect1 id="downloading">
+ <title>Downloading and compiling</title>
+ <para>The next step is to <ulink url="http://www.jboss.org/file-access/default/members/dna/downloads/0.1/jboss-...">download</ulink>
+ the example for this Getting Started guide, and extract the contents to a convenient location on your local disk.
+ You'll find the example contains the following files, which are organized according to the standard Maven directory structure:
+ <programlisting>
+examples/pom.xml
+ sequencers/pom.xml
+ /src/main/assembly
+ /config
+ /java
+ /resources
+ /test/java
+ /resources
+ </programlisting>
</para>
- <para>The build is successful if you see the following:</para>
+ <para>There are essentially two Maven projects: a <code>sequencers</code> project and a parent project. All of the source
+ for the examples are located in the <code>sequencers</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>.
+ This command downloads all of the JARs necessary to compile and build the example, including the JBoss DNA libraries,
+ the libraries they depend on, and any missing Maven components. (These are downloaded from the JBoss repositories
+ only once, and saved on your machine. This means that the next time you run Maven, all the libraries will
+ already be available locally, and the build will run much faster.) The command then continues by compiling the example's source
+ code (and unit tests) and running the unit tests. The build is successful if you see the following:
<programlisting language="bash">$ mvn install
...
[INFO] ------------------------------------------------------------------------
@@ -733,64 +764,8 @@
[INFO] Final Memory: 14M/28M
[INFO] ------------------------------------------------------------------------
$ </programlisting>
- <para>If there are errors, check whether you have the correct version of Maven installed and that you've correctly updated
+ 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>
- The <link linkend="using_dna">next chapter</link> shows you how to run the examples and walks through the source code to
- show you how to use JBoss DNA.</para>
- </chapter>
-<chapter id="using_dna">
- <title>Using JBoss DNA</title>
- <para>With this release, JBoss DNA is able to monitor existing JCR repositories and automatically sequence newly upload files and updated content.
- The information produced by the sequencers is saved to the repository, making it available to any repository client.
- Using JBoss DNA, therefore, consists of setting up the DNA Java components and connecting them to the JCR repositories.
- This chapter walks you through this process, using the examples downloaded in the <link linkend="downloading">previous chapter</link>.
- </para>
- <para>You will find all of the necessary files for the example in the <code>examples/sequencers</code> directory, which follows the
- Maven Standard Directory Layout:
- <programlisting>
-sequencers/pom.xml
- /src/main/assembly
- /config
- /java
- /resources
- /test/java
- /resources
- </programlisting>
- </para>
- <para>This 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 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.
- </para>
- <para>The example is comprised of 3 classes and 1 interface, located in the <code>src/main/java</code> directory:
- <programlisting>
-org/jboss/example/dna/sequencers/ConsoleInput.java
- /ImageInfo.java
- /SequencingClient.java
- /UserInterface.java
- </programlisting>
- </para>
- <para>
- <code>SequencingClient</code> is the class that contains the main application. <code>ImageInfo</code> is a simple
- Java object that encapsulates metadata about an image (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 behaviour of the client automatically using conventional
- JUnit test cases, as demonstrated by the code in the <code>src/test/java</code> directory:
- <programlisting>
-org/jboss/example/dna/sequencers/SequencingClientTest.java
- /MockUserInterface.java
- </programlisting>
- </para>
- <sect1 id="running_examples">
- <title>Running the example</title>
- <para>
- As mentioned in the <ulink url="downloading">previous chapter</ulink>, simply type <code>mvn package</code> from the <code>example/sequencer</code>
- directory to compile the source code, run the unit tests, build a client JAR and assemble a distribution containing all of the necessary files.
- </para>
<para>If you successfully built the examples, there will be a <code>examples/sequencers/target/dna-example-sequencers-basic.dir/</code>
directory that contains the following:
<itemizedlist>
@@ -854,42 +829,94 @@
</para>
</note>
</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
+ 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.</para>
<para>
- 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="images/example-sequencer-cli-client.png" />
- </figure>
- From this menu, you can upload a file into the repository, search for images in the repository, print sequencing statistics, or quit the application.
+ 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="images/example-sequencer-cli-client.png" />
+ </figure>
+ From this menu, you can upload a file into the repository, search for images in the repository, print sequencing statistics,
+ or quit the application.
</para>
<para>
- The first step is to upload one of the example images. If you type 'u' and press return, you'll be prompted
- to supply the path to the file you want to upload. Since the application is running from within the
- <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>
- <graphic align="center" scale="100" fileref="images/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 specified. The example client configures JBoss DNA to sequence image files (technically nodes that have names)
- with one of the following
- extensions: <code>jpg</code>, <code>jpeg</code>, <code>gif</code>, <code>bmp</code>,
- <code>pcx</code>, <code>png</code>, <code>iff</code>, <code>ras</code>, <code>pbm</code>, <code>pgm</code>, <code>ppm</code>, and <code>psd</code>.
- Files with other extensions in the repository path will be ignored. For your convenience, the example provides
- several files that will be sequenced (<code>caution.png</code>, <code>caution.jpg</code> and <code>caution.gif</code>)
- and one image that will not be sequenced (<code>caution.pict</code>). Feel free to try other files.
+ The first step is to upload one of the example images. If you type 'u' and press return, you'll be prompted to supply the
+ path to the file you want to upload. Since the application is running from within the
+ <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>
+ <graphic align="center" scale="100" fileref="images/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
+ specified. The example client configures JBoss DNA to sequence image files (technically nodes that have names) with one of
+ the following extensions:
+ <code>jpg</code>
+ ,
+ <code>jpeg</code>
+ ,
+ <code>gif</code>
+ ,
+ <code>bmp</code>
+ ,
+ <code>pcx</code>
+ ,
+ <code>png</code>
+ ,
+ <code>iff</code>
+ ,
+ <code>ras</code>
+ ,
+ <code>pbm</code>
+ ,
+ <code>pgm</code>
+ ,
+ <code>ppm</code>
+ , and
+ <code>psd</code>
+ . Files with other extensions in the repository path will be ignored. For your convenience, the example provides several
+ files that will be sequenced (
+ <code>caution.png</code>
+ ,
+ <code>caution.jpg</code>
+ and
+ <code>caution.gif</code>
+ ) and one image that will not be sequenced (
+ <code>caution.pict</code>
+ ). Feel free to try other files.
</para>
<para>
- After you specified the file you want to upload, the example application asks you where in the repository you'd
- like to place the file. (If you want to use the suggested location, just press <code>return</code>.)
- The client application uses the JCR API to upload the file to that location in the repository, creating any nodes (of type <code>nt:folder</code>)
- for any directories that don't exist, and creating a node (of type <code>nt:file</code>) for the file. And,
- per the JCR specification, the application creates a <code>jcr:content</code> node (of type <code>nt:resource</code>)
- under the file node. The file contents are placed on this <code>jcr:content</code> node in the <code>jcr:data</code> property.
- For example, if you specify <code>/a/b/caution.png</code>, the following structure will be created in the repository:
- <programlisting>
+ After you specified the file you want to upload, the example application asks you where in the repository you'd like to
+ place the file. (If you want to use the suggested location, just press
+ <code>return</code>
+ .) The client application uses the JCR API to upload the file to that location in the repository, creating any nodes (of
+ type
+ <code>nt:folder</code>
+ ) for any directories that don't exist, and creating a node (of type
+ <code>nt:file</code>
+ ) for the file. And, per the JCR specification, the application creates a
+ <code>jcr:content</code>
+ node (of type
+ <code>nt:resource</code>
+ ) under the file node. The file contents are placed on this
+ <code>jcr:content</code>
+ node in the
+ <code>jcr:data</code>
+ property. For example, if you specify
+ <code>/a/b/caution.png</code>
+ , the following structure will be created in the repository:<programlisting>
/a (nt:folder)
/b (nt:folder)
/caution.png (nt:file)
@@ -899,14 +926,15 @@
@jcr:lastModified = {now}
</programlisting>
</para>
- <para>
- When the client uploads the file using the JCR API, DNA gets notified of the changes, consults the sequencers
- to see whether any of them are interested in the new or updated content, and if so runs the sequencers. The image
- sequencer processes image files for metadata, and any metadata found is stored under the <code>/images</code>
- branch of the repository. All of this happens asynchronously, so any DNA activity doesn't impede or slow
- down the client activities.
- </para>
- <para>
+ <para>
+ When the client uploads the file using the JCR API, DNA gets notified of the changes, consults the sequencers to see whether
+ any of them are interested in the new or updated content, and if so runs the sequencers. The image sequencer processes image
+ files for metadata, and any metadata found is stored under the
+ <code>/images</code>
+ branch of the repository. All of this happens asynchronously, so any DNA activity doesn't impede or slow down the client
+ 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>Uploading an image using the Example Client</title>
@@ -917,20 +945,71 @@
<title>Uploading an image using the Example Client</title>
<graphic align="center" scale="100" fileref="images/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 criteria.</para>
- <note>
- <para>There will probably be more nodes skipped than sequenced, since there are more <code>nt:folder</code>
- and <code>nt:resource</code> nodes than there are <code>nt:file</code> nodes with acceptible names.
- </para>
- </note>
+ These stats show how many nodes were sequenced, and how many nodes were skipped because they didn't apply to the sequencer's
+ criteria.
+ </para>
+ <note>
<para>
- You can repeat this process with other files. Any file that isn't an image (as recognized by the sequencing configuration
- described later) will not be sequenced.
+ There will probably be more nodes skipped than sequenced, since there are more
+ <code>nt:folder</code>
+ and
+ <code>nt:resource</code>
+ nodes than there are
+ <code>nt:file</code>
+ nodes with acceptible names.
</para>
+ </note>
+ <para>You can repeat this process with other files. Any file that isn't an image (as recognized by the sequencing configuration
+ that we'll describe later) will not be sequenced.</para>
</sect1>
- <sect1 id="example_java_code">
- <title>Reviewing the Java code</title>
+ </chapter>
+
+
+
+
+
+ <!-- ====================================================================================================
+ Chapter
+ ==================================================================================================== -->
+<chapter id="using_dna">
+ <title>Using JBoss DNA</title>
+ <para></para>
+
+
+ <para>This 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 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.
+ </para>
+ <para>The example is comprised of 3 classes and 1 interface, located in the <code>src/main/java</code> directory:
+ <programlisting>
+org/jboss/example/dna/sequencers/ConsoleInput.java
+ /ImageInfo.java
+ /SequencingClient.java
+ /UserInterface.java
+ </programlisting>
+ </para>
+ <para><code>SequencingClient</code> is the class that contains the main application. <code>ImageInfo</code> is a simple
+ Java object that encapsulates metadata about an image (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 behaviour of the client automatically using conventional
+ JUnit test cases, as demonstrated by the code in the <code>src/test/java</code> directory:
+ <programlisting>
+org/jboss/example/dna/sequencers/SequencingClientTest.java
+ /MockUserInterface.java
+ </programlisting>
+ </para>
+
+<!-- Reviewing the code -->
+ <para>The example application you just used demonstrated how JBoss DNA sequencing responds
+ to the changes in a repository. This example doesn't do much, but the con </para>
+
+ <para>The example application you just used demonstrated how JBoss DNA sequencing responds
+ to the changes in a repository. This example was pretty simple, but </para>
+
<para>The example you just ran demonstrated that JBoss DNA does sequence image files. It does everything
necessary to set up and configure JBoss DNA to use a JCR repository, so reviewing that code can help understand
what's involved.
@@ -940,15 +1019,43 @@
<code>ConsoleInput</code>, and <code>ImageInfo</code> classes are there to just make the example easy to run.
The interesting code is in <code>SequencingClient</code>.
</para>
-
<para>
+ The <code>SequencingClient</code> class contains several methods that work with the JBoss DNA components.
+ One of these is the <code>ObservationService</code> that monitors JCR workspaces and serves as a broker
+ for events describing sets of changes to those JCR workspaces.
</para>
- </sect1>
+
+ <para>Three of the most important concepts in the JCR API are the <emphasis>repository</emphasis> (represented
+ by the <code>javax.jcr.Repository</code> interface), the <emphasis>workspace</emphasis> (represented by the
+ <code>javax.jcr.Workspace</code> interface), and a <emphasis>session</emphasis> (represented by the
+ <code>javax.jcr.Session</code> interface). A single repository can contain multiple workspaces, each of which
+ contains a tree of nodes with properties and relationships that form a graph. A client connects to the repository
+ by providing credentials and the name of the workspace they wish to use. If the client's credentials are
+ authenticated, the repository returns a session that provides access to all the nodes in the workspace and
+ methods for adding, changing or deleting nodes.
+ </para>
+ <para>A session in the JCR API is not thread-safe. In other words, it is designed to be used by a single thread.
+ If multiple threads in an application are to concurrently use a single session, that application is responsible
+ for ensuring that all access to the session is properly synchronized and controlled. Separate sessions,
+ on the other hand, may be used concurrently and in isolation, although all committed changes to the workspace's
+ nodes are immediately visible to all sessions using that workspace.</para>
+ <note>
+ <para>This design follows a very common pattern: establish a connection to a resource, use that connection,
+ then close the connection. If you need to use the resource again, you must establish a new connection, use it,
+ and close the connection. The Java Database Connectivity (JDBC) API uses a similar pattern
+ with it's <code>java.sql.Connection</code> interface.
+ </para>
+ </note>
+ <para>The challenge with this approach in JCR, however, is that the credentials must be used every time a
+ session is to be created.
+ session</para>
+
+
</chapter>
<chapter id="custom_sequencers">
<title>Custom sequencers</title>
16 years