Author: rhauch
Date: 2008-05-07 16:43:55 -0400 (Wed, 07 May 2008)
New Revision: 122
Added:
trunk/docs/examples/gettingstarted/sequencers/src/test/java/org/jboss/example/dna/sequencers/MockUserInterface.java
trunk/docs/gettingstarted/en/images/example-sequencer-cli-client.png
trunk/docs/gettingstarted/en/images/example-sequencer-search.png
trunk/docs/gettingstarted/en/images/example-sequencer-search2.png
trunk/docs/gettingstarted/en/images/example-sequencer-statistics.png
trunk/docs/gettingstarted/en/images/example-sequencer-statistics2.png
trunk/docs/gettingstarted/en/images/example-sequencer-upload.png
trunk/docs/gettingstarted/en/images/example-sequencer-upload2.png
Modified:
trunk/build/assembly/examples.xml
trunk/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/ConsoleInput.java
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/UserInterface.java
trunk/docs/examples/gettingstarted/sequencers/src/test/java/org/jboss/example/dna/sequencers/SequencingClientTest.java
trunk/docs/gettingstarted/en/master.xml
Log:
Update the sequencing example and Getting Started document.
Modified: trunk/build/assembly/examples.xml
===================================================================
--- trunk/build/assembly/examples.xml 2008-05-07 16:26:20 UTC (rev 121)
+++ trunk/build/assembly/examples.xml 2008-05-07 20:43:55 UTC (rev 122)
@@ -1,5 +1,5 @@
<assembly>
- <id>examples</id>
+ <id>gettingstarted-examples</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<!--<format>tar.gz</format>
Modified:
trunk/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/ConsoleInput.java
===================================================================
---
trunk/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/ConsoleInput.java 2008-05-07
16:26:20 UTC (rev 121)
+++
trunk/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/ConsoleInput.java 2008-05-07
20:43:55 UTC (rev 122)
@@ -25,6 +25,7 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.net.URL;
import java.util.List;
import java.util.Map;
import org.jboss.dna.repository.sequencers.SequencingService;
@@ -134,7 +135,10 @@
return buffer.toString();
}
- public File getPathOfFileToUpload() throws IllegalArgumentException, IOException {
+ /**
+ * {@inheritDoc}
+ */
+ public URL getFileToUpload() throws IllegalArgumentException, IOException {
System.out.println("Please enter the file to upload:");
String path = in.readLine();
File file = new File(path);
@@ -147,7 +151,7 @@
if (!file.isFile()) {
throw new IllegalArgumentException("Please specify a file. The file
\"" + file.getAbsolutePath() + "\" is a directory.");
}
- return file;
+ return file.toURL();
}
public String getRepositoryPath( String defaultPath ) throws
IllegalArgumentException, IOException {
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-07
16:26:20 UTC (rev 121)
+++
trunk/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/SequencingClient.java 2008-05-07
20:43:55 UTC (rev 122)
@@ -22,8 +22,6 @@
package org.jboss.example.dna.sequencers;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
@@ -50,6 +48,7 @@
import org.jboss.dna.repository.sequencers.SequencingService;
import org.jboss.dna.repository.util.ExecutionContext;
import org.jboss.dna.repository.util.JcrTools;
+import org.jboss.dna.repository.util.SessionFactory;
import org.jboss.dna.repository.util.SimpleExecutionContext;
/**
@@ -90,10 +89,6 @@
setRepositoryInformation(DEFAULT_REPOSITORY_NAME, DEFAULT_WORKSPACE_NAME,
DEFAULT_USERNAME, DEFAULT_PASSWORD);
}
- public void setUserInterface( UserInterface userInterface ) {
- this.userInterface = userInterface;
- }
-
protected void setWorkingDirectory( String workingDirectoryPath ) {
this.workingDirectory = workingDirectoryPath != null ? workingDirectoryPath :
DEFAULT_WORKING_DIRECTORY;
}
@@ -112,6 +107,18 @@
this.password = password;
}
+ /**
+ * Set the user interface that this client should use.
+ * @param userInterface
+ */
+ public void setUserInterface( UserInterface userInterface ) {
+ this.userInterface = userInterface;
+ }
+
+ /**
+ * Start up the JCR repository. This method only operates using the JCR API and
Jackrabbit-specific API.
+ * @throws Exception
+ */
public void startRepository() throws Exception {
if (this.repository == null) {
try {
@@ -163,6 +170,10 @@
}
}
+ /**
+ * Shutdown the repository. This method only uses the JCR API.
+ * @throws Exception
+ */
public void shutdownRepository() throws Exception {
if (this.repository != null) {
try {
@@ -174,93 +185,125 @@
}
}
+ /**
+ * Start the DNA services.
+ * @throws Exception
+ */
public void startDnaServices() throws Exception {
if (this.repository == null) {
this.startRepository();
}
- if (this.sequencingService != null) {
- return;
- }
- // Create an execution context for the sequencing service.
- // The repository instances and workspace names are registered, and that the
service will reference.
- // the repository ...
- SimpleExecutionContext executionContext = new SimpleExecutionContext();
- // Register the JCR repository ...
- executionContext.registerRepository(this.repositoryName, this.repository);
- if (this.username != null) {
- Credentials credentials = new SimpleCredentials(this.username,
this.password);
- executionContext.registerCredentials(this.repositoryName + "/" +
this.workspaceName, credentials);
- }
- this.executionContext = executionContext;
+ if (this.sequencingService == null) {
- // Create the sequencing service ...
- this.sequencingService = new SequencingService();
- this.sequencingService.setExecutionContext(executionContext);
+ // Create an execution context for the sequencing service. This execution
context provides an environment
+ // 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);
+ if (this.username != null) {
+ Credentials credentials = new SimpleCredentials(this.username,
this.password);
+ executionContext.registerCredentials(this.repositoryName + "/"
+ this.workspaceName, credentials);
+ }
+ this.executionContext = executionContext;
- // Add the configuration for the image sequencer. This sequencer class should be
on the thread's current context class
- // loader, or if that's null the classloader that loaded the
SequencingService class.
- //
- // The path expressions tell the service that this sequencer should be invoked on
the "jcr:data" property
- // on the "jcr:content" child node of any node uploaded to the
repository whose name ends with one of the
- // supported extensions, and it should place the output metadata in a node with
the same name as the file
- // but immediately below the "/images" node. Path expressions can be
fairly complex, and can even
- // specify that the generated information be placed in a different repository.
- //
- // Sequencers can be added before or after the service is started.
- 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 =
{"//(*.(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);
+ // Create the sequencing service, passing in the execution context ...
+ this.sequencingService = new SequencingService();
+ this.sequencingService.setExecutionContext(executionContext);
+ // Configure the sequencers. In this example, we only use a single sequencer
that processes image files.
+ // So create a configuration. Note that the sequencing service expects the
class to be on the thread's current context
+ // classloader, or if that's null the classloader that loaded the
SequencingService class.
+ //
+ // Part of the configuration includes telling DNA which JCR paths should be
processed by the sequencer.
+ // These path expressions tell the service that this sequencer should be
invoked on the "jcr:data" property
+ // on the "jcr:content" child node of any node uploaded to the
repository whose name ends with one of the
+ // supported extensions, and the sequencer should place the generated output
metadata in a node with the same name as
+ // the file but immediately below the "/images" node. Path
expressions can be fairly complex, and can even
+ // specify that the generated information be placed in a different
repository.
+ //
+ // Sequencer configurations can be added before or after the service is
started, but here we do it before the service
+ // is running.
+ 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();
-
- // Register the sequencing service as a listener using the 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);
}
+ /**
+ * Shut down the DNA services.
+ * @throws Exception
+ */
public void shutdownDnaServices() throws Exception {
if (this.sequencingService == null) return;
- try {
- // 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 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);
-
- } finally {
- this.sequencingService = null;
- this.observationService = null;
- }
+ // Shut down the observation service ...
+ this.observationService.getAdministrator().shutdown();
+ this.observationService.getAdministrator().awaitTermination(5,
TimeUnit.SECONDS);
}
+ /**
+ * Get the sequencing statistics.
+ * @return the statistics; never null
+ */
public SequencingService.Statistics getStatistics() {
return this.sequencingService.getStatistics();
}
+ /**
+ * Prompt the user interface for the file to upload into the JCR repository, then
upload it using the JCR API.
+ * @throws Exception
+ */
public void uploadFile() throws Exception {
- File file = this.userInterface.getPathOfFileToUpload();
- String nodePath = this.userInterface.getRepositoryPath("/a/b/" +
file.getName());
- String mimeType = getMimeType(file);
- uploadFile(new FileInputStream(file), nodePath, mimeType);
+ URL url = this.userInterface.getFileToUpload();
+ // Grab the last segment of the URL path, using it as the filename
+ String filename = url.getPath().replaceAll("([^/]*/)*", "");
+ String nodePath = this.userInterface.getRepositoryPath("/a/b/" +
filename);
+ String mimeType = getMimeType(url);
+
+ // Now use the JCR API to upload the file ...
+ Session session = createSession();
+ JcrTools tools = this.executionContext.getTools();
+ try {
+ // Create the node at the supplied path ...
+ Node node = tools.findOrCreateNode(session, nodePath, "nt:folder",
"nt:file");
+
+ // Upload the file to that node ...
+ Node contentNode = tools.findOrCreateChild(session, node,
"jcr:content", "nt:resource");
+ contentNode.setProperty("jcr:mimeType", mimeType);
+ contentNode.setProperty("jcr:lastModified",
Calendar.getInstance());
+ contentNode.setProperty("jcr:data", url.openStream());
+
+ // Save the session ...
+ session.save();
+ } finally {
+ session.logout();
+ }
}
+ /**
+ * Perform a search of the repository for all image metadata automatically created by
the image sequencer.
+ * @throws Exception
+ */
public void search() throws Exception {
- List<ImageInfo> images = getImages();
- // Display the search results ...
- this.userInterface.displaySearchResults(images);
- }
-
- protected List<ImageInfo> getImages() throws Exception {
+ // Use JCR to search the repository for image metadata ...
List<ImageInfo> images = new ArrayList<ImageInfo>();
Session session = createSession();
try {
@@ -308,45 +351,31 @@
} finally {
session.logout();
}
- return images;
+
+ // Display the search results ...
+ this.userInterface.displaySearchResults(images);
}
+ /**
+ * Utility method to create a new JCR session from the execution context's {@link
SessionFactory}.
+ * @return the session
+ * @throws RepositoryException
+ */
protected Session createSession() throws RepositoryException {
return
this.executionContext.getSessionFactory().createSession(this.repositoryName +
"/" + this.workspaceName);
}
- protected boolean uploadFile( InputStream content, String nodePath, String mimeType )
throws Exception {
- Session session = createSession();
- JcrTools tools = this.executionContext.getTools();
- try {
- // Create the node at the supplied path ...
- Node node = tools.findOrCreateNode(session, nodePath, "nt:folder",
"nt:file");
-
- // Upload the file to that node ...
- Node contentNode = tools.findOrCreateChild(session, node,
"jcr:content", "nt:resource");
- contentNode.setProperty("jcr:mimeType", mimeType);
- contentNode.setProperty("jcr:lastModified",
Calendar.getInstance());
- contentNode.setProperty("jcr:data", content);
-
- // Save the session ...
- session.save();
- } finally {
- session.logout();
- }
- return true;
+ protected String getMimeType( URL file ) {
+ String filename = file.getPath().toLowerCase();
+ if (filename.endsWith(".gif")) return "image/gif";
+ if (filename.endsWith(".png")) return "image/png";
+ if (filename.endsWith(".pict")) return "image/x-pict";
+ if (filename.endsWith(".bmp")) return "image/bmp";
+ if (filename.endsWith(".jpg")) return "image/jpeg";
+ if (filename.endsWith(".jpe")) return "image/jpeg";
+ if (filename.endsWith(".jpeg")) return "image/jpeg";
+ if (filename.endsWith(".ras")) return "image/x-cmu-raster";
+ throw new SystemFailureException("Unknown mime type for " + file);
}
- protected String getMimeType( File file ) {
- String extension = file.getName().toLowerCase();
- if (extension.endsWith(".gif")) return "image/gif";
- if (extension.endsWith(".png")) return "image/png";
- if (extension.endsWith(".pict")) return "image/x-pict";
- if (extension.endsWith(".bmp")) return "image/bmp";
- if (extension.endsWith(".jpg")) return "image/jpeg";
- if (extension.endsWith(".jpe")) return "image/jpeg";
- if (extension.endsWith(".jpeg")) return "image/jpeg";
- if (extension.endsWith(".ras")) return "image/x-cmu-raster";
- throw new SystemFailureException("Unknown mime type for file " +
file);
- }
-
}
Modified:
trunk/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/UserInterface.java
===================================================================
---
trunk/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/UserInterface.java 2008-05-07
16:26:20 UTC (rev 121)
+++
trunk/docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers/UserInterface.java 2008-05-07
20:43:55 UTC (rev 122)
@@ -21,8 +21,8 @@
*/
package org.jboss.example.dna.sequencers;
-import java.io.File;
import java.io.IOException;
+import java.net.URL;
import java.util.List;
/**
@@ -30,7 +30,7 @@
*/
public interface UserInterface {
- public File getPathOfFileToUpload() throws IllegalArgumentException, IOException;
+ public URL getFileToUpload() throws IllegalArgumentException, IOException;
public String getRepositoryPath( String defaultPath ) throws
IllegalArgumentException, IOException;
Added:
trunk/docs/examples/gettingstarted/sequencers/src/test/java/org/jboss/example/dna/sequencers/MockUserInterface.java
===================================================================
---
trunk/docs/examples/gettingstarted/sequencers/src/test/java/org/jboss/example/dna/sequencers/MockUserInterface.java
(rev 0)
+++
trunk/docs/examples/gettingstarted/sequencers/src/test/java/org/jboss/example/dna/sequencers/MockUserInterface.java 2008-05-07
20:43:55 UTC (rev 122)
@@ -0,0 +1,66 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.example.dna.sequencers;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import java.net.URL;
+import java.util.List;
+
+/**
+ * @author Randall Hauch
+ */
+public class MockUserInterface implements UserInterface {
+
+ private final String repositoryPath;
+ private final URL fileToUpload;
+
+ public MockUserInterface( URL fileToUpload, String repositoryPath ) {
+ this.repositoryPath = repositoryPath;
+ this.fileToUpload = fileToUpload;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void displaySearchResults( List<ImageInfo> images ) {
+ assertThat(images.size(), is(1));
+ for (ImageInfo image : images) {
+ System.out.println("Image: " + image);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public URL getFileToUpload() throws IllegalArgumentException {
+ return this.fileToUpload;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getRepositoryPath( String defaultPath ) {
+ return this.repositoryPath != null ? this.repositoryPath : defaultPath;
+ }
+
+}
Modified:
trunk/docs/examples/gettingstarted/sequencers/src/test/java/org/jboss/example/dna/sequencers/SequencingClientTest.java
===================================================================
---
trunk/docs/examples/gettingstarted/sequencers/src/test/java/org/jboss/example/dna/sequencers/SequencingClientTest.java 2008-05-07
16:26:20 UTC (rev 121)
+++
trunk/docs/examples/gettingstarted/sequencers/src/test/java/org/jboss/example/dna/sequencers/SequencingClientTest.java 2008-05-07
20:43:55 UTC (rev 122)
@@ -24,7 +24,6 @@
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import java.net.URL;
-import java.util.List;
import org.jboss.dna.common.util.FileUtil;
import org.junit.After;
import org.junit.Before;
@@ -71,19 +70,21 @@
@Test
public void shouldUploadFile() throws Exception {
+ client.setUserInterface(new MockUserInterface(this.file,
"/a/b/caution.png"));
client.startRepository();
client.startDnaServices();
- client.uploadFile(file.openStream(), "/a/b/caution.png",
"image/png");
+ client.uploadFile();
- // Let the sequencing start ...
+ // Use a trick to wait until the sequencing has been done by sleeping (to give
the sequencing time to start)
+ // and to then shut down the DNA services (which will block until all sequencing
has been completed) ...
Thread.sleep(1000);
- client.shutdownDnaServices(); // this will block untill all processing has been
done ...
+ client.shutdownDnaServices();
- List<ImageInfo> images = client.getImages();
- assertThat(images.size(), is(1));
- for (ImageInfo image : images) {
- System.out.println("Image: " + image);
- }
+ // The sequencers should have run, so perform the search.
+ // The mock user interface checks the results.
+ client.search();
+
+ assertThat(client.getStatistics().getNumberOfNodesSequenced(), is(1l));
}
}
Added: trunk/docs/gettingstarted/en/images/example-sequencer-cli-client.png
===================================================================
(Binary files differ)
Property changes on: trunk/docs/gettingstarted/en/images/example-sequencer-cli-client.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/gettingstarted/en/images/example-sequencer-search.png
===================================================================
(Binary files differ)
Property changes on: trunk/docs/gettingstarted/en/images/example-sequencer-search.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/gettingstarted/en/images/example-sequencer-search2.png
===================================================================
(Binary files differ)
Property changes on: trunk/docs/gettingstarted/en/images/example-sequencer-search2.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/gettingstarted/en/images/example-sequencer-statistics.png
===================================================================
(Binary files differ)
Property changes on: trunk/docs/gettingstarted/en/images/example-sequencer-statistics.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/gettingstarted/en/images/example-sequencer-statistics2.png
===================================================================
(Binary files differ)
Property changes on:
trunk/docs/gettingstarted/en/images/example-sequencer-statistics2.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/gettingstarted/en/images/example-sequencer-upload.png
===================================================================
(Binary files differ)
Property changes on: trunk/docs/gettingstarted/en/images/example-sequencer-upload.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/gettingstarted/en/images/example-sequencer-upload2.png
===================================================================
(Binary files differ)
Property changes on: trunk/docs/gettingstarted/en/images/example-sequencer-upload2.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: trunk/docs/gettingstarted/en/master.xml
===================================================================
--- trunk/docs/gettingstarted/en/master.xml 2008-05-07 16:26:20 UTC (rev 121)
+++ trunk/docs/gettingstarted/en/master.xml 2008-05-07 20:43:55 UTC (rev 122)
@@ -611,18 +611,18 @@
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://labs.jboss.com/file-access/default/members/jbossmc/downl...
+ <ulink
url="http://www.jboss.org/file-access/default/members/dna/downloads/...
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
available from
+ To build and run the examples you first need to install and configure Maven 2.0.7
(or higher), available from
<ulink
url="http://maven.apache.org/">http://maven.apache.org/</...
</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"><settings>
+ <programlisting role="XML"
language="xml"><settings>
<profiles>
<profile>
<id>jboss.repository</id>
@@ -666,28 +666,216 @@
</profile>
</profiles>
</settings></programlisting>
- <para>This profile informs maven of the two JBoss repositories (snapshots
and releases) that are needed to download the JBoss Microcontainer and dependant
JARs.</para>
+ <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>
</note>
- <para>Once you have configured Maven and downloaded the examples then you can
go to one of the following subdirectories in the
<code>examples/User_Guide</code> directory and enter <code>mvn
install</code> to perform a build:</para>
- <itemizedlist>
- <listitem>
- <para>gettingStarted - projects for creating and using a service
together with AOP</para>
- </listitem>
- <listitem>
- <para>pojoDevelopment - examples of creating and configuring POJOs using
XML and annotations</para>
- </listitem>
- <listitem>
- <para>aopDevelopment - examples of using AOP to add behaviour to
POJOs</para>
- </listitem>
- <listitem>
- <para>extending - examples of how we created various extensions to the
microcontainer by creating new dependencies</para>
- </listitem>
- </itemizedlist>
- <para>Instructions on how to run the individual examples can be found in the
corresponding parts of this guide.</para>
+ <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.)
+ </para>
+ <para>The build is successful if you see the following:</para>
+ <programlisting language="bash">$ mvn install
+...
+[INFO] ------------------------------------------------------------------------
+[INFO] Reactor Summary:
+[INFO] ------------------------------------------------------------------------
+[INFO] Getting Started examples .............................. SUCCESS [2.106s]
+[INFO] Sequencer Examples .................................... SUCCESS [9.768s]
+[INFO] ------------------------------------------------------------------------
+[INFO] ------------------------------------------------------------------------
+[INFO] BUILD SUCCESSFUL
+[INFO] ------------------------------------------------------------------------
+[INFO] Total time: 12 seconds
+[INFO] Finished at: Wed May 07 12:00:06 CDT 2008
+[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
+ 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></para>
+ <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 are 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>
+ <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>
+ <listitem>
+ <para><emphasis
role="strong"><code>run.sh</code></emphasis> is the *nix
shell script that will run the example.</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>jackrabbitConfig.xml</code>
+ </emphasis>
+ is the Jackrabbit configuration file, which is set up to use a transient in-memory
repository.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis role="strong">
+ <code>jackrabbitNodeTypes.cnd</code>
+ </emphasis>
+ defines the additional JCR node types used by this example.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis role="strong">
+ <code>caution.gif</code>
+ </emphasis>, <emphasis role="strong">
+ <code>caution.png</code>
+ </emphasis>, and <emphasis role="strong">
+ <code>caution.jpg</code>
+ </emphasis>
+ are images that you'll use later and upload into the repository.
+ </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>
+ </listitem>
+ </itemizedlist>
+ <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>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>
+ <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.
+ </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>
+ However, you can specify any fully-qualified or relative path. The application will
notify you if it cannot
+ find the file you specified.
+ </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>
+ /a (nt:folder)
+ /b (nt:folder)
+ /caution.png (nt:file)
+ /jcr:content (nt:resource)
+ @jcr:data = {contents of the file}
+ @jcr:mimeType = {mime type of the file}
+ @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.
+ </para>
+ <para>
+ So, very soon after the file is uploaded, DNA will sequence the image file and store
the metadata.
+ You can search the repository for this metadata using the "s" menu option:
+ <figure id="example-sequencer-search">
+ <title>Uploading an image using the Example Client</title>
+ <graphic align="center" scale="100"
fileref="images/example-sequencer-search.png" />
+ </figure>
+ You can also print the statistics for the sequencer using the "p" menu
option:
+ <figure id="example-sequencer-statistics">
+ <title>Uploading an image using the Example Client</title>
+ <graphic align="center" scale="100"
fileref="images/example-sequencer-statistics.png" />
+ </figure>
+ </para>
+ <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.
+ </para>
+
+
+
+
+
</chapter>
<chapter id="custom_sequencers">
<title>Custom sequencers</title>