From dna-commits at lists.jboss.org Fri Sep 5 16:01:50 2008 Content-Type: multipart/mixed; boundary="===============8263287339175654506==" MIME-Version: 1.0 From: dna-commits at lists.jboss.org To: dna-commits at lists.jboss.org Subject: [dna-commits] DNA SVN: r505 - in trunk/docs/gettingstarted/src/main/docbook/en-US: content and 1 other directories. Date: Fri, 05 Sep 2008 16:01:50 -0400 Message-ID: --===============8263287339175654506== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Author: rhauch Date: 2008-09-05 16:01:49 -0400 (Fri, 05 Sep 2008) New Revision: 505 Added: trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_for_s= equencing.xml trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_repos= itories.xml trunk/docs/gettingstarted/src/main/docbook/en-US/images/example-sequence= r-client.png Removed: trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna.xml trunk/docs/gettingstarted/src/main/docbook/en-US/images/example-sequence= r-cli-client.png Modified: trunk/docs/gettingstarted/src/main/docbook/en-US/content/downloading_and= _running.xml trunk/docs/gettingstarted/src/main/docbook/en-US/master.xml Log: DNA-214 Update documentation to describe the repository, federation, JCR an= d other 0.2 features https://jira.jboss.org/jira/browse/DNA-214 Changed the Getting Started document to add the new repository example. Modified: trunk/docs/gettingstarted/src/main/docbook/en-US/content/download= ing_and_running.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- trunk/docs/gettingstarted/src/main/docbook/en-US/content/downloading_an= d_running.xml 2008-09-05 19:59:46 UTC (rev 504) +++ trunk/docs/gettingstarted/src/main/docbook/en-US/content/downloading_an= d_running.xml 2008-09-05 20:01:49 UTC (rev 505) @@ -24,7 +24,7 @@ --> - Running the example application + Running the example applications This chapter provides instructions for downloading and running a sampl= e application that demonstrates how JBoss DNA works with a JCR repository to automatically sequence changing content to ex= tract useful information. So read on to get the simple @@ -105,9 +105,17 @@ /resources /test/java /resources + repository/pom.xml + /src/main/assembly + /config + /java + /resources + /test/java + /resources ]]> - There are essentially two Maven projects: a sequencers project and a parent project. All of the source - for the example is located in the sequencers subdirecto= ry. And you may have noticed that none + There are essentially three Maven projects: a sequencers project, a repository project, = + and a parent project. All of the source for the sequencing example is= located in the sequencers subdirectory, + while all of the source for the federation example is located in the <= code>repository subdirectory. And you may have noticed that none of the JBoss DNA libraries are there. This is where Maven comes in.= The two pom.xml files tell Maven everything it needs to know about what libraries are required = and how to build the example. In a terminal, go to the examples directory and run <= emphasis role=3D"strong">mvn install. = @@ -136,10 +144,11 @@ If there are errors, check whether you have the correct version of= Maven installed and that you've correctly updated your Maven settings as described above. If you've successfully built the examples, there will be a new examples/sequencers/target/ directory that contains - all of the generated output, including a dna-example-sequencers-b= asic.dir/ subdirectory that contains the following: + all of the generated output for the sequencers example, including a dna-example-sequencers-basic.dir/ subdirectory = + that contains the following: - run.sh is the= *nix shell script that will run the example. + run.sh is the= *nix shell script that will run the sequencer example application. log4j.properties @@ -167,26 +176,42 @@ - lib - subdirectory contains the JARs for all of the JBoss DNA artifac= ts as well as those for other libraries required - by JBoss DNA and the example. + lib subdirect= ory contains the JARs for all of the JBoss DNA artifacts = + as well as those for other libraries required by JBoss DNA and the = sequencer example. - + - JBoss DNA 0.1 and the examples are currently tested with Apache Jackrabbit version 1.3.= 3. = - This version is stable and used by a number of other projects and a= pplications. However, you should be able to use a newer - version of Jackrabbit, as long as that version uses the same JCR AP= I. For example, version 1.4.2 was released on March 26, 2008 and - should be compatible. + JBoss DNA &versionNumber; and the sequencer example uses Apache Jackrabbit version 1.4.= 5. = + This version is stable and used by a number of other projects and a= pplications. However, you should be able to use any + version of Jackrabbit, as long as that version uses the same JCR AP= I. Just remember, if the version of Jackrabbit you want to use for t= hese examples is not in the Maven repository, you'll have to either add it or add it locally. For more informati= on, see the Maven documentation. + Similarly, the examples/repository/target/ directory = contains all of the generated output for the repository example, including + a dna-example-repository-basic.dir/ subdirectory that cont= ains the following: + + + run.sh is the= *nix shell script that will run the repository example application. + + + log4j.properties + is the Log4J configuration file. + + + + lib subdirect= ory contains the JARs for all of the JBoss DNA artifacts + as well as those for other libraries required by JBoss DNA and the = repository example. + + + + - - Running the example - This example consists of a client application that sets up an in-m= emory JCR repository and that allows a user to + + Running the sequencing example + The sequencing example consists of a client application that sets = up an in-memory JCR repository and that allows a user to upload files into that repository. The client also sets up the DNA s= ervices with two sequencers so that if any of the uploaded files are PNG, JPEG, GIF, BMP or other images, DNA will aut= omatically extract the image's metadata (e.g., image format, physical size, pixel density, etc.) and store that in the re= pository. Alternatively, if the uploaded file = @@ -196,8 +221,8 @@ To run the client application, go to the examples/sequencers/t= arget/dna-example-sequencers-basic.dir/ directory and type ./run.sh. You should see the command= -line client and its menus in your terminal:
- Example Client - + Example client +
From this menu, you can upload a file into the repository, search fo= r media in the repository, print sequencing statistics, or quit the application.
@@ -207,7 +232,7 @@ examples/sequencers/target/dna-example-sequencers-basic.dir/ directory, you can specify any of the files = in that directory without specifying the path:
- Uploading an image using the Example Client + Uploading an image using the example client
You can specify any fully-qualified or relative path. The applicatio= n will notify you if it cannot find the file you @@ -245,17 +270,17 @@ activities.
So, after the file is uploaded, you can search the repository for = the image metadata using the "s" menu option:
- Searching for media using the Example Client + Searching for media using the example client
Here are the search results after the sample1.mp3 audio = file has been uploaded (to the /a/b/sample1.mp3 location):
- Searching for media using the Example Client + Searching for media using the example client
You can also display the sequencing statistics using the "d" menu opt= ion:
- Sequencing statistics using the Example Client + Sequencing statistics using the example client
These stats show how many nodes were sequenced, and how many nodes we= re skipped because they didn't apply to the sequencer's @@ -268,14 +293,52 @@ You can repeat this process with other files. Any file that isn't = an image or MP3 files (as recognized by the sequencing configurations that we'll describe later) will not be sequenced.
+ + Running the repository example + The repository example consists of a client application that sets = up several DNA repositories, including one that = + is a federation of several of the others, and then allows you to naviga= te those repositories. + + To run the client application, go to the examples/repository/t= arget/dna-example-repository-basic.dir/ + directory and type ./run.sh. You should see the command= -line client and its menus in your terminal: +
+ Example Client + +
+ From this menu, you can see the list of repositories, select one, an= d navigate through that repository in a manner similar + to a *nix command-line shell (although the client itself uses the JC= R API to interact with the repositories). + Here are some of the commands you can use:
+ + Repository client commands to navigate a repository + + + + + CommandDescription + + + pwdPrint the path of the current node (e.= g., the "working directory") + ls [path]List the ch= ildren and properties of the node at the supplied path, + where "path" can be any relative path or a= bsolute path. If "path" is not supplied, + the current working node's path is used. + cd pathChange to the= specified node, where "path" + can be any relative path or absolute path. For example, "cd alpha" changes the current node to be a child named + "alpha"; "cd .." changes the current = node to the parent node; "cd /a/b" changes = + the current node to be the "/a/b" node. + exitExit this repository and return the l= ist of repositories. + + +
+ Try using the client to walk the different repositories. And whi= le this is a contrived application, it does demonstrate + the use of JBoss DNA to federate repositories and provide access throu= gh JCR. +
Summarizing what we just did - In this chapter you downloaded and installed the example applicati= on and used it to upload files into a - JCR repository. JBoss DNA automatically sequenced the image and/or M= P3 files you uploaded, extracted the metadata from the - files, and stored that metadata inside the repository. The applicati= on allowed you to see this metadata - and the sequencing statistics. - This application was very simplistic. In fact, running through th= e example probably only took you a minute or two. - So while this application won't win any awards, it does show the basi= cs of what JBoss DNA can do. + In this chapter you downloaded, installed, and built the example a= pplications. With the sequencer client, you could upload files into a + JCR repository, while JBoss DNA automatically sequenced the image, MP= 3, or Java source files you uploaded, extracted the metadata from the + files, and stored that metadata inside the repository. The repositor= y client allowed you to walk through multiple repositories, + including one whose content was federated from multiple other reposi= tories. + These example applications were very simplistic. In fact, running= through the examples probably only took you a few minutes. + So while these applications won't win any awards, they hopefully show= ed you the basics of what JBoss DNA can do. In the next chapter we'll ventu= re into the code to get an understanding of how JBoss DNA actually works and how you can use it in your own ap= plications. Deleted: trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna= .xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna.xml = 2008-09-05 19:59:46 UTC (rev 504) +++ trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna.xml = 2008-09-05 20:01:49 UTC (rev 505) @@ -1,485 +0,0 @@ - - - - - Using JBoss DNA - 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 au= tomatically uses its sequencers to extract - additional information from the uploaded files. - - Configuring JBoss DNA sequencers is a bit more manual than is idea= l. As you'll see, JBoss DNA uses dependency - injection to allow a great deal of flexibility in how it can be conf= igured and customized. However, the next release will - provide a much easier mechanism for configuring not only the sequenc= er service but also the upcoming federation engine and - JCR implementation. - - - Configuring the Sequencing Service - The JBoss DNA sequencing service is the compo= nent that manages the sequencers, = - reacting to changes in JCR repositories and then running the appropriat= e sequencers. - This involves processing the changes on a node, determining which (i= f any) sequencers should be run on that node, - and for each sequencer constructing the execution environment, calli= ng the sequencer, and saving the information - generated by the sequencer. - To set up the sequencing service, an instance is created, and depe= ndent components are injected into - the object. This includes among other things: - - - An execution context that defines the cont= ext in which the service runs, including - a factory for JCR sessions given names of the repository and wo= rkspace. 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. - - - An optional factory for class loaders 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). - - - An java.util.concurrent.ExecutorService used to ex= ecute the sequencing activites. If none - is supplied, a new single-threaded executor is created by calli= ng Executors.newSingleThreadExecutor(). - (This can easily be changed by subclassing and overriding the <= code>SequencerService.createDefaultExecutorService()
method.) - - - Filters for sequencers and events. By default, all sequencers = are considered for "node added", "property added" - and "property changed" events. - - - - As mentioned above, the ExecutionContext provides acc= ess to a SessionFactory that is used - by JBoss DNA to establish sessions to your JCR repositories. Two im= plementations are available: - - - The JndiSessionFactory looks up JCR Reposito= ry instances in JNDI using - names that are supplied when creating sessions. This impleme= ntation also has methods to set the - JCR Credentials for a given workspace name. - - - The SimpleSessionFactory has methods to register t= he JCR Repository instances - with names, as well as methods to set the JCR Credentia= ls for a given workspace name. - - - You can use the SimpleExecutionContext implementation o= f ExecutionContext and supply - a SessionFactory instance, or you can provide your own = implementation. - Here's an example of how to instantiate and configure the Sequenci= ngService: - - After the sequencing service is created and configured, it must be= started. The SequencingService - has an administration object (that is an instan= ce of ServiceAdministrator) - with start(), pause(), and shutdown(= ) 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 awaitTermination method - and pass it the maximum amount of time you want to wait. - - The sequencing service must also be configured with the sequencers= that it will use. This is done using the - addSequencer(SequencerConfig) method and passing a SequencerConfig instance that - you create. Here's an example: - /images/$1"}; -SequencerConfig imageSequencerConfig =3D new SequencerConfig(name, desc, c= lassname, = - classpath, path= Expressions); -sequencingService.addSequencer(imageSequencerConfig); - -name =3D "Mp3 Sequencer"; -desc =3D "Sequences mp3 files to extract the id3 tags of the audio file"; -classname =3D "org.jboss.dna.sequencer.mp3.Mp3MetadataSequencer"; -String[] mp3PathExpressions =3D {"//(*.mp3[*])/jcr:content[@jcr:data] =3D&= gt; /mp3s/$1"}; -SequencerConfig mp3SequencerConfig =3D new SequencerConfig(name, desc, cla= ssname, = - classpath, mp3Pat= hExpressions); -sequencingService.addSequencer(mp3SequencerConfig); - ]]> - This code fragment is pretty self-explanatory, except for the classpath and pathExpression parameters. - The classpath parameter defines the classpath that is passed to the = class loader factory mentioned above. - Our sequencer is on the classpath, so we can simply use null here. - The path expression is more complicated. Sequencer path expressio= ns are used by the sequencing service to - determine whether a particular changed node should be sequenced. Th= e expressions consist of two parts: a selection - criteria and an output expression: - outputPath ]]> - The inputPath part defines an expression for = the path that is to change and that should be sequenced. - Input paths consist of '/' separated segments, where each= segment represents a pattern for a single node's - name (including the same-name-sibling indexes) and '@' si= gnifies a property name. - Before getting into the details, let's look at some simple example= s: - - Simple Input Path Examples - - - - - - Input Path - Description - - - - /a/bMatch node "b" that is a = child of the top level node "a". Neither node - may have any same-name-sibilings. - /a/*Match any child node of the top level = node "a". - /a/*.txtMatch any child node of the top le= vel node "a" that also has a name ending in ".txt= ". - /a/*.txtMatch any child node of the top le= vel node "a" that also has a name ending in ".txt= ". - /a/b(a)cMatch the property "c= " of node "/a/b". - /a/b[2]The second child named "b" below the top level node "a". - /a/b[2,3,4]The second, third or fourth chi= ld named "b" below the top level node "a". - /a/b[*]Any (and every) child named "= b" below the top level node "a". - //a/bAny node named "b" that = exists below a node named "a", regardless = - of where node "a" occurs. Again, neither node may = have any same-name-sibilings. - - -
- With these simple examples, you can probably discern the most impo= rtant rules. First, the '*' 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., "*.txt"). - Second, square brackets (i.e., '[' and ']') 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. - Third, combining two delimiters (e.g., "//") matches = any sequence of nodes, regardless of what their names are = - or how many nodes. Often used with other patterns to identify nodes a= t any level matching other patterns. = - Three or more sequential slash characters are treated as two. - Many input paths can be created using just these simple rules. Ho= wever, input paths can be more complicated. Here are some - more examples: - - More Complex Input Path Examples - - - - - - Input Path - Description - - - - /a/(b|c|d)Match children of the top level= node "a" that are named "a", = - "b" or "c". None of the nodes may have = same-name-sibling indexes. - /a/b[c/d]Match node "b" chil= d of the top level node "a", when node - "b" has a child named "c", and "c" has a child named "d". - Node "b" is the selected node, while nodes "b<= /code>" and "b" are used as criteria but are not - selected. - /a(/(b|c|d|)/e)[f/g/@something]Match node= "/a/b/e", "/a/c/e", "/a/d/e", - or "/a/e" when they also have a child "f" that itself has a child "g" with property - "something". None of the nodes may have same-name-= sibling indexes. - - -
- These examples show a few more advanced rules. Parentheses (i.e.= , '(' and ')') 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 "/a/b", and "b" would be captured and c= ould be used within the output path using "$1", - where the number used in the output path identifies the parentheses.<= /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. - Let's go back to the previous code fragment and look at the firs= t path expression: - /images/$1 ]]> - This matches a node named "jcr:content" with proper= ty "jcr:data" but no siblings with the same name, - and that is a child of a node whose name ends with ".jpg", ".jpeg", ".gif", ".bmp", "= .pcx", = - or ".png" 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 seq= uenced content is placed. - Now that we've covered path expressions, let's get back to the SequencingService. = - After the service is started, it is ready to start reacting to change= s in the repository. But it first - must be wired to the repositories using a listener. This is accomp= lished using the ObservationService - described in the next section= . - - - Configuring the Observation Service - The JBoss DNA ObservationService is responsible for l= istening to one or more JCR repositories - and multiplexing the events to its listeners. Unlike JCR events, thi= s framework embeds in the events the - name of the repository and workspace that can be passed to a Se= ssionFactory to obtain a session - to the repository in which the change occurred. This simple design m= akes it very easy for JBoss DNA to - concurrently work with multiple JCR repositories. - Configuring an observation service is pretty easy, especially if y= ou reuse the same SessionFactory - supplied to the sequencing service. Here's an example: - - - Both ObservationService and SequencingService<= /code> implement - AdministeredService, which has a ServiceAdministr= ator used to start, pause, and shutdown the - service. In other words, the lifecycle of the services are managed = in the same way. - - After the observation service is started, listeners can be added. = The SequencingService implements the required - interface, and so it may be registered directly: - - Finally, the observation service must be wired to monitor one of y= our JCR repositories. This is done with - one of the monitor(...) methods: - - At this point, the observation service is listening to a JCR repos= itory and forwarding the appropriate events - to the sequencing service, which will asynchronously process the chan= ges and sequence the information added to or changed in the repository. - - - - Shutting down JBoss DNA services - The JBoss DNA services are utilizing resources and threads that mu= st be released before your application is ready to shut down. - The safe way to do this is to simply obtain the ServiceAdminist= rator for each service (via the getServiceAdministrator() method) - and call shutdown(). As previously mentioned, the shutd= own 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: - - At this point, we've covered how to configure and use the JBoss DN= A services in your application. - The next chapter goes back to the sample application to show how all = - these pieces fit together. - - - Reviewing the example application - Recall that the example application consists of a client applicati= on that sets up an in-memory JCR repository and - that allows a user to upload files into that repository. The client = also sets up the DNA services with an image sequencer so - that if any of the uploaded files are PNG, JPEG, GIF, BMP or other i= mages, DNA will automatically extract the image's - metadata (e.g., image format, physical size, pixel density, etc.) an= d store that in the repository. Or, if the client uploads - MP3 audio files, the title, author, album, year, and comment are ext= racted from the audio file and stored in the repository. - - The example is comprised of 3 classes and 1 interface, located in th= e src/main/java directory: - - SequencingClient is the class that contains the main = application. MediaInfo is a simple Java object = - that encapsulates metadata about a media file (as generated by the sequ= encer), and used by the client to - pass information to the UserInterface, which is an inte= rface with methods that will be called at runtime to = - request data from the user. ConsoleInput is an implementa= tion of this that creates a text user interface, = - allowing the user to operate the client from the command-line. We can = easily create a graphical implementation of - UserInterface at a later date. We can also create a moc= k implementation for testing purposes that simulates = - a user entering data. This allows us to check the behavior of the clien= t automatically using conventional JUnit test cases, = - as demonstrated by the code in the src/test/java directory= : - - If we look at the SequencingClient code, there are a = handful of methods that encapsulate the various activities. - - To keep the code shown in this book as readable as possible, some= of the comments and error handling have been removed. - - The startRepository() method starts up an in-memory J= ackrabbit JCR repository. The bulk of this method is simply = - gathering and passing the information required by Jackrabbit. Because J= ackrabbit's TransientRepository - implementation shuts down after the last session is closed, the appl= ication maintains a session to ensure that the - repository remains open throughout the application's lifetime. And f= inally, the node type needed by the image sequencer is - registered with Jackrabbit. - - As you can see, this method really has nothing to do with JBoss DN= A, other than setting up a JCR repository that JBoss - DNA will use. - The shutdownRepository() method shuts down the Jackra= bbit transient repository by closing the "keep-alive session". = - Again, this method really does nothing specifically with JBoss DNA, but= is needed to manage the JCR repository that JBoss DNA uses. - - The startDnaServices() method first starts the JCR re= pository (if it was not already started), and proceeds = - to create and configure the SequencingService as described= earlier. - This involes setting up the SessionFactory and Ex= ecutionContext, creating the - SequencingService instance, and configuring the image s= equencer. The method then continues by setting up the - ObservationService as described earlier and starting the service. - /images/$1"}; - SequencerConfig imageSequencerConfig =3D new SequencerConfig(name,= desc, classname, classpath, pathExpressions); - this.sequencingService.addSequencer(imageSequencerConfig); - - // Set up the MP3 sequencer ... - name =3D "Mp3 Sequencer"; - desc =3D "Sequences mp3 files to extract the id3 tags of the audio= file"; - classname =3D "org.jboss.dna.sequencer.mp3.Mp3MetadataSequencer"; - String[] mp3PathExpressions =3D {"//(*.mp3)[*]/jcr:content[@jcr:da= ta] =3D> /mp3s/$1"}; - SequencerConfig mp3SequencerConfig =3D new SequencerConfig(name, d= esc, classname, classpath, mp3PathExpressions); - this.sequencingService.addSequencer(mp3SequencerConfig); - - // Use the DNA observation service to listen to the JCR repository= (or multiple ones), and - // then register the sequencing service as a listener to this obse= rvation service... - this.observationService =3D new ObservationService(this.executionC= ontext.getSessionFactory()); - this.observationService.getAdministrator().start(); - this.observationService.addListener(this.sequencingService); - this.observationService.monitor(this.repositoryName + "/" + this.w= orkspaceName, Event.NODE_ADDED | Event.PROPERTY_ADDED | Event.PROPERTY_CHAN= GED); - } - // Start up the sequencing service ... - this.sequencingService.getAdministrator().start(); -} - ]]> - The shutdownDnaServices() method is pretty straightfo= rward: it just calls shutdown on each of the services - and waits until they terminate. - - None of the other methods really do anything with JBoss DNA per se. Instead, they merely work with the repository - using the JCR API. - The main method of the SequencingClient = class creates a SequencingClient instance, - and passes a new ConsoleInput instance: - - If we look at the ConsoleInput constructor, it starts= the repository, the DNA services, and a thread = - for the user interface. At this point, the constructor returns, but the= main application continues under the user interface thread. = - When the user requests to quit, the user interface thread also shuts do= wn the DNA services and JCR repository. - - At this point, we've reviewed all of the interesting code in the e= xample application. However, feel free - to play with the application, trying different things. - - - Summarizing what we just did - In this chapter we covered the different JBoss DNA components and = how they can be used in your application. - Specifically, we described how the SequencingService an= d ObservationService can = - be configured and used. And we ended the chapter by reviewing the e= xample application, which not only uses - JBoss DNA, but also the repository via the JCR API. - -
Copied: trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_= for_sequencing.xml (from rev 499, trunk/docs/gettingstarted/src/main/docboo= k/en-US/content/using_dna.xml) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_for_= sequencing.xml (rev 0) +++ trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_for_= sequencing.xml 2008-09-05 20:01:49 UTC (rev 505) @@ -0,0 +1,553 @@ + + + + + Using JBoss DNA for Sequencing + 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 au= tomatically uses its sequencers to extract + additional information from the uploaded files. + + Configuring JBoss DNA sequencers is a bit more manual than is idea= l. As you'll see, JBoss DNA uses dependency + injection to allow a great deal of flexibility in how it can be conf= igured and customized. However, the next release will + provide a much easier mechanism for configuring the services using D= NA repositories and configuration files. Current + plans are to use the JBoss = Microcontainer. + + + Configuring the Sequencing Service + The JBoss DNA sequencing service is the compo= nent that manages the sequencers, = + reacting to changes in JCR repositories and then running the appropriat= e sequencers. + This involves processing the changes on a node, determining which (i= f any) sequencers should be run on that node, + and for each sequencer constructing the execution environment, calli= ng the sequencer, and saving the information + generated by the sequencer. + To set up the sequencing service, an instance is created, and depe= ndent components are injected into + the object. This includes among other things: + + + An execution context that defines the cont= ext in which the service runs, including + a factory for JCR sessions given names of the repository and wo= rkspace. 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. + + + An optional factory for class loaders 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). + + + An java.util.concurrent.ExecutorService used to ex= ecute the sequencing activites. If none + is supplied, a new single-threaded executor is created by calli= ng Executors.newSingleThreadExecutor(). + (This can easily be changed by subclassing and overriding the <= code>SequencerService.createDefaultExecutorService() method.) + + + Filters for sequencers and events. By default, all sequencers = are considered for "node added", "property added" + and "property changed" events. + + + + As mentioned above, the ExecutionContext provides acc= ess to a SessionFactory that is used + by JBoss DNA to establish sessions to your JCR repositories. Two im= plementations are available: + + + The JndiSessionFactory looks up JCR Reposito= ry instances in JNDI using + names that are supplied when creating sessions. This impleme= ntation also has methods to set the + JCR Credentials for a given workspace name. + + + The SimpleSessionFactory has methods to register t= he JCR Repository instances + with names, as well as methods to set the JCR Credentia= ls for a given workspace name. + + + You can use the SimpleExecutionContext implementation o= f ExecutionContext and supply + a SessionFactory instance, or you can provide your own = implementation. + Here's an example of how to instantiate and configure the Sequenci= ngService: + + After the sequencing service is created and configured, it must be= started. The SequencingService + has an administration object (that is an instan= ce of ServiceAdministrator) + with start(), pause(), and shutdown(= ) 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 awaitTermination method + and pass it the maximum amount of time you want to wait. + + The sequencing service must also be configured with the sequencers= that it will use. This is done using the + addSequencer(SequencerConfig) method and passing a SequencerConfig instance that + you create. Here's the code that defines 3 sequencer configurations= : 1 that places image metadata into + "]]>", another that places M= P3 metadata into "]]>", + and a third that places a structure that represents the classes, met= hods, and attributes found within Java source into = + "]]>". + /images/$1"}; +SequencerConfig imageSequencerConfig =3D new SequencerConfig(name, desc, c= lassname, = + classpath, path= Expressions); +sequencingService.addSequencer(imageSequencerConfig); + +name =3D "Mp3 Sequencer"; +desc =3D "Sequences mp3 files to extract the id3 tags of the audio file"; +classname =3D "org.jboss.dna.sequencer.mp3.Mp3MetadataSequencer"; +pathExpressions =3D {"//(*.mp3[*])/jcr:content[@jcr:data] =3D> /mp3s/$1= "}; +SequencerConfig mp3SequencerConfig =3D new SequencerConfig(name, desc, cla= ssname, = + classpath, pathEx= pressions); +sequencingService.addSequencer(mp3SequencerConfig); + +name =3D "Java Sequencer"; +desc =3D "Sequences java files to extract the characteristics of the Java = source"; +classname =3D "org.jboss.dna.sequencer.java.JavaMetadataSequencer"; +pathExpressions =3D {"//(*.java[*])/jcr:content[@jcr:data] =3D> /java/$1"}; +SequencerConfig javaSequencerConfig =3D new SequencerConfig(name, desc, cl= assname, = + classpath, pathE= xpressions); +this.sequencingService.addSequencer(javaSequencerConfig); + ]]> + Each configuration defines several things, including the name, d= escription, and sequencer implementation class. + The configuration also defines the classpath information, which can b= e passed to the class loader factory to get + a Java classloader with which the sequencer class can be loaded. (If= no classpath information is provided, as is done + in the code above, the application class loader is used.) The config= uration also specifies the path expressions that + identify the nodes that should be sequenced with the sequencer and wh= ere to store the output generated by the sequencer. + Path expressions are pretty straightforward but are quite powerful, s= o before we go any further with the example, + let's dive into path expressions in more detail. + + Path Expressions + Path expressions consist of two parts: a selection criteria (or a= n input path) and an output path: + outputPath ]]> + The inputPath part defines an expression for= the path of a node that is to be sequenced. + Input paths consist of '/' separated segments, where eac= h segment represents a pattern for a single node's + name (including the same-name-sibling indexes) and '@' s= ignifies a property name. + Let's first look at some simple examples: + + Simple Input Path Examples + + + + + + Input Path + Description + + + + /a/bMatch node "b" that is a= child of the top level node "a". Neither node + may have any same-name-sibilings. + /a/*Match any child node of the top level= node "a". + /a/*.txtMatch any child node of the top l= evel node "a" that also has a name ending in ".txt". + /a/*.txtMatch any child node of the top l= evel node "a" that also has a name ending in ".txt". + /a/b(a)cMatch the property "c" of node "/a/b". + /a/b[2]The second child named "b" below the top level node "a". + /a/b[2,3,4]The second, third or fourth ch= ild named "b" below the top level node "a". + /a/b[*]Any (and every) child named "b" below the top level node "a". + //a/bAny node named "b" that= exists below a node named "a", regardless = + of where node "a" occurs. Again, neither node may= have any same-name-sibilings. + + +
+ With these simple examples, you can probably discern the most imp= ortant rules. First, the '*' 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., "*.txt<= /code>"). + Second, square brackets (i.e., '[' and ']') 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 sam= e-name-sibling. + Third, combining two delimiters (e.g., "//") 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. + Many input paths can be created using just these simple rules. H= owever, input paths can be more complicated. Here are some + more examples: + + More Complex Input Path Examples + + + + + + Input Path + Description + + + + /a/(b|c|d)Match children of the top level= node "a" that are named "a", = + "b" or "c". None of the nodes may have = same-name-sibling indexes. + /a/b[c/d]Match node "b" chil= d of the top level node "a", when node + "b" has a child named "c", and "c" has a child named "d". + Node "b" is the selected node, while nodes "b<= /code>" and "b" are used as criteria but are not + selected. + /a(/(b|c|d|)/e)[f/g/@something]Match node= "/a/b/e", "/a/c/e", "/a/d/e", + or "/a/e" when they also have a child "f" that itself has a child "g" with property + "something". None of the nodes may have same-name-= sibling indexes. + + +
+ These examples show a few more advanced rules. Parentheses (i.e.= , '(' and ')') 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 "/a/b", and "b" would be captured and c= ould be used within the output path using "$1", + where the number used in the output path identifies the parentheses.<= /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. + Let's go back to the previous code fragment and look at the firs= t path expression: + /images/$1 ]]> + This matches a node named "jcr:content" with proper= ty "jcr:data" but no siblings with the same name, + and that is a child of a node whose name ends with ".jpg", ".jpeg", ".gif", ".bmp", "= .pcx", = + or ".png" 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 seq= uenced content is placed. +
+ + Path Expressions Used in the Example + Now that we've covered path expressions, let's go back to the thr= ee sequencer configuration in the example. + Here they are again, with a description of what each path means: + + Path Expressions for the 3 Sequencers + + + + + + + Input Path + Output Path + Description + + + + + + + Any node with a name ending in ".jpg", ".= jpeg", ".gif", ".bmp", = + ".pcx", or ".png", whether or not it ha= s a same-name-sibling index, but that has a child named = + "jcr:content" with "jcr:data" property. = The node name representing the filename (including any + same-name-sibling index) is captured, and used to place the output= in "]]>". + + + + + Any node with a name ending in ".mp3", whether = or not it has a same-name-sibling index, but that has a child named = + "jcr:content" with "jcr:data" property. = The node name representing the filename (including any + same-name-sibling index) is captured, and used to place the output= in "]]>". + + + + + Any node with a name ending in ".java", whether= or not it has a same-name-sibling index, but that has a child named = + "jcr:content" with "jcr:data" property. = The node name representing the filename (including any + same-name-sibling index) is captured, and used to place the output= in "]]>". + + + +
+ After these sequencer configurations are defined and added to the= SequencingService, + the service is now ready to start reacting to changes in the repositor= y and automatically looking for nodes to sequence. = + But we first need to wire the service into the repository to receive t= hose change events. + This is accomplished using the ObservationService + described in the next section= . +
+ + + Configuring the Observation Service + The JBoss DNA ObservationService is responsible for l= istening to one or more JCR repositories + and multiplexing the events to its listeners. Unlike JCR events, thi= s framework embeds in the events the + name of the repository and workspace that can be passed to a Se= ssionFactory to obtain a session + to the repository in which the change occurred. This simple design m= akes it very easy for JBoss DNA to + concurrently work with multiple JCR repositories. + Configuring an observation service is pretty easy, especially if y= ou reuse the same SessionFactory + supplied to the sequencing service. Here's an example: + + + Both ObservationService and SequencingService<= /code> implement + AdministeredService, which has a ServiceAdministr= ator used to start, pause, and shutdown the + service. In other words, the lifecycle of the services are managed = in the same way. + + After the observation service is started, listeners can be added. = The SequencingService implements the required + interface, and so it may be registered directly: + + Finally, the observation service must be wired to monitor one of y= our JCR repositories. This is done with + one of the monitor(...) methods: + + At this point, the observation service is listening to a JCR repos= itory and forwarding the appropriate events + to the sequencing service, which will asynchronously process the chan= ges and sequence the information added to or changed in the repository. + + + + Shutting down JBoss DNA services + The JBoss DNA services are utilizing resources and threads that mu= st be released before your application is ready to shut down. + The safe way to do this is to simply obtain the ServiceAdminist= rator for each service (via the getServiceAdministrator() method) + and call shutdown(). As previously mentioned, the shutd= own 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: + + At this point, we've covered how to configure and use the JBoss DN= A services in your application. + The next chapter goes back to the sample application to show how all = + these pieces fit together. + + + Reviewing the example application + Recall that the example application consists of a client applicati= on that sets up an in-memory JCR repository and + that allows a user to upload files into that repository. The client = also sets up the DNA services with an image sequencer so + that if any of the uploaded files are PNG, JPEG, GIF, BMP or other i= mages, DNA will automatically extract the image's + metadata (e.g., image format, physical size, pixel density, etc.) an= d store that in the repository. Or, if the client uploads + MP3 audio files, the title, author, album, year, and comment are ext= racted from the audio file and stored in the repository. + + The example is comprised of 3 classes and 1 interface, located in th= e src/main/java directory: + + SequencingClient is the class that contains the main = application. MediaInfo is a simple Java object = + that encapsulates metadata about a media file (as generated by the sequ= encer), and used by the client to + pass information to the UserInterface, which is an inte= rface with methods that will be called at runtime to = + request data from the user. ConsoleInput is an implementa= tion of this that creates a text user interface, = + allowing the user to operate the client from the command-line. We can = easily create a graphical implementation of + UserInterface at a later date. We can also create a moc= k implementation for testing purposes that simulates = + a user entering data. This allows us to check the behavior of the clien= t automatically using conventional JUnit test cases, = + as demonstrated by the code in the src/test/java directory= : + + If we look at the SequencingClient code, there are a = handful of methods that encapsulate the various activities. + + To keep the code shown in this book as readable as possible, some= of the comments and error handling have been removed. + + The startRepository() method starts up an in-memory J= ackrabbit JCR repository. The bulk of this method is simply = + gathering and passing the information required by Jackrabbit. Because J= ackrabbit's TransientRepository + implementation shuts down after the last session is closed, the appl= ication maintains a session to ensure that the + repository remains open throughout the application's lifetime. And f= inally, the node type needed by the image sequencer is + registered with Jackrabbit. + + As you can see, this method really has nothing to do with JBoss DN= A, other than setting up a JCR repository that JBoss + DNA will use. + The shutdownRepository() method shuts down the Jackra= bbit transient repository by closing the "keep-alive session". = + Again, this method really does nothing specifically with JBoss DNA, but= is needed to manage the JCR repository that JBoss DNA uses. + + The startDnaServices() method first starts the JCR re= pository (if it was not already started), and proceeds = + to create and configure the SequencingService as described= earlier. + This involes setting up the SessionFactory and Ex= ecutionContext, creating the + SequencingService instance, and configuring the image s= equencer. The method then continues by setting up the + ObservationService as described earlier and starting the service. + /images/$1"}; + SequencerConfig imageSequencerConfig =3D new SequencerConfig(name,= desc, classname, classpath, pathExpressions); + this.sequencingService.addSequencer(imageSequencerConfig); + + // Set up the MP3 sequencer ... + name =3D "Mp3 Sequencer"; + desc =3D "Sequences mp3 files to extract the id3 tags of the audio= file"; + classname =3D "org.jboss.dna.sequencer.mp3.Mp3MetadataSequencer"; + pathExpressions =3D {"//(*.mp3)[*]/jcr:content[@jcr:data] =3D> = /mp3s/$1"}; + SequencerConfig mp3SequencerConfig =3D new SequencerConfig(name, d= esc, classname, classpath, pathExpressions); + this.sequencingService.addSequencer(mp3SequencerConfig); + + name =3D "Java Sequencer"; + desc =3D "Sequences java files to extract the characteristics of the J= ava source"; + classname =3D "org.jboss.dna.sequencer.java.JavaMetadataSequencer"; + pathExpressions =3D {"//(*.java[*])/jcr:content[@jcr:data] =3D> /java/= $1"}; + SequencerConfig javaSequencerConfig =3D new SequencerConfig(name, desc= , classname,classpath, pathExpressions); + this.sequencingService.addSequencer(javaSequencerConfig); + + // Use the DNA observation service to listen to the JCR repository= (or multiple ones), and + // then register the sequencing service as a listener to this obse= rvation service... + this.observationService =3D new ObservationService(this.executionC= ontext.getSessionFactory()); + this.observationService.getAdministrator().start(); + this.observationService.addListener(this.sequencingService); + this.observationService.monitor(this.repositoryName + "/" + this.w= orkspaceName, Event.NODE_ADDED | Event.PROPERTY_ADDED | Event.PROPERTY_CHAN= GED); + } + // Start up the sequencing service ... + this.sequencingService.getAdministrator().start(); +} + ]]> + The shutdownDnaServices() method is pretty straightfo= rward: it just calls shutdown on each of the services + and waits until they terminate. + + None of the other methods really do anything with JBoss DNA per se. Instead, they merely work with the repository + using the JCR API. + The main method of the SequencingClient = class creates a SequencingClient instance, + and passes a new ConsoleInput instance: + + If we look at the ConsoleInput constructor, it starts= the repository, the DNA services, and a thread = + for the user interface. At this point, the constructor returns, but the= main application continues under the user interface thread. = + When the user requests to quit, the user interface thread also shuts do= wn the DNA services and JCR repository. + + At this point, we've reviewed all of the interesting code in the e= xample application. However, feel free + to play with the application, trying different things. + + + Summarizing what we just did + In this chapter we covered the different JBoss DNA components and = how they can be used in your application. + Specifically, we described how the SequencingService an= d ObservationService can = + be configured and used. And we ended the chapter by reviewing the e= xample application, which not only uses + JBoss DNA, but also the repository via the JCR API. + + Added: trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_r= epositories.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_repo= sitories.xml (rev 0) +++ trunk/docs/gettingstarted/src/main/docbook/en-US/content/using_dna_repo= sitories.xml 2008-09-05 20:01:49 UTC (rev 505) @@ -0,0 +1,32 @@ + + + + + Using JBoss DNA Repositories + As we've mentioned before, one of the capabilities of JBoss DNA is = to provide access through JCR to different kinds = + of repositories. You're applications work with the JCR API, but JBoss D= NA accesses the content from the underlying systems, + including able to work with existing JCR repositories. + + = Deleted: trunk/docs/gettingstarted/src/main/docbook/en-US/images/example-se= quencer-cli-client.png =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D (Binary files differ) Copied: trunk/docs/gettingstarted/src/main/docbook/en-US/images/example-seq= uencer-client.png (from rev 497, trunk/docs/gettingstarted/src/main/docbook= /en-US/images/example-sequencer-cli-client.png) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D (Binary files differ) Modified: trunk/docs/gettingstarted/src/main/docbook/en-US/master.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- trunk/docs/gettingstarted/src/main/docbook/en-US/master.xml 2008-09-05 = 19:59:46 UTC (rev 504) +++ trunk/docs/gettingstarted/src/main/docbook/en-US/master.xml 2008-09-05 = 20:01:49 UTC (rev 505) @@ -53,7 +53,8 @@ - + + --===============8263287339175654506==--