[dna-commits] DNA SVN: r122 - in trunk: docs/examples/gettingstarted/sequencers/src/main/java/org/jboss/example/dna/sequencers and 3 other directories.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Wed May 7 16:43:55 EDT 2008


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/downloads/userGuide-examples-13112007.zip">download</ulink>
+      <ulink url="http://www.jboss.org/file-access/default/members/dna/downloads/0.1/jboss-dna-0.1-gettingstarted-examples.zip">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 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/</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">&lt;settings&gt;
+      <programlisting role="XML" language="xml">&lt;settings&gt;
   &lt;profiles&gt;
     &lt;profile&gt;
       &lt;id&gt;jboss.repository&lt;/id&gt;
@@ -666,28 +666,216 @@
     &lt;/profile&gt;
   &lt;/profiles&gt;
 &lt;/settings&gt;</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>




More information about the dna-commits mailing list