DNA SVN: r1017 - in trunk/docs/reference/src/main/docbook/en-US: content/core and 1 other directory.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-06-09 15:46:34 -0400 (Tue, 09 Jun 2009)
New Revision: 1017
Removed:
trunk/docs/reference/src/main/docbook/en-US/content/core/configuration.xml
Modified:
trunk/docs/reference/src/main/docbook/en-US/content/core/connector.xml
trunk/docs/reference/src/main/docbook/en-US/content/core/sequencing.xml
trunk/docs/reference/src/main/docbook/en-US/custom.dtd
trunk/docs/reference/src/main/docbook/en-US/master.xml
Log:
Updated the sequencing chapter of the Reference Guide.
Deleted: trunk/docs/reference/src/main/docbook/en-US/content/core/configuration.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/content/core/configuration.xml 2009-06-09 18:48:18 UTC (rev 1016)
+++ trunk/docs/reference/src/main/docbook/en-US/content/core/configuration.xml 2009-06-09 19:46:34 UTC (rev 1017)
@@ -1,371 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ JBoss DNA (http://www.jboss.org/dna)
- ~
- ~ See the COPYRIGHT.txt file distributed with this work for information
- ~ regarding copyright ownership. Some portions may be licensed
- ~ to Red Hat, Inc. under one or more contributor license agreements.
- ~ See the AUTHORS.txt file in the distribution for a full listing of
- ~ individual contributors.
- ~
- ~ JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- ~ is licensed to you 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.
- ~
- ~ JBoss DNA is distributed in the hope that it will be useful,
- ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- ~ for more details.
- ~
- ~ You should have received a copy of the GNU Lesser General Public License
- ~ along with this distribution; if not, write to:
- ~ Free Software Foundation, Inc.
- ~ 51 Franklin Street, Fifth Floor
- ~ Boston, MA 02110-1301 USA
- -->
-<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
-<!ENTITY % CustomDTD SYSTEM "../../custom.dtd">
-%CustomDTD;
-]>
-<chapter id="configuration">
- <title>Configuring and Using JBoss DNA</title>
- <para>Using JBoss DNA within your application is actually quite straightforward. As you'll see in this chapter,
- the first step is setting up JBoss DNA and starting the <code>JcrEngine</code>. After that, you obtain the
- <code>javax.jcr.Repository</code> instance for a named repository and just use the standard JCR API throughout your
- application.
- </para>
- <sect1 id="jcr_engine">
- <title>JBoss DNA's JcrEngine</title>
- <para>
- JBoss DNA encapsulates everything necessary to run one or more JCR repositories into a single &JcrEngine; instance.
- This includes all underlying repository sources, the pools of connections to the sources, the sequencers,
- the MIME type detector(s), and the &Repository; implementations.
- </para>
- <para>
- Obtaining a &JcrEngine; instance is very easy - assuming that you have a valid &JcrConfiguration; instance. We'll see
- how to get one of those in a little bit, but if you have one then all you have to do is build and start the engine:
- </para>
- <programlisting role="JAVA"><![CDATA[
-JcrConfiguration config = ...
-JcrEngine engine = config.build();
-engine.start();
- ]]></programlisting>
- <para>
- Obtaining a JCR &Repository; instance is a matter of simply asking the engine for it by the name defined in the configuration:
- </para>
- <programlisting role="JAVA"><![CDATA[
-javax.jcr.Repository repository = engine.getRepository("Name of repository");
- ]]></programlisting>
- <para>
- At this point, your application can proceed by working with the JCR API.
- </para>
- <para>
- And, once you're finished with the &JcrEngine;, you should shut it down:
- </para>
- <programlisting role="JAVA"><![CDATA[
-engine.shutdown();
-engine.awaitTermination(3,TimeUnit.SECONDS); // optional
- ]]></programlisting>
- <para>
- When the <code>shutdown()</code> method is called, the &Repository; instances managed by the engine are marked as being shut down,
- and they will not be able to create new &Session;s. However, any existing &Session;s or ongoing operations (e.g., event notifications)
- present at the time of the <code>shutdown()</code> call will be allowed to finish.
- In essence, <code>shutdown()</code> is a <emphasis>graceful</emphasis> request, and since it may take some time to complete,
- you can wait until the shutdown has completed by simply calling <code>awaitTermination(...)</code> as shown above.
- This method will block until the engine has indeed shutdown or until the supplied time duration has passed (whichever comes first).
- And, yes, you can call the <code>awaitTermination(...)</code> method repeatedly if needed.
- </para>
- </sect1>
- <sect1 id="jcr_configuration">
- <title>JcrConfiguration</title>
- <para>
- The previous section assumed the existence of a &JcrConfiguration;. It's not really that creating an instance is all that difficult.
- In fact, there's only one no-argument constructor, so actually creating the instance is a piece of cake. What can be a little more challenging,
- though, is setting up the &JcrConfiguration; instance, which must define the following components:
- <itemizedlist>
- <listitem>
- <para><emphasis role="strong"><code>Repository sources</code></emphasis> are the POJO objects that each describe a particular
- location where content is stored. Each repository source object is an instance of a JBoss DNA connector, and is configured
- with the properties that particular source. JBoss DNA's &RepositorySource; classes are analogous to JDBC's &DataSource; classes -
- they are implemented by specific connectors (aka, "drivers") for specific kinds of repository sources (aka, "databases").
- Similarly, a &RepositorySource; instance is analogous to a &DataSource; instance, with bean properties for each configurable
- parameter. Therefore, each repository source definition must supply the name of the &RepositorySource; class, any
- bean properties, and, optionally, the classpath that should be used to load the class. </para>
- </listitem>
- <listitem>
- <para><emphasis role="strong"><code>Repositories</code></emphasis> define the JCR repositories that are available. Each
- repository has a unique name that is used to obtain the &Repository; instance from the &JcrEngine;'s <code>getRepository(String)</code>
- method, but each repository definition also can include the predefined namespaces (other than those automatically defined by
- JBoss DNA), various options, and the node types that are to be available in the repository without explicit registration
- through the JCR API.</para>
- </listitem>
- <listitem>
- <para><emphasis role="strong"><code>Sequencers</code></emphasis> define the particular sequencers that are available for use.
- Each sequencer definition provides the path expressions governing which nodes in the repository should be sequenced when those nodes change,
- and where the resulting output generated by the sequencer should be placed. The definition also must state the name of
- the sequencer class, any bean properties and, optionally, the classpath that should be used to load the class.</para>
- </listitem>
- <listitem>
- <para><emphasis role="strong"><code>MIME type detectors</code></emphasis> define the particular MIME type detector(s) that should
- be made available. A MIME type detector does exactly what the name implies: it attempts to determine the MIME type given a
- "filename" and contents. JBoss DNA automatically uses a detector that uses the file extension to identify the MIME type,
- but also provides an implementation that uses an external library to identify the MIME type based upon the contents.
- The definition must state the name of the detector class, any bean properties and, optionally, the classpath that should
- be used to load the class.</para>
- </listitem>
- </itemizedlist>
- </para>
- <para>
- There really are three options:
- <itemizedlist>
- <listitem>
- <para><emphasis role="strong"><code>Load from a file</code></emphasis> is conceptually the easiest and requires the least amount
- of Java code, but it now requires a configuration file.</para>
- </listitem>
- <listitem>
- <para><emphasis role="strong"><code>Load from a configuration repository</code></emphasis> is not much more complicated than loading
- from a file, but it does allow multiple &JcrEngine; instances (usually in different processes perhaps on different machines)
- to easily access their (shared) configuration. And technically, loading the configuration from a file really just creates an
- &InMemoryRepositorySource;, imports the configuration file into that source, and then proceeds with this approach.</para>
- </listitem>
- <listitem>
- <para><emphasis role="strong"><code>Programmatic configuration</code></emphasis> is always possible, even if the configuration is loaded
- from a file or repository. Using the &JcrConfiguration;'s API, you can define (or update or remove) all of the definitions that make
- up a configuration.</para>
- </listitem>
- </itemizedlist>
- </para>
- <para>
- Each of these approaches has their obvious advantages, so the choice of which one to use is entirely up to you.
- </para>
- <sect2 id="loading_from_file">
- <title>Loading from a configuration file</title>
- <para>
- Loading the JBoss DNA configuration from a file is actually very simple:
- </para>
- <programlisting role="JAVA"><![CDATA[
-JcrConfiguration config = new JcrConfiguration();
-configuration.loadFrom(file);
- ]]></programlisting>
- <para>
- where the <code>file</code> parameter can actually be a &File; instance, a &URL; to the file, an &InputStream;
- containing the contents of the file, or even a &String; containing the contents of the file.
- </para>
- <note>
- <para>The <code>loadFrom(...)</code> method can be called any number of times, but each time it is called it completely wipes
- out any current notion of the configuration and replaces it with the configuration found in the file.
- </para>
- </note>
- <para>
- There is an optional second parameter that defines the &Path; within the configuration file identifying the parent node of the various
- configuration nodes. If not specified, it assumes "/". This makes it possible for the configuration content to be
- located at a different location in the hierarchical structure. (This is not often required, but when it is required
- this second parameter is very useful.)
- </para>
- <para>
- Here is the configuration file that is used in the repository example, though it has been simplified a bit and most comments
- have been removed for clarity):
- </para>
- <programlisting role="JAVA"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration xmlns="http://www.jboss.org/dna/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0">
- <!--
- Define the JCR repositories
- -->
- <dna:repositories>
- <!--
- Define a JCR repository that accesses the 'Cars' source directly.
- This of course is optional, since we could access the same content through 'vehicles'.
- -->
- <dna:repository jcr:name="car repository" dna:source="Cars">
- <options jcr:primaryType="dna:options"/>
- <jaasLoginConfigName jcr:primaryType="dna:option" dna:value="dna-jcr"/>
- </options>
- </dna:repository>
- </dna:repositories>
- <!--
- Define the sources for the content. These sources are directly accessible using the DNA-specific Graph API.
- -->
- <dna:sources jcr:primaryType="nt:unstructured">
- <dna:source jcr:name="Cars" dna:classname="org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource" dna:retryLimit="3" dna:defaultWorkspaceName="workspace1"/>
- <dna:source jcr:name="Aircraft" dna:classname="org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource">
- <!-- Define the name of the workspace used by default. Optional, but convenient. -->
- <defaultWorkspaceName>workspace2</defaultWorkspaceName>
- </dna:source>
- </dna:sources>
- <!--
- Define the sequencers. This is an optional section. For this example, we're not using any sequencers.
- -->
- <dna:sequencers>
- <!--dna:sequencer jcr:name="Image Sequencer" dna:classname="org.jboss.dna.sequencer.image.ImageMetadataSequencer">
- <dna:description>Image metadata sequencer</dna:description>
- <dna:pathExpression>/foo/source => /foo/target</dna:pathExpression>
- <dna:pathExpression>/bar/source => /bar/target</dna:pathExpression>
- </dna:sequencer-->
- </dna:sequencers>
- <dna:mimeTypeDetectors>
- <dna:mimeTypeDetector jcr:name="Detector" dna:description="Standard extension-based MIME type detector"/>
- </dna:mimeTypeDetectors>
-</configuration>
- ]]></programlisting>
- </sect2>
- <sect2 id="loading_from_repository">
- <title>Loading from a configuration repository</title>
- <para>
- Loading the JBoss DNA configuration from an existing repository is also pretty straightforward. Simply create and configure the
- &RepositorySource; instance to point to the desired repository, and then call the <code>loadFrom(&RepositorySource; source)</code>
- method:
- </para>
- <programlisting role="JAVA"><![CDATA[
-RepositorySource configSource = ...
-JcrConfiguration config = new JcrConfiguration();
-configuration.loadFrom(configSource);
- ]]></programlisting>
- <para>
- This really is a more advanced way to define your configuration, so we won't go into how you configure a &RepositorySource;.
- For more information, consult the &ReferenceGuide;.
- </para>
- <note>
- <para>The <code>loadFrom(...)</code> method can be called any number of times, but each time it is called it completely wipes
- out any current notion of the configuration and replaces it with the configuration found in the file.
- </para>
- </note>
- <para>
- There is an optional second parameter that defines the name of the workspace in the supplied source where the configuration content
- can be found. It is not needed if the workspace is the source's default workspace.
- There is an optional third parameter that defines the &Path; within the configuration repository identifying the parent node of the various
- configuration nodes. If not specified, it assumes "/". This makes it possible for the configuration content to be
- located at a different location in the hierarchical structure. (This is not often required, but when it is required
- this second parameter is very useful.)
- </para>
- </sect2>
- <sect2 id="programmatic_configuration">
- <title>Programmatic configuration</title>
- <para>
- Defining the configuration programmatically is not terribly complicated, and it for obvious reasons results in more verbose Java code.
- But this approach is very useful and often the easiest approach when the configuration must change or is a reflection of other
- dynamic information.
- </para>
- <para>
- The &JcrConfiguration; class was designed to have an easy-to-use API that makes it easy to configure each of the different kinds of
- components, especially when using an IDE with code completion. Here are several examples:
- </para>
- <sect3 id="programmatically_configuring_sources">
- <title>Repository sources</title>
- <para>Each repository source definition must include the name of the &RepositorySource; class as well as each bean property
- that should be set on the object:
- </para>
- <programlisting role="JAVA"><![CDATA[
-JcrConfiguration config = ...
-config.repositorySource("source A")
- .usingClass(InMemoryRepositorySource.class)
- .setDescription("The repository for our content")
- .setProperty("defaultWorkspaceName", workspaceName);
- ]]></programlisting>
- <para>
- This example defines an in-memory source with the name "source A", a description, and a single "defaultWorkspaceName" bean property.
- Different &RepositorySource; implementations will the bean properties that are required and optional.
- Of course, the class can be specified as Class reference or a string (followed by whether the class should be loaded from
- the classpath or from a specific classpath).
- </para>
- <note>
- <para>Each time <code>repositorySource(String)</code> is called, it will either load the existing definition with the supplied
- name or will create a new definition if one does not already exist. To remove a definition, simply call <code>remove()</code>
- on the result of <code>repositorySource(String)</code>.
- The set of existing definitions can be accessed with the <code>repositorySources()</code> method.
- </para>
- </note>
- </sect3>
- <sect3 id="programmatically_configuring_repositories">
- <title>Repositories</title>
- <para>Each repository must be defined to use a named repository source, but all other aspects (e.g., namespaces, node types, options)
- are optional.</para>
- <programlisting role="JAVA"><![CDATA[
-JcrConfiguration config = ...
-config.repository("repository A")
- .addNodeTypes("myCustomNodeTypes.cnd")
- .setSource("source 1")
- .registerNamespace("acme","http://www.example.com/acme")
- .setOption(JcrRepository.Option.JAAS_LOGIN_CONFIG_NAME, "dna-jcr");
- ]]></programlisting>
- <para>
- This example defines a repository that uses the "source 1" repository source (which could be a federated source, an in-memory source,
- a database store, or any other source). Additionally, this example adds the node types in the "myCustomNodeTypes.cnd" file as those
- that will be made available when the repository is accessed. It also defines the "http://www.example.com/acme" namespace,
- and finally sets the "JAAS_LOGIN_CONFIG_NAME" option to define the name of the JAAS login configuration that should be used by
- the JBoss DNA repository.
- </para>
- <note>
- <para>Each time <code>repository(String)</code> is called, it will either load the existing definition with the supplied
- name or will create a new definition if one does not already exist. To remove a definition, simply call <code>remove()</code>
- on the result of <code>repository(String)</code>.
- The set of existing definitions can be accessed with the <code>repositories()</code> method.
- </para>
- </note>
- </sect3>
- <sect3 id="programmatically_configuring_sequencers">
- <title>Sequencers</title>
- <para>Each defined sequencer must specify the name of the &StreamSequencer; implementation class as well as the path expressions
- defining which nodes should be sequenced and the output paths defining where the sequencer output should be placed (often as a function
- of the input path expression).</para>
- <programlisting role="JAVA"><![CDATA[
-JcrConfiguration config = ...
-config.sequencer("Image Sequencer")
- .usingClass("org.jboss.dna.sequencer.image.ImageMetadataSequencer")
- .loadedFromClasspath()
- .setDescription("Sequences image files to extract the characteristics of the image")
- .sequencingFrom("//(*.(jpg|jpeg|gif|bmp|pcx|png|iff|ras|pbm|pgm|ppm|psd)[*])/jcr:content[@jcr:data]")
- .andOutputtingTo("/images/$1");
- ]]></programlisting>
- <para>
- This shows an example of a sequencer definition named "Image Sequencer" that uses the &ImageMetadataSequencer; class
- (loaded from the classpath), that is to sequence the "jcr:data" property on any new or changed nodes that are named
- "jcr:content" below a parent node with a name ending in ".jpg", ".jpeg", ".gif", ".bmp", ".pcx", ".iff", ".ras",
- ".pbm", ".pgm", ".ppm" or ".psd". The output of the sequencing operation should be placed at the "/images/$1" node,
- where the "$1" value is captured as the name of the parent node. (The capture groups work the same was as regular expressions;
- see the &ReferenceGuide; for more details.)
- Of course, the class can be specified as Class reference or a string (followed by whether the class should be loaded from
- the classpath or from a specific classpath).
- </para>
- <note>
- <para>Each time <code>sequencer(String)</code> is called, it will either load the existing definition with the supplied
- name or will create a new definition if one does not already exist. To remove a definition, simply call <code>remove()</code>
- on the result of <code>sequencer(String)</code>.
- The set of existing definitions can be accessed with the <code>sequencers()</code> method.
- </para>
- </note>
- </sect3>
- <sect3 id="programmatically_configuring_mime_type_detectors">
- <title>MIME type detectors</title>
- <para>Each defined MIME type detector must specify the name of the &MimeTypeDetector; implementation class as well as any
- other bean properties required by the implementation.</para>
- <programlisting role="JAVA"><![CDATA[
-JcrConfiguration config = ...
-config.mimeTypeDetector("Extension Detector")
- .usingClass(org.jboss.dna.graph.mimetype.ExtensionBasedMimeTypeDetector.class);
- ]]></programlisting>
- <para>
- Of course, the class can be specified as Class reference or a string (followed by whether the class should be loaded from
- the classpath or from a specific classpath).
- </para>
- <note>
- <para>Each time <code>mimeTypeDetector(String)</code> is called, it will either load the existing definition with the supplied
- name or will create a new definition if one does not already exist. To remove a definition, simply call <code>remove()</code>
- on the result of <code>mimeTypeDetector(String)</code>.
- The set of existing definitions can be accessed with the <code>mimeTypeDetectors()</code> method.
- </para>
- </note>
- </sect3>
- </sect2>
- </sect1>
- <sect1 id="using_dna_whats_next">
- <title>What's next</title>
- <para>
- This chapter outline how you configure JBoss DNA, how you then access a <code>javax.jcr.Repository</code> instance,
- and use the standard JCR API to interact with the repository. The
- <link linkend="downloading_and_running">next chapter </link> walks you through downloading
- and running the JBoss DNA examples.
- </para>
- </sect1>
-</chapter>
Modified: trunk/docs/reference/src/main/docbook/en-US/content/core/connector.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/content/core/connector.xml 2009-06-09 18:48:18 UTC (rev 1016)
+++ trunk/docs/reference/src/main/docbook/en-US/content/core/connector.xml 2009-06-09 19:46:34 UTC (rev 1017)
@@ -260,6 +260,7 @@
As for testing, you probably will want to add more dependencies, such as those listed here:
</para>
<programlisting role="XML"><![CDATA[
+<!-- DNA-related unit testing utilities and classes -->
<dependency>
<groupId>org.jboss.dna</groupId>
<artifactId>dna-graph</artifactId>
Modified: trunk/docs/reference/src/main/docbook/en-US/content/core/sequencing.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/content/core/sequencing.xml 2009-06-09 18:48:18 UTC (rev 1016)
+++ trunk/docs/reference/src/main/docbook/en-US/content/core/sequencing.xml 2009-06-09 19:46:34 UTC (rev 1017)
@@ -30,229 +30,233 @@
]>
<chapter id="sequencing_framework">
<title>Sequencing framework</title>
- <para>As we've mentioned before, JBoss DNA is able to work with existing JCR repositories. Your client applications
- make changes to the information in those repositories, and JBoss DNA automatically uses its sequencers to extract
- additional information from the uploaded files.</para>
<para>
- This chapter discusses the sequencing features of JBoss DNA and the components that are involved.
+ Many repositories are used (at least in part) to manage files and other artifacts, including
+ service definitions, policy files, images, media, documents, presentations, application components,
+ reusable libraries, configuration files, application installations, databases schemas, management scripts, and so on.
+ Unlocking the information buried within all of those files is what JBoss DNA sequencing is all about.
+ As files are loaded into the repository, you JBoss DNA can automatically sequence these files to extract
+ from their content meaningful information that can be stored in the repository, where it can then be
+ searched, accessed, and analyzed using the JCR API.
</para>
- <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>,
- reacting to changes in JCR repositories and then running the appropriate sequencers.
- This involves processing the changes on a node, determining which (if any) sequencers should be run on that node,
- and for each sequencer constructing the execution environment, calling the sequencer, and saving the information
- generated by the sequencer.</para>
- <note>
- <para>Configuring JBoss DNA services 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. But this flexibility
- makes it more difficult for you to use. We understand this, and will soon provide a much easier way to set up
- and manage JBoss DNA. Current plans are to use the <ulink url="http://www.jboss.org/jbossmc">JBoss Microcontainer</ulink>
- along with a configuration repository.</para>
- </note>
- <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 &ExecutorService; 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 &JcrExecutionContext; provides access to a &SessionFactory; that is used
- by JBoss DNA to establish sessions to your JCR repositories. Two implementations are available:
- <itemizedlist>
- <listitem>
- <para>The &JndiSessionFactory;> looks up JCR &Repository; instances in JNDI using
- names that are supplied when creating sessions. This implementation also has methods to set the
- JCR &Credentials; for a given workspace name.</para>
- </listitem>
- <listitem>
- <para>The &SimpleSessionFactory; has methods to register the JCR &Repository; instances
- with names, as well as methods to set the JCR &Credentials; for a given workspace name.</para>
- </listitem>
- </itemizedlist>
- You can use the &JcrExecutionContext; and use one of these &SessionFactory; implementations or another
- implementation that you provide.</para>
- <para>Here's an example of how to instantiate and configure the &SequencingService;:</para>
+ <sect1 id="sequencers">
+ <title>Sequencers</title>
+ <para>
+ Sequencers are just POJOs that implement a specific interface, and their job is to process a stream of
+ data (supplied by JBoss DNA) to extract meaningful content that usually takes the form of a structured graph.
+ Exactly what content is up to each sequencer
+ implementation. For example, JBoss DNA comes with an <link linkend="image-sequencer">image sequencer</link>
+ that extracts the simple metadata from different kinds of image files (e.g., JPEG, GIF, PNG, etc.).
+ Another example is the <link linkend="cnd-sequencer">Compact Node Definition (CND) sequencer</link>
+ that processes the CND files to extract and produce a structured representation of the node type definitions,
+ property definitions, and child node definitions contained within the file.
+ </para>
+ <para>
+ Sequencers are configured to identify the kinds of nodes that the sequencers can work against.
+ When content in the repository changes, JBoss DNA looks to see which (if any) sequencers might be able
+ to run on the changed content. If any sequencer configurations do match, those sequencers are run
+ against the content, and the structured graph output of the sequencers is then written back into the repository
+ (at a location dictated by the sequencer configuration). And once that information is in the repository,
+ it can be easily found and accessed via the standard JCR API.
+ </para>
+ <para>
+ In other words, JBoss DNA uses sequencers to help you extract more meaning from the artifacts you already
+ are managing, and makes it much easier for applications to find and use all that valuable information.
+ All without your applications doing anything extra.
+ </para>
+ </sect1>
+ <sect1 id="stream-sequencers">
+ <title>Stream Sequencers</title>
+ <para>
+ The &StreamSequencer; interface defines the single method that must be implemented by a sequencer:
+ </para>
<programlisting>
-&SimpleSessionFactory; sessionFactory = new &SimpleSessionFactory;();
-sessionFactory.registerRepository("Main Repository", this.repository);
-&Credentials; credentials = new &SimpleCredentials;("jsmith", "secret".toCharArray());
-sessionFactory.registerCredentials("Main Repository/Workspace1", credentials);
-// Now create the JCR execution context, with a reference to the session factory
-// and the name of the repository from which sessions will be obtained ...
-ExecutionContext executionContext = new &JcrExecutionContext;(sessionFactory,"Main Repository");
+public interface &StreamSequencer; {
-// Create the sequencing service, passing in the execution context ...
-&SequencingService; sequencingService = new &SequencingService;();
-sequencingService.setExecutionContext(executionContext);
+ /**
+ * Sequence the data found in the supplied stream, placing the output
+ * information into the supplied map.
+ *
+ * @param stream the stream with the data to be sequenced; never null
+ * @param output the output from the sequencing operation; never null
+ * @param context the context for the sequencing operation; never null
+ */
+ void sequence( &InputStream; stream, &SequencerOutput; output, &StreamSequencerContext; context );
+}
</programlisting>
- <para>After the sequencing service is created and configured, it must be started. The &SequencingService;
- has an <emphasis>administration object</emphasis> (that is an instance of &ServiceAdministrator;)
- with <code>start()</code>, <code>pause()</code>, and <code>shutdown()</code> methods. The latter method will
- close the queue for sequencing, but will allow sequencing operations already running to complete normally.
- To wait until all sequencing operations have completed, simply call the <code>awaitTermination</code> method
- and pass it the maximum amount of time you want to wait.</para>
- <programlisting>
-sequencingService.getAdministrator().start();
-</programlisting>
- <para>The JBoss DNA services are utilizing resources and threads that must be released before your application is ready to shut down.
- The safe way to do this is to simply obtain the &ServiceAdministrator; for each service (via the <code>getServiceAdministrator()</code> method)
- and call <code>shutdown()</code>. As previously mentioned, the shutdown method will simply prevent new work from being processed
- and will not wait for existing work to be completed. If you want to wait until the service completes all its work, you must wait
- until the service terminates. Here's an example that shows how this is done:</para>
- <programlisting>
-// Shut down the service and wait until it's all shut down ...
-sequencingService.getAdministrator().shutdown();
-sequencingService.getAdministrator().awaitTermination(5, TimeUnit.SECONDS);
+ <para>
+ Implementations are responsible for processing the content in the supplied &InputStream; content and generating
+ structured content using the supplied &SequencerOutput; interface.
+ The &StreamSequencerContext; provides additional details about the information that is being sequenced,
+ including the location and properties of the node being sequenced, the MIME type
+ of the node being sequenced, and a &Problems; object where the sequencer can record problems that aren't
+ severe enough to warrant throwing an exception. The &StreamSequencerContext; also provides access
+ to the &ValueFactories; that can be used to create &Path;, &Name;, and any other value objects.
+ </para>
+ <para>The &SequencerOutput; interface is fairly easy to use, and its job is to hide from the sequencer
+ all the specifics about where the output is being written. Therefore, the interface has only a few methods
+ for implementations to call.
+ Two methods set the property values on a node, while the other sets references to other nodes in the repository.
+ Use these methods to describe the properties of the nodes you want to create, using relative paths for the nodes and
+ valid JCR property names for properties and references. JBoss DNA will ensure that nodes are created or updated
+ whenever they're needed.
+ </para>
+ <programlisting>
+public interface &SequencerOutput; {
-// Shut down the observation service ...
-observationService.getAdministrator().shutdown();
-observationService.getAdministrator().awaitTermination(5, TimeUnit.SECONDS);
-</programlisting>
- </sect1>
- <sect1 id="sequencer-configuration">
- <title>Sequencer Configurations</title>
- <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 &SequencerConfig; instance that
- you create. Here's the code that defines 3 sequencer configurations: 1 that places image metadata into
- "<code><![CDATA[/images/<filename>]]></code>", another that places MP3 metadata into "<code><![CDATA[/mp3s/<filename>]]></code>",
- and a third that places a structure that represents the classes, methods, and attributes found within Java source into
- "<code><![CDATA[/java/<filename>]]></code>".</para>
- <programlisting>
-String name = "Image Sequencer";
-String desc = "Sequences image files to extract the characteristics of the image";
-String classname = "org.jboss.dna.sequencer.images.ImageMetadataSequencer";
-String[] classpath = null; // Use the current classpath
-String[] pathExpressions = {"//(*.(jpg|jpeg|gif|bmp|pcx|png)[*])/jcr:content[@jcr:data] => /images/$1"};
-&SequencerConfig; imageSequencerConfig = new &SequencerConfig;(name, desc, classname,
- classpath, pathExpressions);
-sequencingService.addSequencer(imageSequencerConfig);
+ /**
+ * Set the supplied property on the supplied node. The allowable
+ * values are any of the following:
+ * - primitives (which will be autoboxed)
+ * - String instances
+ * - String arrays
+ * - byte arrays
+ * - InputStream instances
+ * - Calendar instances
+ *
+ * @param nodePath the path to the node containing the property;
+ * may not be null
+ * @param property the name of the property to be set
+ * @param values the value(s) for the property; may be empty if
+ * any existing property is to be removed
+ */
+ void setProperty( String nodePath, String property, Object... values );
+ void setProperty( &Path; nodePath, &Name; property, Object... values );
-name = "MP3 Sequencer";
-desc = "Sequences MP3 files to extract the ID3 tags from the audio file";
-classname = "org.jboss.dna.sequencer.mp3.Mp3MetadataSequencer";
-pathExpressions = {"//(*.mp3[*])/jcr:content[@jcr:data] => /mp3s/$1"};
-&SequencerConfig; mp3SequencerConfig = new &SequencerConfig;(name, desc, classname,
- classpath, pathExpressions);
-sequencingService.addSequencer(mp3SequencerConfig);
-
-name = "Java Sequencer";
-desc = "Sequences java files to extract the characteristics of the Java source";
-classname = "org.jboss.dna.sequencer.java.JavaMetadataSequencer";
-pathExpressions = {"//(*.java[*])/jcr:content[@jcr:data] => /java/$1"};
-&SequencerConfig; javaSequencerConfig = new &SequencerConfig;(name, desc, classname,
- classpath, pathExpressions);
-this.sequencingService.addSequencer(javaSequencerConfig);
-</programlisting>
- <para>Each configuration defines several things, including the name, description, and sequencer implementation class.
- The configuration also defines the classpath information, which can be passed to the &ClassLoaderFactory; to get
- a Java &ClassLoader; with which the sequencer class can be loaded. (If no classpath information is provided, as is done
- in the code above, the application class loader is used.) The configuration also specifies the path expressions that
- identify the nodes that should be sequenced with the sequencer and where to store the output generated by the sequencer.
- Path expressions are pretty straightforward but are quite powerful, so before we go any further with the example,
- let's dive into path expressions in more detail.</para>
- <sect2 id="path_expressions">
- <title>Path Expressions</title>
- <para>Path expressions consist of two parts: a selection criteria (or an input path) and an output path:</para>
- <programlisting><![CDATA[ inputPath => outputPath ]]></programlisting>
- <para>The <emphasis>inputPath</emphasis> part defines an expression for the path of a node that is to be sequenced.
- Input paths consist of '<code>/</code>' separated segments, where each segment represents a pattern for a single node's
- name (including the same-name-sibling indexes) and '<code>@</code>' signifies a property name.</para>
- <para>Let's first look at some simple examples:</para>
- <table frame='all'>
- <title>Simple Input Path Examples</title>
- <tgroup cols='2' align='left' colsep='1' rowsep='1'>
- <colspec colname='c1' colwidth="1*"/>
- <colspec colname='c2' colwidth="1*"/>
- <thead>
- <row>
- <entry>Input Path</entry>
- <entry>Description</entry>
- </row>
- </thead>
- <tbody>
- <row><entry>/a/b</entry><entry>Match node "<code>b</code>" that is a child of the top level node "<code>a</code>". Neither node
- may have any same-name-sibilings.</entry></row>
- <row><entry>/a/*</entry><entry>Match any child node of the top level node "<code>a</code>".</entry></row>
- <row><entry>/a/*.txt</entry><entry>Match any child node of the top level node "<code>a</code>" that also has a name ending in "<code>.txt</code>".</entry></row>
- <row><entry>/a/*.txt</entry><entry>Match any child node of the top level node "<code>a</code>" that also has a name ending in "<code>.txt</code>".</entry></row>
- <row><entry>/a/b@c</entry><entry>Match the property "<code>c</code>" of node "<code>/a/b</code>".</entry></row>
- <row><entry>/a/b[2]</entry><entry>The second child named "<code>b</code>" below the top level node "<code>a</code>".</entry></row>
- <row><entry>/a/b[2,3,4]</entry><entry>The second, third or fourth child named "<code>b</code>" below the top level node "<code>a</code>".</entry></row>
- <row><entry>/a/b[*]</entry><entry>Any (and every) child named "<code>b</code>" below the top level node "<code>a</code>".</entry></row>
- <row><entry>//a/b</entry><entry>Any node named "<code>b</code>" that exists below a node named "<code>a</code>", regardless
- of where node "<code>a</code>" occurs. Again, neither node may have any same-name-sibilings.</entry></row>
- </tbody>
- </tgroup>
- </table>
- <para>With these simple examples, you can probably discern the most important rules. First, the '<code>*</code>' is a wildcard character
- that matches any character or sequence of characters in a node's name (or index if appearing in between square brackets), and
- can be used in conjunction with other characters (e.g., "<code>*.txt</code>").</para>
- <para>Second, square brackets (i.e., '<code>[</code>' and '<code>]</code>') are used to match a node's same-name-sibiling index.
- You can put a single non-negative number or a comma-separated list of non-negative numbers. Use '0' to match a node that has no
- same-name-sibilings, or any positive number to match the specific same-name-sibling.</para>
- <para>Third, combining two delimiters (e.g., "<code>//</code>") matches any sequence of nodes, regardless of what their names are
- or how many nodes. Often used with other patterns to identify nodes at any level matching other patterns.
- Three or more sequential slash characters are treated as two.</para>
- <para>Many input paths can be created using just these simple rules. However, input paths can be more complicated. Here are some
- more examples:</para>
- <table frame='all'>
- <title>More Complex Input Path Examples</title>
- <tgroup cols='2' align='left' colsep='1' rowsep='1'>
- <colspec colname='c1' colwidth="1*"/>
- <colspec colname='c2' colwidth="1*"/>
- <thead>
- <row>
- <entry>Input Path</entry>
- <entry>Description</entry>
- </row>
- </thead>
- <tbody>
- <row><entry>/a/(b|c|d)</entry><entry>Match children of the top level node "<code>a</code>" that are named "<code>a</code>",
- "<code>b</code>" or "<code>c</code>". None of the nodes may have same-name-sibling indexes.</entry></row>
- <row><entry>/a/b[c/d]</entry><entry>Match node "<code>b</code>" child of the top level node "<code>a</code>", when node
- "<code>b</code>" has a child named "<code>c</code>", and "<code>c</code>" has a child named "<code>d</code>".
- Node "<code>b</code>" is the selected node, while nodes "<code>b</code>" and "<code>b</code>" are used as criteria but are not
- selected.</entry></row>
- <row><entry>/a(/(b|c|d|)/e)[f/g/@something]</entry><entry>Match node "<code>/a/b/e</code>", "<code>/a/c/e</code>", "<code>/a/d/e</code>",
- or "<code>/a/e</code>" when they also have a child "<code>f</code>" that itself has a child "<code>g</code>" with property
- "<code>something</code>". None of the nodes may have same-name-sibling indexes.</entry></row>
- </tbody>
- </tgroup>
- </table>
- <para>These examples show a few more advanced rules. Parentheses (i.e., '<code>(</code>' and '<code>)</code>') can be used
- to define a set of options for names, as shown in the first and third rules. Whatever part of the selected node's path
- appears between the parentheses is captured for use within the output path. Thus, the first input path in the previous table
- would match node "<code>/a/b</code>", and "b" would be captured and could be used within the output path using "<code>$1</code>",
- where the number used in the output path identifies the parentheses.</para>
- <para>Square brackets can also be used to specify criteria on a node's properties or children. Whatever appears in between the square
- brackets does not appear in the selected node.</para>
- <para>Let's go back to the previous code fragment and look at the first path expression:</para>
- <programlisting><![CDATA[ //(*.(jpg|jpeg|gif|bmp|pcx|png)[*])/jcr:content[@jcr:data] => /images/$1 ]]></programlisting>
- <para>This matches a node named "<code>jcr:content</code>" with property "<code>jcr:data</code>" but no siblings with the same name,
- and that is a child of a node whose name ends with "<code>.jpg</code>", "<code>.jpeg</code>", "<code>.gif</code>", "<code>.bmp</code>", "<code>.pcx</code>",
- or "<code>.png</code>" that may have any same-name-sibling index. These nodes can appear at any level in the repository.
- Note how the input path capture the filename (the segment containing the file extension), including any same-name-sibling index.
- This filename is then used in the output path, which is where the sequenced content is placed.</para>
- </sect2>
+ /**
+ * Set the supplied reference on the supplied node.
+ *
+ * @param nodePath the path to the node containing the property;
+ * may not be null
+ * @param property the name of the property to be set
+ * @param paths the paths to the referenced property, which may be
+ * absolute paths or relative to the sequencer output node;
+ * may be empty if any existing property is to be removed
+ */
+ void setReference( String nodePath, String property, String... paths );
+}
+ </programlisting>
+ <note>
+ <para>
+ JBoss DNA will create nodes of type <code>nt:unstructured</code> unless you specify the value for the
+ <code>jcr:primaryType</code> property. You can also specify the values for the <code>jcr:mixinTypes</code> property
+ if you want to add mixins to any node.
+ </para>
+ </note>
</sect1>
+ <sect1 id="path-expressions">
+ <title>Path Expressions</title>
+ <para>
+ Each sequencer must be configured to describe the areas or types of content that the sequencer is capable
+ of handling. This is done by specifying these patterns using path expressions that
+ identify the nodes (or node patterns) that should be sequenced and where to store the output generated by the sequencer.
+ We'll see how to fully configure a sequencer in the <link linkend="configuration">next chapter</link>,
+ but before then let's dive into path expressions in more detail.
+ </para>
+ <para>
+ A path expression consist of two parts: a selection criteria (or an input path) and an output path:
+ </para>
+ <programlisting><![CDATA[ inputPath => outputPath ]]></programlisting>
+ <para>
+ The <emphasis>inputPath</emphasis> part defines an expression for the path of a node that is to be sequenced.
+ Input paths consist of '<code>/</code>' separated segments, where each segment represents a pattern for a single node's
+ name (including the same-name-sibling indexes) and '<code>@</code>' signifies a property name.
+ </para>
+ <para>
+ Let's first look at some simple examples:
+ </para>
+ <table frame='all'>
+ <title>Simple Input Path Examples</title>
+ <tgroup cols='2' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Input Path</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row><entry>/a/b</entry><entry>Match node "<code>b</code>" that is a child of the top level node "<code>a</code>". Neither node
+ may have any same-name-sibilings.</entry></row>
+ <row><entry>/a/*</entry><entry>Match any child node of the top level node "<code>a</code>".</entry></row>
+ <row><entry>/a/*.txt</entry><entry>Match any child node of the top level node "<code>a</code>" that also has a name ending in "<code>.txt</code>".</entry></row>
+ <row><entry>/a/*.txt</entry><entry>Match any child node of the top level node "<code>a</code>" that also has a name ending in "<code>.txt</code>".</entry></row>
+ <row><entry>/a/b@c</entry><entry>Match the property "<code>c</code>" of node "<code>/a/b</code>".</entry></row>
+ <row><entry>/a/b[2]</entry><entry>The second child named "<code>b</code>" below the top level node "<code>a</code>".</entry></row>
+ <row><entry>/a/b[2,3,4]</entry><entry>The second, third or fourth child named "<code>b</code>" below the top level node "<code>a</code>".</entry></row>
+ <row><entry>/a/b[*]</entry><entry>Any (and every) child named "<code>b</code>" below the top level node "<code>a</code>".</entry></row>
+ <row><entry>//a/b</entry><entry>Any node named "<code>b</code>" that exists below a node named "<code>a</code>", regardless
+ of where node "<code>a</code>" occurs. Again, neither node may have any same-name-sibilings.</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+ <para>
+ With these simple examples, you can probably discern the most important rules. First, the '<code>*</code>' is a wildcard character
+ that matches any character or sequence of characters in a node's name (or index if appearing in between square brackets), and
+ can be used in conjunction with other characters (e.g., "<code>*.txt</code>").
+ </para>
+ <para>
+ Second, square brackets (i.e., '<code>[</code>' and '<code>]</code>') are used to match a node's same-name-sibiling index.
+ You can put a single non-negative number or a comma-separated list of non-negative numbers. Use '0' to match a node that has no
+ same-name-sibilings, or any positive number to match the specific same-name-sibling.
+ </para>
+ <para>
+ Third, combining two delimiters (e.g., "<code>//</code>") matches any sequence of nodes, regardless of what their names are
+ or how many nodes. Often used with other patterns to identify nodes at any level matching other patterns.
+ Three or more sequential slash characters are treated as two.
+ </para>
+ <para>
+ Many input paths can be created using just these simple rules. However, input paths can be more complicated. Here are some
+ more examples:
+ </para>
+ <table frame='all'>
+ <title>More Complex Input Path Examples</title>
+ <tgroup cols='2' align='left' colsep='1' rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Input Path</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row><entry>/a/(b|c|d)</entry><entry>Match children of the top level node "<code>a</code>" that are named "<code>a</code>",
+ "<code>b</code>" or "<code>c</code>". None of the nodes may have same-name-sibling indexes.</entry></row>
+ <row><entry>/a/b[c/d]</entry><entry>Match node "<code>b</code>" child of the top level node "<code>a</code>", when node
+ "<code>b</code>" has a child named "<code>c</code>", and "<code>c</code>" has a child named "<code>d</code>".
+ Node "<code>b</code>" is the selected node, while nodes "<code>b</code>" and "<code>b</code>" are used as criteria but are not
+ selected.</entry></row>
+ <row><entry>/a(/(b|c|d|)/e)[f/g/@something]</entry><entry>Match node "<code>/a/b/e</code>", "<code>/a/c/e</code>", "<code>/a/d/e</code>",
+ or "<code>/a/e</code>" when they also have a child "<code>f</code>" that itself has a child "<code>g</code>" with property
+ "<code>something</code>". None of the nodes may have same-name-sibling indexes.</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+ <para>
+ These examples show a few more advanced rules. Parentheses (i.e., '<code>(</code>' and '<code>)</code>') can be used
+ to define a set of options for names, as shown in the first and third rules. Whatever part of the selected node's path
+ appears between the parentheses is captured for use within the output path. Thus, the first input path in the previous table
+ would match node "<code>/a/b</code>", and "b" would be captured and could be used within the output path using "<code>$1</code>",
+ where the number used in the output path identifies the parentheses.
+ </para>
+ <para>
+ Square brackets can also be used to specify criteria on a node's properties or children. Whatever appears in between the square
+ brackets does not appear in the selected node.
+ </para>
+ <para>
+ Let's go back to the previous code fragment and look at the first path expression:
+ </para>
+ <programlisting><![CDATA[ //(*.(jpg|jpeg|gif|bmp|pcx|png)[*])/jcr:content[@jcr:data] => /images/$1 ]]></programlisting>
+ <para>
+ This matches a node named "<code>jcr:content</code>" with property "<code>jcr:data</code>" but no siblings with the same name,
+ and that is a child of a node whose name ends with "<code>.jpg</code>", "<code>.jpeg</code>", "<code>.gif</code>", "<code>.bmp</code>", "<code>.pcx</code>",
+ or "<code>.png</code>" that may have any same-name-sibling index. These nodes can appear at any level in the repository.
+ Note how the input path capture the filename (the segment containing the file extension), including any same-name-sibling index.
+ This filename is then used in the output path, which is where the sequenced content is placed.
+ </para>
+ </sect1>
<sect1 id="sequencer-library">
<title>Out-of-the-box sequencers</title>
<para>
@@ -309,19 +313,15 @@
<programlisting role="XML"><![CDATA[
<dependency>
<groupId>org.jboss.dna</groupId>
- <artifactId>dna-common</artifactId>
- <version>0.3</version>
-</dependency>
-<dependency>
- <groupId>org.jboss.dna</groupId>
<artifactId>dna-graph</artifactId>
- <version>0.3</version>
+ <version>0.5</version>
</dependency>
]]></programlisting>
<para>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, such as those listed here:</para>
<programlisting role="XML"><![CDATA[
+<!-- DNA-related unit testing utilities and classes -->
<dependency>
<groupId>org.jboss.dna</groupId>
<artifactId>dna-graph</artifactId>
@@ -330,6 +330,14 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-common</artifactId>
+ <version>0.5</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+</dependency>
+<!-- Unit testing -->
+<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
@@ -353,8 +361,7 @@
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>test</scope>
-</dependency>
- ]]></programlisting>
+</dependency> ]]></programlisting>
<para>Testing JBoss DNA sequencers does not require a JCR repository or the JBoss DNA services. (For more detail,
see the <link linkend="testing_custom_sequencers">testing section</link>.) However, if you want to do
integration testing with a JCR repository and the JBoss DNA services, you'll need additional dependencies for these libraries.</para>
@@ -374,81 +381,16 @@
<scope>test</scope>
</dependency>
]]></programlisting>
- <para>At this point, your project should be set up correctly, and you're ready to move on to
- <link linkend="custom_sequencer_implementation">writing the Java implementation</link> for your sequencer.</para>
- </sect2>
- <sect2 id="custom_sequencer_implementation">
- <title>Implementing the StreamSequencer interface</title>
- <para>After creating the project and setting up the dependencies, the next step is to create a Java class that implements
- the &StreamSequencer; interface. This interface is very straightforward and involves a single method:</para>
- <programlisting>
-public interface &StreamSequencer; {
-
- /**
- * Sequence the data found in the supplied stream, placing the output
- * information into the supplied map.
- *
- * @param stream the stream with the data to be sequenced; never null
- * @param output the output from the sequencing operation; never null
- * @param context the context for the sequencing operation; never null
- */
- void sequence( &InputStream; stream, &SequencerOutput; output, &SequencerContext; context );
-}
-</programlisting>
- <para>The job of a stream sequencer is to process the data in the supplied stream, and place into the &SequencerOutput;
- any information that is to go into the JCR repository. JBoss DNA figures out when your sequencer should be called
- (of course, using the sequencing configuration you'll add in a bit), and then makes sure the generated information
- is saved in the correct place in the repository.
- </para>
- <para>The &SequencerContext; provides information about
- the current sequencing operation, including the location and properties of the node being sequenced, the MIME type
- of the node being sequenced, and a location to record problems that aren't severe enough to warrant throwing an exception.
- </para>
- <para>The &SequencerOutput; class is fairly easy to use. There are basically two methods you need to call.
- One method sets the property values, while the other sets references to other nodes in the repository. Use these
- methods to describe the properties of the nodes you want to create, using relative paths for the nodes and
- valid JCR property names for properties and references. JBoss DNA will ensure that nodes are created or updated
- whenever they're needed.</para>
- <programlisting>
-public interface &SequencerOutput; {
-
- /**
- * Set the supplied property on the supplied node. The allowable
- * values are any of the following:
- * - primitives (which will be autoboxed)
- * - String instances
- * - String arrays
- * - byte arrays
- * - InputStream instances
- * - Calendar instances
- *
- * @param nodePath the path to the node containing the property;
- * may not be null
- * @param property the name of the property to be set
- * @param values the value(s) for the property; may be empty if
- * any existing property is to be removed
- */
- void setProperty( String nodePath, String property, Object... values );
-
- /**
- * Set the supplied reference on the supplied node.
- *
- * @param nodePath the path to the node containing the property;
- * may not be null
- * @param property the name of the property to be set
- * @param paths the paths to the referenced property, which may be
- * absolute paths or relative to the sequencer output node;
- * may be empty if any existing property is to be removed
- */
- void setReference( String nodePath, String property, String... paths );
-}
-</programlisting>
- <para>JBoss DNA will create nodes of type <code>nt:unstructured</code> unless you specify the value for the
- <code>jcr:primaryType</code> property. You can also specify the values for the <code>jcr:mixinTypes</code> property
- if you want to add mixins to any node.</para>
- <para>For a complete example of a sequencer, let's look at the &ImageMetadataSequencer;
- implementation:</para>
- <programlisting>
+ <para>
+ At this point, your project should be set up correctly, and you're ready to move on to
+ write your custom implementation of the &StreamSequencer; interface. As stated earlier, this should be fairly
+ straightforward: process the stream and generate the output that's appropriate for the kind of file being
+ sequenced.
+ </para>
+ <para>
+ Let's look at an example. Here is the complete code for the &ImageMetadataSequencer; implementation:
+ </para>
+ <programlisting>
public class &ImageMetadataSequencer; implements &StreamSequencer; {
public static final String METADATA_NODE = "image:metadata";
@@ -493,20 +435,26 @@
output.setProperty(METADATA_NODE, IMAGE_HEIGHT, metadata.getHeight());
output.setProperty(METADATA_NODE, IMAGE_BITS_PER_PIXEL, metadata.getBitsPerPixel());
output.setProperty(METADATA_NODE, IMAGE_PROGRESSIVE, metadata.isProgressive());
- output.setProperty(METADATA_NODE, IMAGE_NUMBER_OF_IMAGES, metadata.getNumberOfImages());
- output.setProperty(METADATA_NODE, IMAGE_PHYSICAL_WIDTH_DPI, metadata.getPhysicalWidthDpi());
- output.setProperty(METADATA_NODE, IMAGE_PHYSICAL_HEIGHT_DPI, metadata.getPhysicalHeightDpi());
- output.setProperty(METADATA_NODE, IMAGE_PHYSICAL_WIDTH_INCHES, metadata.getPhysicalWidthInch());
- output.setProperty(METADATA_NODE, IMAGE_PHYSICAL_HEIGHT_INCHES, metadata.getPhysicalHeightInch());
+ output.setProperty(METADATA_NODE, IMAGE_NUMBER_OF_IMAGES,
+ metadata.getNumberOfImages());
+ output.setProperty(METADATA_NODE, IMAGE_PHYSICAL_WIDTH_DPI,
+ metadata.getPhysicalWidthDpi());
+ output.setProperty(METADATA_NODE, IMAGE_PHYSICAL_HEIGHT_DPI,
+ metadata.getPhysicalHeightDpi());
+ output.setProperty(METADATA_NODE, IMAGE_PHYSICAL_WIDTH_INCHES,
+ metadata.getPhysicalWidthInch());
+ output.setProperty(METADATA_NODE, IMAGE_PHYSICAL_HEIGHT_INCHES,
+ metadata.getPhysicalHeightInch());
}
}
}
</programlisting>
- <para>
- Notice how the image metadata is extracted and the output graph is generated. A single node is created with the name <code>image:metadata</code>
- and with the <code>image:metadata</code> node type. No mixins are defined for the node, but several properties are set on the node
- using the values obtained from the image metadata. After this method returns, the constructed graph will be saved to the repository
- in all of the places defined by its configuration. (This is why only relative paths are used in the sequencer.)
+ <para>
+ Notice how the image metadata is extracted and the output graph is generated. A single node is created with the name
+ <code>image:metadata</code>
+ and with the <code>image:metadata</code> node type. No mixins are defined for the node, but several properties are set on the node
+ using the values obtained from the image metadata. After this method returns, the constructed graph will be saved to the repository
+ in all of the places defined by its configuration. (This is why only relative paths are used in the sequencer.)
</para>
</sect2>
<sect2 id="testing_custom_sequencers">
@@ -563,38 +511,18 @@
that <link linkend="using_dna">configure JBoss DNA</link> to use a custom sequencer, and to then upload
content using the JCR API, verifying that the custom sequencer did run. However, remember that JBoss DNA
runs sequencers asynchronously in the background, and you must synchronize your tests to ensure that the
- sequencers have a chance to run before checking the results. (One way of doing this (although, granted, not always reliable) is to wait for a second
- after uploading your content, shutdown the &SequencingService; and await its termination,
- and then check that the sequencer output has been saved to the JCR repository. For an example of this technique,
- see the <code>SequencingClientTest</code> unit test in the example application.)
+ sequencers have a chance to run before checking the results.
</para>
</sect2>
- <sect2 id="deploying_custom_sequencers">
- <title>Deploying custom sequencers</title>
- <para>The first step of deploying a sequencer consists of adding/changing the sequencer configuration (e.g., &SequencerConfig;)
- in the &SequencingService;. This was covered in the <link linkend="sequencing_service">previous chapter</link>.
- </para>
- <para>
- The second step is to make the sequencer implementation available to JBoss DNA. At this time, the JAR containing
- your new sequencer, as well as any JARs that your sequencer depends on, should be placed on your application classpath.</para>
- <note>
- <para>A future goal of JBoss DNA is to allow sequencers, connectors, and other extensions to be easily deployed into
- a runtime repository. This process will not only be much simpler, but it will also provide JBoss DNA
- with the information necessary to update configurations and create the appropriate class loaders for each extension.
- Having separate class loaders for each extension helps prevent the pollution of the common classpath,
- facilitates an isolated runtime environment to eliminate any dependency conflicts, and may potentially
- enable hot redeployment of newer extension versions.
- </para>
- </note>
- </sect2>
</sect1>
<sect1>
<title>Summary</title>
<para>
- In this chapter, we described how JBoss DNA sequences files as they're uploaded into a repository.
- And one of the things we mentioned was that each sequencer is handed (with other inputs) the MIME type of the file it is to process.
- How does DNA know what the MIME type is?
- JBoss DNA uses <emphasis>MIME type detectors</emphasis>, and this is the topic of the <link linkend="mimetypes">next chapter</link>.
+ In this chapter, we described how JBoss DNA sequences files as they're uploaded into a repository. We've also learned
+ in previous chapters about the JBoss DNA <link linkend="execution-context">execution contexts</link>,
+ <link linkend="graph-model">graph model</link>, and <link linkend="connector-framework">connectors</link>.
+ In the <link linkend="jcr">next part</link> we'll put all these pieces together to learn how
+ to set up a JBoss DNA repository and access it using the JCR API.
</para>
</sect1>
</chapter>
Modified: trunk/docs/reference/src/main/docbook/en-US/custom.dtd
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/custom.dtd 2009-06-09 18:48:18 UTC (rev 1016)
+++ trunk/docs/reference/src/main/docbook/en-US/custom.dtd 2009-06-09 19:46:34 UTC (rev 1017)
@@ -82,6 +82,7 @@
<!ENTITY UrlEncoder "<ulink url='&API;common/text/Jsr283Encoder.html'><classname>UrlEncoder</classname></ulink>">
<!ENTITY XmlNameEncoder "<ulink url='&API;common/text/Jsr283Encoder.html'><classname>XmlNameEncoder</classname></ulink>">
<!ENTITY XmlValueEncoder "<ulink url='&API;common/text/XmlValueEncoder.html'><classname>XmlValueEncoder</classname></ulink>">
+<!ENTITY Problems "<ulink url='&API;common/collection/Problems.html'><interface>Problems</interface></ulink>">
<!-- Types in dna-graph -->
@@ -141,7 +142,7 @@
<!ENTITY RequestProcessor "<ulink url='&API;graph/request/processor/RequestProcessor.html'><classname>RequestProcessor</classname></ulink>">
<!ENTITY StreamSequencer "<ulink url='&API;graph/sequencer/StreamSequencer.html'><interface>StreamSequencer</interface></ulink>">
<!ENTITY SequencerOutput "<ulink url='&API;graph/sequencer/SequencerOutput.html'><interface>SequencerOutput</interface></ulink>">
-<!ENTITY SequencerContext "<ulink url='&API;graph/sequencer/SequencerContext.html'><interface>SequencerContext</interface></ulink>">
+<!ENTITY StreamequencerContext "<ulink url='&API;graph/sequencer/StreamequencerContext.html'><interface>StreamequencerContext</interface></ulink>">
<!ENTITY MimeTypeDetector "<ulink url='&API;graph/mimetype/MimeTypeDetector.html'><interface>MimeTypeDetector</interface></ulink>">
<!ENTITY MockSequencerOutput "<ulink url='&API;graph/sequencer/MockSequencerOutput.html'><interface>MockSequencerOutput</interface></ulink>">
<!ENTITY MockSequencerContext "<ulink url='&API;graph/sequencer/MockSequencerContext.html'><interface>MockSequencerContext</interface></ulink>">
Modified: trunk/docs/reference/src/main/docbook/en-US/master.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/master.xml 2009-06-09 18:48:18 UTC (rev 1016)
+++ trunk/docs/reference/src/main/docbook/en-US/master.xml 2009-06-09 19:46:34 UTC (rev 1017)
@@ -85,7 +85,7 @@
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/core/graph.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/core/connector.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/core/sequencing.xml"/>
- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/core/configuration.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/jcr/configuration.xml"/>
</part>
<part id="jcr-part">
<title>JBoss DNA JCR</title>
16 years, 6 months
DNA SVN: r1016 - trunk/docs/reference/src/main/docbook/en-US.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2009-06-09 14:48:18 -0400 (Tue, 09 Jun 2009)
New Revision: 1016
Modified:
trunk/docs/reference/src/main/docbook/en-US/master.xml
Log:
Removed chapter on Deploying DNA JCR from this version
Modified: trunk/docs/reference/src/main/docbook/en-US/master.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/master.xml 2009-06-09 18:39:03 UTC (rev 1015)
+++ trunk/docs/reference/src/main/docbook/en-US/master.xml 2009-06-09 18:48:18 UTC (rev 1016)
@@ -97,7 +97,7 @@
</para>
</partintro>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/jcr/jcr.xml"/>
- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/jcr/deploying_dna_jcr.xml"/>
+ <!-- xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/jcr/deploying_dna_jcr.xml"/ -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/jcr/rest_service.xml"/>
</part>
<part id="provied-connectors-part">
16 years, 6 months
DNA SVN: r1014 - in trunk: docs/reference/src/main/docbook/en-US/content/jcr and 2 other directories.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2009-06-09 12:45:30 -0400 (Tue, 09 Jun 2009)
New Revision: 1014
Modified:
trunk/docs/reference/src/main/docbook/en-US/content/jcr/rest_service.xml
trunk/docs/reference/src/main/docbook/en-US/custom.dtd
trunk/extensions/dna-web-jcr-rest-war/src/main/webapp/WEB-INF/web.xml
trunk/extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrApplication.java
Log:
Final draft of REST chapter
Modified: trunk/docs/reference/src/main/docbook/en-US/content/jcr/rest_service.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/content/jcr/rest_service.xml 2009-06-09 16:36:50 UTC (rev 1013)
+++ trunk/docs/reference/src/main/docbook/en-US/content/jcr/rest_service.xml 2009-06-09 16:45:30 UTC (rev 1014)
@@ -89,7 +89,7 @@
</programlisting>
This request would generate a response that mapped the names of the available repositories to metadata information
about the repositories like so:
-<programlisting>
+<programlisting><![CDATA[
{
"dna%3arepository" : {
"repository" : {
@@ -98,7 +98,7 @@
}
}
}
-</programlisting>
+]]></programlisting>
The actual response wouldn't be pretty-printed like the example, but the format would be the same. The name
of the repository ("dna:repository" URL-encoded) is mapped to a repository object that contains a name
(the redundant "dna:repository") and a list of available resources within the repository and their respective
@@ -115,7 +115,7 @@
require that security be configured. This process is described in more detail in
<link linkend="dna_rest_server_configuration">a later section</link>. Assuming that security has been properly
configured, the response would look something like this:
-<programlisting>
+<programlisting><![CDATA[
{
"default" : {
"workspace" : {
@@ -124,7 +124,7 @@
}
}
}
-</programlisting>
+]]></programlisting>
Like the first response, this response consists of a list of workspace names mapped to metadata about the
workspaces. The example above only lists one workspace for simplicity, but there could be many different
workspaces returned in a real deployment. Note that the "items" resource builds the full URI to the root
@@ -137,14 +137,14 @@
</programlisting>
Any other item in the repository could be accessed by appending its path to the URI above. In a default
repository with no content, this would return the following response:
-<programlisting>
+<programlisting><![CDATA[
{
"properties": {
"jcr:primaryType": "dna:root",
"jcr:uuid": "97d7e2ef-996e-4d99-8ec2-dc623e6c2239"
},
"children": ["jcr:system"]
-</programlisting>
+]]></programlisting>
The response contains a mapping of property names to their values and an array of child names. Had one of
the properties been multi-valued, the values for that property would have been provided as an array as well,
as will shortly be shown.
@@ -156,7 +156,7 @@
GET http://www.example.com/resources/dna%3arepository/default/items?dna:depth=2
</programlisting>
Then the response would have contained details for the children of the root node as well.
-<programlisting>
+<programlisting><![CDATA[
{
"properties": {
"jcr:primaryType": "dna:root",
@@ -169,7 +169,7 @@
}
}
}
-</programlisting>
+]]></programlisting>
</para>
<para>
It is also possible to use the RESTful API to add, modify and remove repository content. Removes are simple -
@@ -182,7 +182,7 @@
Adding content simply requires a POST to the name of the <emphasis>relative</emphasis> root node of the
content that you wish to add and a request body in the same format as the response from a GET. Adding multiple
nodes at once is supported, as shown below.
-<programlisting>
+<programlisting><![CDATA[
POST http://www.example.com/resources/dna%3arepository/default/items/newNode
{
@@ -197,7 +197,7 @@
}
}
}
-</programlisting>
+]]></programlisting>
Note that protected properties like jcr:uuid are not provided but that the primary type and mixin types are
provided as properties. The REST server will translate these into the appropriate calls behind the
scenes. The response from the request will be empty by convention.
@@ -205,21 +205,21 @@
<para>
The PUT method allows for updates of nodes and properties. If the URI points to a property, the body of the
request should be the new JSON-encoded value for the property.
-<programlisting>
+<programlisting><![CDATA[
PUT http://www.example.com/resources/dna%3arepository/default/items/newNode/s...
"bar"
-</programlisting>
+]]></programlisting>
Setting multiple properties at once can be performed by providing a URI to a node instead of a property. The
body of the request should then be a JSON object that maps property names to their new values.
-<programlisting>
+<programlisting><![CDATA[
PUT http://www.example.com/resources/dna%3arepository/default/items/newNode
{
"someProperty": "foobar",
"someOtherProperty": "newValue"
}
-</programlisting>
+]]></programlisting>
<note>
<para>
The PUT method doesn't currently support adding or removing mixin types. This will be corrected in the future.
@@ -229,32 +229,320 @@
</note>
</para>
</sect1>
- <sect1 id="jcr_rest_spi">
- <title>Repository Providers</title>
- <para>
- One of the objects that must be supplied to many JBoss DNA components is an &ExecutionContext;. Some components
- require this context to be passed into individual methods, allowing the context to vary with each method invocation.
- Other components require the context to be provided before it's used, and will use that context for all its operations
- (until it is given a different one).
- </para>
- </sect1>
<sect1 id="dna_rest_server_configuration">
<title>Configuring the DNA REST Server</title>
<para>
- One of the objects that must be supplied to many JBoss DNA components is an &ExecutionContext;. Some components
- require this context to be passed into individual methods, allowing the context to vary with each method invocation.
- Other components require the context to be provided before it's used, and will use that context for all its operations
- (until it is given a different one).
+ The DNA REST server is deployed as a WAR and configured mostly through its web configuration file (web.xml).
+ Here is an example web configuration that is used for integration testing of the DNA REST server along with
+ an explanation of its parts.
+<programlisting role="xml"><![CDATA[
+<?xml version="1.0"?>
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd">
+<web-app>
+ <display-name>JBoss DNA JCR RESTful Interface</display-name>
+]]></programlisting>
+ This first section is largely boilerplate and should look familiar to anyone who has deployed a servlet-based
+ application before. The display-name can be customized, of course.
</para>
+ <para>
+ The next stanza configures the <link linkend="jcr_rest_spi">repository provider</link>.
+<programlisting role="xml"><![CDATA[
+ <!--
+ This parameter provides the fully-qualified name of a class that implements
+ the o.j.d.web.jcr.rest.spi.RepositoryProvider interface. It is required
+ by the DnaJcrDeployer that controls the lifecycle for the DNA REST server.
+ -->
+ <context-param>
+ <param-name>org.jboss.dna.web.jcr.rest.REPOSITORY_PROVIDER</param-name>
+ <param-value>org.jboss.dna.web.jcr.rest.spi.DnaJcrRepositoryProvider</param-value>
+ </context-param>
+]]></programlisting>
+ As noted above, this parameter informs the &DnaJcrDeployer; of the specific repository provider in use.
+ Unless you are using the JBoss DNA REST server to connect to a different JCR implementation, this should
+ never change.
+ </para>
+
+ <para>
+ Next we configure the DNA &JcrEngine; itself.
+<programlisting role="xml"><![CDATA[
+ <!--
+ This parameter, specific to the DnaJcrRepositoryProvider implementation, specifies
+ the name of the configuration file to initialize the repository or repositories.
+ This configuration file must be on the classpath and is given as a classpath-relative
+ directory.
+ -->
+ <context-param>
+ <param-name>org.jboss.dna.web.jcr.rest.CONFIG_FILE</param-name>
+ <param-value>/configRepository.xml</param-value>
+ </context-param>
+]]></programlisting>
+ If you are not familiar with the file format for a &JcrEngine; configuration file, you can build one
+ programatically with the &JcrConfiguration; class and call <code>save(...)</code> instead of <code>build()</code>
+ to output the configuration file that equates to the configuration.
+ </para>
+
+ <para>
+ This is followed by a bit of RESTEasy and JAX-RS boilerplate.
+<programlisting role="xml"><![CDATA[
+ <!--
+ This parameter defines the JAX-RS application class, which is really just a metadata class
+ that lets the JAX-RS engine (RESTEasy in this case) know which classes implement pieces
+ of the JAX-RS specification like exception handling and resource serving.
+
+ This should not be modified.
+ -->
+ <context-param>
+ <param-name>javax.ws.rs.Application</param-name>
+ <param-value>org.jboss.dna.web.jcr.rest.JcrApplication</param-value>
+ </context-param>
+
+ <!-- Required parameter for RESTEasy - should not be modified -->
+ <listener>
+ <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
+ </listener>
+
+ <!-- Required parameter for JBoss DNA REST - should not be modified -->
+ <listener>
+ <listener-class>org.jboss.dna.web.jcr.rest.DnaJcrDeployer</listener-class>
+ </listener>
+
+ <!-- Required parameter for RESTEasy - should not be modified -->
+ <servlet>
+ <servlet-name>Resteasy</servlet-name>
+ <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
+ </servlet>
+
+ <!-- Required parameter for JBoss DNA REST - should not be modified -->
+ <servlet-mapping>
+ <servlet-name>Resteasy</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+
+]]></programlisting>
+ In general, this part of the web configuration file should not be modified.
+ </para>
+
+ <para>
+ Finally, security must be configured for the REST server.
+<programlisting role="xml"><![CDATA[
+ <!--
+ The JBoss DNA REST implementation leverages the HTTP credentials to for authentication and authorization
+ within the JCR repository. It makes no sense to try to log into the JCR repository without credentials,
+ so this constraint helps lock down the repository.
+
+ This should generally not be modified.
+ -->
+ <security-constraint>
+ <display-name>DNA REST</display-name>
+ <web-resource-collection>
+ <web-resource-name>RestEasy</web-resource-name>
+ <url-pattern>/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <!--
+ A user must be assigned this role to connect to any JCR repository, in addition to needing the READONLY
+ or READWRITE roles to actually read or modify the data. This is not used internally, so another
+ role could be substituted here.
+ -->
+ <role-name>connect</role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <!--
+ Any auth-method will work for JBoss DNA. BASIC is used this example for simplicity.
+ -->
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ </login-config>
+
+ <!--
+ This must match the role-name in the auth-constraint above.
+ -->
+ <security-role>
+ <role-name>connect</role-name>
+ </security-role>
+</web-app>
+
+]]></programlisting>
+ As noted above, the REST server will not function properly unless security is configured. All authorization
+ methods supported by the Servlet specification are supported by JBoss DNA and can be used interchangeable, as
+ long as authenticated users have the connect role listed above.
+ </para>
+
</sect1>
<sect1 id="dna_rest_server_deployment">
<title>Deploying the DNA REST Server</title>
<para>
- One such implementation is the &JaasSecurityContext;, which delegates any authentication or authorization requests to a
- <ulink url="http://java.sun.com/javase/technologies/security/">Java Authentication and Authorization Service (JAAS)</ulink>
- provider. This is the standard approach for authenticating and authorizing in Java, and is the default mechanism
- used by the &JcrEngine;.
+ Deploying the DNA REST server only requires three steps: <link linkend="dna_rest_server_configuration">
+ preparing the web configuration</link>, configuring the users and their roles in your web container
+ (outside the scope of this document), and assembling the WAR. This section describes the requirements
+ for assembling the WAR.
</para>
+ <para>
+ If you are using Maven to build your projects, the WAR can be built from a POM. Here is a portion of the
+ POM used to build the JBoss DNA REST Server integration subproject.
+<programlisting role='xml'> <![CDATA[
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>dna</artifactId>
+ <groupId>org.jboss.dna</groupId>
+ <version>0.5-SNAPSHOT</version>
+ <relativePath>../..</relativePath>
+ </parent>
+ <artifactId>dna-web-jcr-rest-war</artifactId>
+ <packaging>war</packaging>
+ <name>JBoss DNA JCR REST Servlet</name>
+ <description>JBoss DNA servlet that provides RESTful access to JCR items</description>
+ <url>http://labs.jboss.org/dna</url>
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-web-jcr-rest</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.4.3</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>resteasy-client</artifactId>
+ <version>1.0-beta-8</version>
+ </dependency>
+ </dependencies>
+</project>
+
+]]></programlisting>
+ If you use this approach, make sure that web configuration file is in the <code>/src/main/webapp/WEB-INF</code>
+ directory.
+ </para>
+ <para>
+ The JBoss REST Server WAR is still easy enough to build if you are not using Maven. Simply construct a WAR with
+ the following contents:
+<programlisting>
++ /WEB-INF
+ + /classes
+ | + configRepository.xml
+ | + log4j.properties (Optional)
+ + /lib
+ | + activation-1.1.jar
+ | + antlr-runtime-3.1.3.jar
+ | + commons-codec-1.2.jar
+ | + commons-httpclient-3.1.jar
+ | + commons-logging-1.0.4.jar
+ | + dna-cnd-0.5-SNAPSHOT.jar
+ | + dna-common-0.5-SNAPSHOT.jar
+ | + dna-connector-federation-0.5-SNAPSHOT.jar
+ | + dna-graph-0.5-SNAPSHOT.jar
+ | + dna-jcr-0.5-SNAPSHOT.jar
+ | + dna-repository-0.5-SNAPSHOT.jar
+ | + dna-web-jcr-rest-0.5-SNAPSHOT.jar
+ | + FastInfoset-1.2.2.jar
+ | + google-collect-snapshot-20080530.jar
+ | + hamcrest-core-1.1.jar
+ | + javassist-3.6.0.GA.jar
+ | + jaxb-api-2.1.jar
+ | + jaxb-impl-2.1.9.jar
+ | + jaxrs-api-1.1-RC2.jar
+ | + jcip-annotations-1.0.jar
+ | + jcr-1.0.1.jar
+ | + jettison-1.0.1.jar
+ | + joda-time-1.4.jar
+ | + jsr250-api-1.0.jar
+ | + junit-dep-4.4.jar
+ | + resteasy-client-1.0-beta-8.jar
+ | + resteasy-common-1.0-beta-8.jar
+ | + resteasy-jaxb-provider-1.1-RC2.jar
+ | + resteasy-jaxrs-1.1-RC2.jar
+ | + scannotation-1.0.2.jar
+ | + servlet-api-2.5.jar
+ | + sjsxp-1.0.1.jar
+ | + slf4j-api-1.4.3.jar
+ | + slf4j-log4j12-1.4.3.jar
+ | + slf4j-simple-1.5.2.jar
+ | + stax-api-1.0-2.jar
+ | + webserver-1.3.3.jar
+ + web.xml
+
+</programlisting>
+ If you are using sequencers or any connectors other than the in-memory or federated connector, you will also have
+ to add the JARs for those dependencies into the <code>WEB-INF/lib</code> directory as well. You will also have to
+ change the version numbers on the JARs to reflect the current version of JBoss DNA.
+ </para>
+ <para>
+ This WAR can be deployed into your servlet container.
+ </para>
</sect1>
+ <sect1 id="jcr_rest_spi">
+ <title>Repository Providers</title>
+ <para>
+ The JBoss DNA REST server can also be used as an interface to to other JCR repositories by creating
+ an implementation of the &RepositoryProvider; interface that connects to the other repository.
+ </para>
+ <para>
+ The &RepositoryProvider; only has a few methods that must be implemented. When the &DnaJcrDeployer; starts
+ up, it will dynamically load the &RepositoryProvider; implementation (as noted above) and call the <code>
+ startup(ServletContext)</code> method on the provider. The provider can use this method to load any
+ required configuration parameters from the web configuration (web.xml) and initialize the repository.
+ </para>
+ <para>
+ As an example, here's the DNA JCR provider implementation of this method with exception handling omitted for brevity.
+<programlisting><![CDATA[
+public void startup( ServletContext context ) {
+ String configFile = context.getInitParameter(CONFIG_FILE);
+
+ InputStream configFileInputStream = getClass().getResourceAsStream(configFile);
+ jcrEngine = new JcrConfiguration().loadFrom(configFileInputStream).build();
+ jcrEngine.start();
+
+}
+]]></programlisting>
+ As you can see, the name of configuration file for the &JcrEngine; is read from the servlet context and used
+ to initialize the engine.
+ Once the repository has been started, it is now ready to accept the main methods that provide the interface
+ to the repository.
+ </para>
+ <para>
+ The first method returns the set of repository names supported by this REST server.
+<programlisting><![CDATA[
+public Set<String> getJcrRepositoryNames() {
+ return new HashSet<String>(jcrEngine.getRepositoryNames());
+}
+]]></programlisting>
+ The JBoss DNA JCR repository does support multiple repositories on the same server. Other JCR implementations
+ that don't support multiple repositories are free to return a singleton set containing any string from this method.
+ </para>
+ <para>
+ The other required method returns an open JCR &Session; for the user from the current request in a given repository
+ and workspace. The provider can use the &HttpServletRequest; to get the authentication credentials for the
+ HTTP user.
+<programlisting><![CDATA[
+public Session getSession( HttpServletRequest request,
+ String repositoryName,
+ String workspaceName ) throws RepositoryException {
+ Repository repository = getRepository(repositoryName);
+
+ SecurityContext context = new ServletSecurityContext(request);
+ Credentials credentials = new SecurityContextCredentials(context);
+ return repository.login(credentials, workspaceName);
+
+}
+]]></programlisting>
+ The <code>getSession(...)</code> method is used by most of the REST server methods to access the JCR
+ repository and return results as needed.
+ </para>
+ <para>
+ Finally, the <code>shutdown()</code> method signals that the web context is being undeployed and the JCR
+ repository should shutdown and clean up any resources that are in use.
+ </para>
+ </sect1>
</chapter>
Modified: trunk/docs/reference/src/main/docbook/en-US/custom.dtd
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/custom.dtd 2009-06-09 16:36:50 UTC (rev 1013)
+++ trunk/docs/reference/src/main/docbook/en-US/custom.dtd 2009-06-09 16:45:30 UTC (rev 1014)
@@ -185,4 +185,6 @@
<!ENTITY ImageMetadata "<ulink url='&API;sequencer/image/ImageMetadata.html'><classname>ImageMetadata</classname></ulink>">
<!ENTITY ImageSequencerI18n "<ulink url='&API;sequencer/image/ImageSequencerI18n.html'><classname>ImageSequencerI18n</classname></ulink>">
<!ENTITY ApertureMimeTypeDetector "<ulink url='&API;mimetype/aperture/ApertureMimeTypeDetector.html'><classname>ApertureMimeTypeDetector</classname></ulink>">
+<!ENTITY DnaJcrDeployer "<ulink url='&API;web/jcr/rest/DnaJcrDeployer.html'><classname>DnaJcrDeployer</classname></ulink>">
+<!ENTITY RepositoryProvider "<ulink url='&API;web/jcr/rest/spi/RepositoryProvider.html'><classname>RepositoryProvider</classname></ulink>">
Modified: trunk/extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrApplication.java
===================================================================
--- trunk/extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrApplication.java 2009-06-09 16:36:50 UTC (rev 1013)
+++ trunk/extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrApplication.java 2009-06-09 16:45:30 UTC (rev 1014)
@@ -23,7 +23,8 @@
*/
package org.jboss.dna.web.jcr.rest;
-import java.util.Collections;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
@@ -41,7 +42,12 @@
*/
@Override
public Set<Class<?>> getClasses() {
- return Collections.<Class<?>>singleton(JcrResources.class);
+ return new HashSet<Class<?>>(Arrays.asList(new Class<?>[] {
+ JcrResources.class,
+ JcrResources.JSONExceptionMapper.class,
+ JcrResources.NotFoundExceptionMapper.class,
+ JcrResources.RepositoryExceptionMapper.class,
+ }));
}
}
Modified: trunk/extensions/dna-web-jcr-rest-war/src/main/webapp/WEB-INF/web.xml
===================================================================
--- trunk/extensions/dna-web-jcr-rest-war/src/main/webapp/WEB-INF/web.xml 2009-06-09 16:36:50 UTC (rev 1013)
+++ trunk/extensions/dna-web-jcr-rest-war/src/main/webapp/WEB-INF/web.xml 2009-06-09 16:45:30 UTC (rev 1014)
@@ -22,46 +22,68 @@
<web-app>
<display-name>JBoss DNA JCR RESTful Interface</display-name>
+ <!--
+ This parameter provides the fully-qualified name of a class that implements
+ the o.j.d.web.jcr.rest.spi.RepositoryProvider interface. It is required
+ by the DnaJcrDeployer that controls the lifecycle for the DNA REST server.
+ -->
<context-param>
<param-name>org.jboss.dna.web.jcr.rest.REPOSITORY_PROVIDER</param-name>
<param-value>org.jboss.dna.web.jcr.rest.spi.DnaJcrRepositoryProvider</param-value>
</context-param>
+ <!--
+ This parameter, specific to the DnaJcrRepositoryProvider implementation, specifies
+ the name of the configuration file to initialize the repository or repositories.
+ This configuration file must be on the classpath and is given as a classpath-relative
+ directory.
+ -->
<context-param>
<param-name>org.jboss.dna.web.jcr.rest.CONFIG_FILE</param-name>
<param-value>/configRepository.xml</param-value>
</context-param>
+ <!--
+ This parameter defines the JAX-RS application class, which is really just a metadata class
+ that lets the JAX-RS engine (RESTEasy in this case) know which classes implement pieces
+ of the JAX-RS specification like exception handling and resource serving.
+
+ This should not be modified.
+ -->
<context-param>
- <param-name>resteasy.providers</param-name>
- <param-value>org.jboss.dna.web.jcr.rest.JcrResources$NotFoundExceptionMapper,
- org.jboss.dna.web.jcr.rest.JcrResources$JSONExceptionMapper,
- org.jboss.dna.web.jcr.rest.JcrResources$RepositoryExceptionMapper</param-value>
- </context-param>
-
- <context-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>org.jboss.dna.web.jcr.rest.JcrApplication</param-value>
</context-param>
+ <!-- Required parameter for RESTEasy - should not be modified -->
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
+ <!-- Required parameter for JBoss DNA REST - should not be modified -->
<listener>
<listener-class>org.jboss.dna.web.jcr.rest.DnaJcrDeployer</listener-class>
</listener>
+ <!-- Required parameter for RESTEasy - should not be modified -->
<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
</servlet>
+ <!-- Required parameter for JBoss DNA REST - should not be modified -->
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
+ <!--
+ The JBoss DNA REST implementation leverages the HTTP credentials to for authentication and authorization
+ within the JCR repository. It makes no sense to try to log into the JCR repository without credentials,
+ so this constraint helps lock down the repository.
+
+ This should generally not be modified.
+ -->
<security-constraint>
<display-name>DNA REST</display-name>
<web-resource-collection>
@@ -69,14 +91,25 @@
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
+ <!--
+ A user must be assigned this role to connect to any JCR repository, in addition to needing the READONLY
+ or READWRITE roles to actually read or modify the data. This is not used internally, so another
+ role could be substituted here.
+ -->
<role-name>connect</role-name>
</auth-constraint>
</security-constraint>
+ <!--
+ Any auth-method will work for JBoss DNA. BASIC is used this example for simplicity.
+ -->
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
+ <!--
+ This must match the role-name in the auth-constraint above.
+ -->
<security-role>
<role-name>connect</role-name>
</security-role>
16 years, 6 months
DNA SVN: r1013 - trunk/docs/reference/src/main/docbook/en-US/content.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-06-09 12:36:50 -0400 (Tue, 09 Jun 2009)
New Revision: 1013
Modified:
trunk/docs/reference/src/main/docbook/en-US/content/future.xml
Log:
Updated the last chapter in the Reference Guide to better reflect the current status and plans for the immediate future.
Modified: trunk/docs/reference/src/main/docbook/en-US/content/future.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/content/future.xml 2009-06-09 15:16:00 UTC (rev 1012)
+++ trunk/docs/reference/src/main/docbook/en-US/content/future.xml 2009-06-09 16:36:50 UTC (rev 1013)
@@ -31,21 +31,31 @@
<chapter id="future">
<title>Looking to the future</title>
<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.
- We've also established the foundation for JBoss DNA repositories, including a number of <link linkend="repository-connectors">connectors</link>.
- We'll continue to expand our library of sequencers and connectors, as well as expand our support of JCR.
- 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 farther out on our roadmap, and at this time have not been
- targeted to a particular release.
+ JBoss DNA &version; adds a lot of new features and capabilities. It introduced an initial RESTful server that makes
+ JCR repositories accessible over HTTP to clients. The JCR implementation was enhanced to support more features,
+ including the ability to define and register node types using the Compact Node Definition (CND) format.
+ A new configuration system was added, making it very easy to configure and manage the JBoss DNA JCR engine.
+ An observation framework was added to the graph API. The federation connector was rewritten to improve performance
+ and correct several issues. And quite a few issues were fixed.
</para>
<para>
- 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!
+ What's next for JBoss DNA? Passing all of the JCR API compatibility tests for Level 1 and Level 2,
+ plus some of the optional features, is the primary focus for the next release. Of course, there are a handful of
+ improvements we'd like to make under the covers, and a few outstanding issues that we'll address.
+ Farther out on our <ulink url="&Roadmap;">roadmap</ulink> are the development of additional connectors and sequencers,
+ some Eclipse tooling for publishing artifacts to a repository, and quite a few other interesting features.
</para>
<para>
+ We're always looking for suggestions and contributors. If you'd like to get involved on JBoss DNA, the first
+ step is joining the <ulink url="&Home;lists.html">mailing lists</ulink> or hopping into our chat room
+ on IRC (at irc.freenode.net#jbossdna). You can also <ulink url="&Home;subversion.html">download the code</ulink>
+ and get it building, and start looking for simple issues or bugs in our
+ <ulink url="&JIRA;">JIRA issue management system</ulink>.
+ </para>
+ <para>
+ But if nothing else, please contact us and let us know how you're using JBoss DNA and what we can do to make it even better.
+ </para>
+ <para>
And, if you haven't already, check out our &GettingStarted; guide, which has examples that you can build and run to see
JBoss DNA in action.
</para>
16 years, 6 months
DNA SVN: r1012 - in trunk/docs/reference/src/main/docbook/en-US: content and 1 other directories.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-06-09 11:16:00 -0400 (Tue, 09 Jun 2009)
New Revision: 1012
Modified:
trunk/docs/reference/src/main/docbook/en-US/content/core/execution_context.xml
trunk/docs/reference/src/main/docbook/en-US/content/core/graph.xml
trunk/docs/reference/src/main/docbook/en-US/content/introduction.xml
trunk/docs/reference/src/main/docbook/en-US/master.xml
Log:
Minor edits to the Reference Guide
Modified: trunk/docs/reference/src/main/docbook/en-US/content/core/execution_context.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/content/core/execution_context.xml 2009-06-09 13:11:36 UTC (rev 1011)
+++ trunk/docs/reference/src/main/docbook/en-US/content/core/execution_context.xml 2009-06-09 15:16:00 UTC (rev 1012)
@@ -570,7 +570,7 @@
facilities throughout the system.
</para>
<para>
- In the <link linkend="graph-api">next chapter</link>, we'll dive into Graph API and will introduce the notion of
+ In the <link linkend="graph-model">next chapter</link>, we'll dive into Graph API and will introduce the notion of
nodes, paths, names, and properties, that are so essential and used throughout JBoss DNA.
</para>
</sect1>
Modified: trunk/docs/reference/src/main/docbook/en-US/content/core/graph.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/content/core/graph.xml 2009-06-09 13:11:36 UTC (rev 1011)
+++ trunk/docs/reference/src/main/docbook/en-US/content/core/graph.xml 2009-06-09 15:16:00 UTC (rev 1012)
@@ -28,8 +28,8 @@
<!ENTITY % CustomDTD SYSTEM "../../custom.dtd">
%CustomDTD;
]>
-<chapter id="graph_api">
- <title>Graph API</title>
+<chapter id="graph-model">
+ <title>Graph Model</title>
<para>
One of the central concepts within JBoss DNA is that of its <emphasis>graph model</emphasis>.
Information is structured into a hierarchy of nodes with properties, where nodes in the hierarchy
Modified: trunk/docs/reference/src/main/docbook/en-US/content/introduction.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/content/introduction.xml 2009-06-09 13:11:36 UTC (rev 1011)
+++ trunk/docs/reference/src/main/docbook/en-US/content/introduction.xml 2009-06-09 15:16:00 UTC (rev 1012)
@@ -268,41 +268,49 @@
<itemizedlist>
<listitem>
<para>
- <emphasis role="strong">dna-common</emphasis>
- is a low-level library of common utilities and frameworks, including logging, progress monitoring,
- internationalization/localization, text translators, component management, and class loader factories.
+ <emphasis role="strong">dna-jcr</emphasis>
+ contains JBoss DNA's implementation of the JCR API. If you're using JBoss DNA as a JCR repository, this is the
+ top-level dependency that you'll want to use. The module defines all required dependencies, except for
+ the repository connector(s) and any sequencer implementations needed by your configuration.
+ As we'll see later on, using JBoss DNA as a JCR repository is easy: simply create a configuration, start the JCR engine,
+ get the JCR &Repository; object for your repository, and then use the JCR API.
+ This module also contains the Jackrabbit JCR API unit tests that verify the behavior of the JBoss DNA implementation.
+ As DNA does not fully implement the JCR 1.0.1 specification, there are a series of tests that are currently commented
+ out in this module. The <code>dna-jcr-tck</code> module contains all of these tests.
</para>
</listitem>
<listitem>
<para>
- <emphasis role="strong">dna-graph</emphasis>
- defines the graph Application Programming Interface (API) and Service Provider Interface (SPI) for DNA,
- including the repository connectors, sequencers, graph interfaces, and MIME type detectors.
+ <emphasis role="strong">dna-repository</emphasis>
+ provides the core DNA graph engine and services for managing repository connections, sequencers, MIME type detectors,
+ and observation. If you're using JBoss DNA repositories via our graph API rather than JCR, then this is where you'd start.
</para>
</listitem>
<listitem>
<para>
- <emphasis role="strong">dna-repository</emphasis>
- is the main module and provides the repository-oriented services, including the Repository Service, Sequencing
- Service, Observation Service, and Rules Service.
+ <emphasis role="strong">dna-graph</emphasis>
+ defines the Application Programming Interface (API) for JBoss DNA's low-level graph model,
+ including a DSL-like API for working with graph content. This module also defines the
+ APIs necessary to implement custom connectors, sequencers, and MIME type detectors.
</para>
</listitem>
<listitem>
<para>
<emphasis role="strong">dna-cnd</emphasis>
- provides a utilities for reading and writing files in the CND (Compact Node Definition) format.
+ provides a self-contained utility for parsing CND (Compact Node Definition) files and transforming
+ the node definitions into a graph notation compatible with JBoss DNA's JCR implementation.
</para>
</listitem>
<listitem>
<para>
- <emphasis role="strong">dna-jcr</emphasis>
- provides the JBoss DNA implementation of the JCR API, which relies upon a repository connector, such as the
- Federation Connector (see
- <code>dna-connector-federation</code>
- ). As DNA does not fully implement the JCR 1.0.1 specification, there are a series of tests that are currently commented
- out in this module. The <code>dna-jcr-tck</code> module contains all of these tests.
+ <emphasis role="strong">dna-common</emphasis>
+ is a small low-level library of common utilities and frameworks, including logging, progress monitoring,
+ internationalization/localization, text translators, component management, and class loader factories.
</para>
</listitem>
+ </itemizedlist>
+ There are several modules that provide system- and integration-level tests:
+ <itemizedlist>
<listitem>
<para>
<emphasis role="strong">dna-jcr-tck</emphasis>
@@ -315,9 +323,9 @@
<para>
<emphasis role="strong">dna-integration-tests</emphasis>
provides a home for all of the integration tests that involve more components that just unit tests. Integration
- tests are often more complicated, take longer, and involve testing the integration and functionality of many
- components (whereas unit tests focus on testing a single class or component and may use stubs or mock objects for
- other components).
+ tests are often more complicated, take longer, and involve testing the integration and functionality of multiple
+ components (whereas unit tests focus on testing a single class or component and may use stubs or mock objects
+ to isolate the code being tested from other related components).
</para>
</listitem>
</itemizedlist>
Modified: trunk/docs/reference/src/main/docbook/en-US/master.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/master.xml 2009-06-09 13:11:36 UTC (rev 1011)
+++ trunk/docs/reference/src/main/docbook/en-US/master.xml 2009-06-09 15:16:00 UTC (rev 1012)
@@ -101,7 +101,7 @@
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/jcr/rest_service.xml"/>
</part>
<part id="provied-connectors-part">
- <title>Provided Connectors</title>
+ <title>Connector Library</title>
<partintro>
<para>
The JBoss DNA project provides a number of <link linkend="connector_framework">connectors</link> out-of-the-box.
@@ -118,7 +118,7 @@
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/connectors/jdbc_metadata.xml"/>
</part>
<part id="provied-sequencers-part">
- <title>Provided Sequencers</title>
+ <title>Sequencer Library</title>
<partintro>
<para>
The JBoss DNA project provides a number of <link linkend="sequencing_framework">sequencers</link> out-of-the-box.
@@ -135,7 +135,7 @@
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/sequencers/mp3.xml"/>
</part>
<part id="provied-mime-type-detectors-part">
- <title>Provided MIME type detectors</title>
+ <title>MIME Type Detector Library</title>
<partintro>
<para>
The JBoss DNA project provides a number of <link linkend="mime-type-detectors">MIME type detectors</link> out-of-the-box.
16 years, 6 months
DNA SVN: r1011 - trunk/docs/reference/src/main/docbook/en-US/content/jcr.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2009-06-09 09:11:36 -0400 (Tue, 09 Jun 2009)
New Revision: 1011
Modified:
trunk/docs/reference/src/main/docbook/en-US/content/jcr/rest_service.xml
Log:
Adding WIP version of REST server documentation
Modified: trunk/docs/reference/src/main/docbook/en-US/content/jcr/rest_service.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/content/jcr/rest_service.xml 2009-06-09 12:14:45 UTC (rev 1010)
+++ trunk/docs/reference/src/main/docbook/en-US/content/jcr/rest_service.xml 2009-06-09 13:11:36 UTC (rev 1011)
@@ -31,16 +31,203 @@
<chapter id="rest_service">
<title>The JBoss DNA REST Server</title>
<para>
- Placeholder for the JBoss DNA REST Server documentation
+ JBoss DNA now provides a RESTful interface to its JCR implementation that allows HTTP-based publishing
+ and unpublishing of content. Although the initial version of this REST server only supports the JBoss DNA
+ JCR implementation, it has been designed to make integration with other JCR implementors easy. This
+ chapter describes how to configure and deploy the REST server.
</para>
<sect1 id="supported_rest_resources">
- <title>Supported Resources and URIs</title>
+ <title>Supported Resources and Methods</title>
<para>
- One of the objects that must be supplied to many JBoss DNA components is an &ExecutionContext;. Some components
- require this context to be passed into individual methods, allowing the context to vary with each method invocation.
- Other components require the context to be provided before it's used, and will use that context for all its operations
- (until it is given a different one).
+ The REST Server currently supports the URIs and HTTP methods described below. The URI patterns assume
+ that the REST server is deployed at its conventional location of "/resources". These URI patterns would
+ change if the REST server were deployed under a different web context and URI patterns below would
+ change accordingly. Currently, only JSON-encoded responses are provided.
</para>
+ <table frame='all'>
+ <title>Supported URIs for the JBoss DNA REST Server</title>
+ <tgroup cols='3' align='left' colsep='1' rowsep='1'>
+ <colspec colname='URI' colwidth="3*"/>
+ <colspec colname='methods' colwidth="1*"/>
+ <colspec colname='description' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>URI Pattern</entry>
+ <entry>HTTP Method(s)</entry>
+ <entry>HTTP Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>/resources</entry>
+ <entry>Returns a list of accessible repositories</entry>
+ <entry>GET</entry>
+ </row>
+ <row>
+ <entry>/resources/{repositoryName}</entry>
+ <entry>Returns a list of accessible workspaces within that repository</entry>
+ <entry>GET</entry>
+ </row>
+ <row>
+ <entry>/resources/{repositoryName}/{workspaceName}</entry>
+ <entry>Returns a list of available operations within the workspace</entry>
+ <entry>GET</entry>
+ </row>
+ <row>
+ <entry>/resources/{repositoryName}/{workspaceName}/item/{path}</entry>
+ <entry>Accesses the item (node or property) at the path</entry>
+ <entry>ALL</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <para>
+ Note that this approach supports dynamic discovery of the available repositories on the server. A typical
+ conversation might start with a request to the server to check the available repositories.
+<programlisting>
+GET http://www.example.com/resources
+</programlisting>
+ This request would generate a response that mapped the names of the available repositories to metadata information
+ about the repositories like so:
+<programlisting>
+{
+ "dna%3arepository" : {
+ "repository" : {
+ "name" : "dna%3arepository",
+ "resources" : { "workspaces":"/resources/dna%3arepository" }
+ }
+ }
+}
+</programlisting>
+ The actual response wouldn't be pretty-printed like the example, but the format would be the same. The name
+ of the repository ("dna:repository" URL-encoded) is mapped to a repository object that contains a name
+ (the redundant "dna:repository") and a list of available resources within the repository and their respective
+ URIs. Note that JBoss DNA supports deploying multiple JCR repositories side-by-side on the same server,
+ so this response could easily contain multiple repositories in a real deployment.
+ </para>
+ <para>
+ The only thing that you can do with a repository through the REST interface at this time is to
+ get a list of its workspaces. A request to do so can be built up from the previous response like this:
+<programlisting>
+GET http://www.example.com/resources/dna%3arepository
+</programlisting>
+ This request (and all of the following requests) actually create a JCR &Session; to service the request and
+ require that security be configured. This process is described in more detail in
+ <link linkend="dna_rest_server_configuration">a later section</link>. Assuming that security has been properly
+ configured, the response would look something like this:
+<programlisting>
+{
+ "default" : {
+ "workspace" : {
+ "name" : "default",
+ "resources" : { "items":"/resources/dna%3arepository/default/items" }
+ }
+ }
+}
+</programlisting>
+ Like the first response, this response consists of a list of workspace names mapped to metadata about the
+ workspaces. The example above only lists one workspace for simplicity, but there could be many different
+ workspaces returned in a real deployment. Note that the "items" resource builds the full URI to the root
+ of the items hierarchy, including the encoding of the repository name and the workspace name.
+ </para>
+ <para>
+ Now a request can be built to retrieve the root item of the repository.
+<programlisting>
+GET http://www.example.com/resources/dna%3arepository/default/items
+</programlisting>
+ Any other item in the repository could be accessed by appending its path to the URI above. In a default
+ repository with no content, this would return the following response:
+<programlisting>
+{
+ "properties": {
+ "jcr:primaryType": "dna:root",
+ "jcr:uuid": "97d7e2ef-996e-4d99-8ec2-dc623e6c2239"
+ },
+ "children": ["jcr:system"]
+</programlisting>
+ The response contains a mapping of property names to their values and an array of child names. Had one of
+ the properties been multi-valued, the values for that property would have been provided as an array as well,
+ as will shortly be shown.
+ </para>
+ <para>
+ The items resource also contains an option query parameter: <code>dna:depth</code>. This parameter, which defaults
+ to 1, controls how deep the hierarchy of returned nodes should be. Had the request had the parameter:
+<programlisting>
+GET http://www.example.com/resources/dna%3arepository/default/items?dna:depth=2
+</programlisting>
+ Then the response would have contained details for the children of the root node as well.
+<programlisting>
+{
+ "properties": {
+ "jcr:primaryType": "dna:root",
+ "jcr:uuid": "163bc5e5-3b57-4e63-b2ae-ededf43d3445"
+ },
+ "children": {
+ "jcr:system": {
+ "properties": {"jcr:primaryType": "dna:system"},
+ "children": ["dna:namespaces"]
+ }
+ }
+}
+</programlisting>
+ </para>
+ <para>
+ It is also possible to use the RESTful API to add, modify and remove repository content. Removes are simple -
+ a DELETE request with no body returns a response with no body.
+<programlisting>
+DELETE http://www.example.com/resources/dna%3arepository/default/items/path/to/d...
+</programlisting>
+ </para>
+ <para>
+ Adding content simply requires a POST to the name of the <emphasis>relative</emphasis> root node of the
+ content that you wish to add and a request body in the same format as the response from a GET. Adding multiple
+ nodes at once is supported, as shown below.
+<programlisting>
+POST http://www.example.com/resources/dna%3arepository/default/items/newNode
+
+{
+ "properties": {
+ "jcr:primaryType": "nt:unstructured",
+ "jcr:mixinTypes": "mix:referenceable",
+ "someProperty": "foo"
+ },
+ "children": {
+ "newChildNode": {
+ "properties": {"jcr:primaryType": "nt:unstructured"}
+ }
+ }
+}
+</programlisting>
+ Note that protected properties like jcr:uuid are not provided but that the primary type and mixin types are
+ provided as properties. The REST server will translate these into the appropriate calls behind the
+ scenes. The response from the request will be empty by convention.
+ </para>
+ <para>
+ The PUT method allows for updates of nodes and properties. If the URI points to a property, the body of the
+ request should be the new JSON-encoded value for the property.
+<programlisting>
+PUT http://www.example.com/resources/dna%3arepository/default/items/newNode/s...
+
+"bar"
+</programlisting>
+ Setting multiple properties at once can be performed by providing a URI to a node instead of a property. The
+ body of the request should then be a JSON object that maps property names to their new values.
+<programlisting>
+PUT http://www.example.com/resources/dna%3arepository/default/items/newNode
+
+{
+ "someProperty": "foobar",
+ "someOtherProperty": "newValue"
+}
+</programlisting>
+ <note>
+ <para>
+ The PUT method doesn't currently support adding or removing mixin types. This will be corrected in the future.
+ A <ulink url="https://jira.jboss.org/jira/browse/DNA-447">JIRA issue</ulink> has been created to help
+ track this issue.
+ </para>
+ </note>
+ </para>
</sect1>
<sect1 id="jcr_rest_spi">
<title>Repository Providers</title>
16 years, 6 months
DNA SVN: r1010 - trunk/extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2009-06-09 08:14:45 -0400 (Tue, 09 Jun 2009)
New Revision: 1010
Modified:
trunk/extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrResources.java
Log:
Cleaned up another dangling Javadoc reference to an unimplemented method
Modified: trunk/extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrResources.java
===================================================================
--- trunk/extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrResources.java 2009-06-09 12:13:04 UTC (rev 1009)
+++ trunk/extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrResources.java 2009-06-09 12:14:45 UTC (rev 1010)
@@ -94,9 +94,6 @@
* <td>accesses the item (node or property) at the path</td>
* <td>ALL</td>
* </tr>
- * <td>/resources/{repositoryName}/{workspaceName}/node/{uuid}</td>
- * <td>accesses the node with the given UUID</td>
- * <td>ALL</td> </tr>
* </table>
*/
@Immutable
16 years, 6 months
DNA SVN: r1009 - trunk/extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2009-06-09 08:13:04 -0400 (Tue, 09 Jun 2009)
New Revision: 1009
Modified:
trunk/extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrResources.java
Log:
Cleaned up Javadoc
Modified: trunk/extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrResources.java
===================================================================
--- trunk/extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrResources.java 2009-06-09 11:17:52 UTC (rev 1008)
+++ trunk/extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrResources.java 2009-06-09 12:13:04 UTC (rev 1009)
@@ -97,16 +97,6 @@
* <td>/resources/{repositoryName}/{workspaceName}/node/{uuid}</td>
* <td>accesses the node with the given UUID</td>
* <td>ALL</td> </tr>
- * <tr>
- * <td>/resources/{repositoryName}/{workspaceName}/lock/{path}</td>
- * <td>locks the node at the path</td>
- * <td>GET</td>
- * </tr>
- * <tr>
- * <td>/resources/{repositoryName}/{workspaceName}/lock/{path}</td>
- * <td>unlocks the node at the path</td>
- * <td>PUT</td>
- * </tr>
* </table>
*/
@Immutable
16 years, 6 months
DNA SVN: r1008 - trunk/docs/reference/src/main/docbook/en-US/content/jcr.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2009-06-09 07:17:52 -0400 (Tue, 09 Jun 2009)
New Revision: 1008
Modified:
trunk/docs/reference/src/main/docbook/en-US/content/jcr/jcr.xml
Log:
Final draft of the JCR chapter
Modified: trunk/docs/reference/src/main/docbook/en-US/content/jcr/jcr.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/content/jcr/jcr.xml 2009-06-09 10:49:08 UTC (rev 1007)
+++ trunk/docs/reference/src/main/docbook/en-US/content/jcr/jcr.xml 2009-06-09 11:17:52 UTC (rev 1008)
@@ -37,14 +37,33 @@
Java Community Process under <ulink url="&JSR170;">JSR-170</ulink> (JCR 1.0) and is being revised under <ulink url="&JSR283;">JSR-283</ulink>.
JBoss DNA provides a partial JCR 1.0 implementation that allows you to work with the contents of a repository using the
JCR API. For information about how to use the JCR API, please see the <ulink url="&JSR170;">JSR-170</ulink> specification.
+ <note>
+ <para>In the interests of brevity, this chapter does not attempt to reproduce the JSR-170 specification in order to provide
+ an exhaustive definition of JBoss DNA JCR capabilities. Rather, this chapter will describe any deviations from the
+ specification as well as any DNA-specific public APIs and configuration.
+ </para>
+ </note>
</para>
- <sect1 id="jcr-repositories">
- <title>Obtaining JCR repositories</title>
- <para>Add reference to how to use JcrConfiguration to obtain a JcrEngine.
+ <para>Using JBoss DNA within your application is actually quite straightforward. As you'll see in this chapter,
+ the first step is setting up JBoss DNA and starting the <code>JcrEngine</code>. After that, you obtain the
+ <code>javax.jcr.Repository</code> instance for a named repository and just use the standard JCR API throughout your
+ application.
+ </para>
+ <sect1>
+ <title>Obtaining JCR Repositories</title>
+ <para>Once you've obtained a reference to a <code>JcrEngine</code> as described in
+ <link linkend="configuration">the previous chapter</link>, obtaining a repository is as easy as calling
+ the <code>getRepository(String)</code> method with the name of the repository that you just configured.
+<programlisting>
+&String; repositoryName = ...;
+&JcrEngine; jcrEngine = ...;
+&Repository; repository = jcrEngine.getRepository(repositoryName);
+</programlisting>
+ At this point, your application can proceed by working with the JCR API.
</para>
</sect1>
<sect1 id="jcr-sessions">
- <title>Creating JCR sessions</title>
+ <title>Creating JCR Sessions</title>
<para>Once you have obtained a reference to the JCR &Repository;, you can create a JCR session using one of its
<code>login(...)</code> methods. The <ulink url="&JSR170;">JSR-170</ulink> specification provides four login methods.
</para>
@@ -57,7 +76,8 @@
&Session; session = (&Session;) Subject.doAsPrivileged(subject, new PrivilegedExceptionAction<&Session;>() {
public Session run() throws Exception {
return repository.login();
- }}, AccessController.getContext());
+ }
+}, AccessController.getContext());
</programlisting>
This approach will yield a session with the same user name and roles as <code>subject</code>. There is a comparable
version of <code>login(...)</code> that allows the workspace to be specified by name.
@@ -104,7 +124,7 @@
&ServletSecurityContext; securityContext = new ServletSecurityContext(request);
&Session; session = repository.login(new &SecurityContextCredentials;(securityContext);
</programlisting>
- Once the &Session; is obtained, the repository content can be access and modified like any other JCR repository. No roles are required to connect
+ Once the &Session; is obtained, the repository content can be accessed and modified like any other JCR repository. No roles are required to connect
to any workspace at this time. Restrictions on workspace connections will likely be added to JBoss DNA in the near future. The roles from the JAAS
information or the &HttpServletRequest; are used to control read and write access to the repository. Please see the <ulink linkend="dna_jcr_security">JCR Security section</ulink>
for more details on how access is controlled.
@@ -168,7 +188,14 @@
</sect2>
<sect2>
<title>Built-In Node Types</title>
- <para>Add description of the DNA built-in node types.</para>
+ <para>JBoss DNA supports all of the built-in node types described in the JSR-170 specification. However, several of these node types
+ (mix:lockable, mix:versionable, nt:version, nt:versionLabels, nt:versionHistory, and nt:frozenNode) are semantically meaningless
+ as JBoss DNA does not yet support the locking or versioning optional features.
+ </para>
+ <para>Although JBoss DNA does define some custom node types in the <code>dna</code> namespace, none of these
+ node types are intended to be used by developers integrating with JBoss DNA and may be changed or removed
+ at any time.
+ </para>
</sect2>
<sect2>
<title>Custom Node Type Registration</title>
@@ -244,7 +271,7 @@
nodeTypeManager.registerNodeTypes(nodeTypeSource);
</programlisting>
<note>
- <para> JBoss DNA does not yet support a simple means on unregistering types at this time, so be careful before registering types outside of a
+ <para> JBoss DNA does not yet support a simple means of unregistering types at this time, so be careful before registering types outside of a
sandboxed environment.
</para>
</note>
@@ -257,7 +284,7 @@
<para>
In this chapter, we covered how to use JCR with JBoss DNA and learned about how it implements the JCR specification. Now that you know how JBoss DNA repositories work,
and how to use JCR to work with DNA repositories, we'll move on in
- the <link linkend="sequencing">next chapter</link> to describing in detail how the sequencing of file content works.
+ the <link linkend="deploying_dna_jcr">next chapter</link> to describing in detail how the sequencing of file content works.
</para>
</sect1>
</chapter>
16 years, 6 months
DNA SVN: r1007 - trunk/docs/reference/src/main/docbook/en-US/content/core.
by dna-commits@lists.jboss.org
Author: bcarothers
Date: 2009-06-09 06:49:08 -0400 (Tue, 09 Jun 2009)
New Revision: 1007
Modified:
trunk/docs/reference/src/main/docbook/en-US/content/core/execution_context.xml
Log:
Fixed a mis-named section
Modified: trunk/docs/reference/src/main/docbook/en-US/content/core/execution_context.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/content/core/execution_context.xml 2009-06-09 06:11:57 UTC (rev 1006)
+++ trunk/docs/reference/src/main/docbook/en-US/content/core/execution_context.xml 2009-06-09 10:49:08 UTC (rev 1007)
@@ -485,7 +485,7 @@
</note>
</sect1>
<sect1 id="mime-type-detectors">
- <title>Property factory and value factories</title>
+ <title>MIME Type Detectors</title>
<para>
JBoss DNA often needs the ability to determine the MIME type for some binary content. When uploading content into
a repository, we may want to add the MIME type as metadata. Or, we may want to make some processing decisions
16 years, 6 months