You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2012/01/10 19:51:06 UTC

svn commit: r1229679 [4/12] - /jackrabbit/site/trunk/content/

Added: jackrabbit/site/trunk/content/first-hops.cwiki
URL: http://svn.apache.org/viewvc/jackrabbit/site/trunk/content/first-hops.cwiki?rev=1229679&view=auto
==============================================================================
--- jackrabbit/site/trunk/content/first-hops.cwiki (added)
+++ jackrabbit/site/trunk/content/first-hops.cwiki Tue Jan 10 18:50:59 2012
@@ -0,0 +1,527 @@
+Welcome to your first hops into the world of Jackrabbit! This introduction gives you a hands-on experience with Jackrabbit and the JCR API. Once you have finished hopping through this document, you should be all set to continue on your own with the official JCR specification and the documentation on this site. 
+
+h2. Hop 0: Getting started 
+
+The easiest way to get started with Jackrabbit is to [download|Downloads] the runnable [Standalone Server] jar. In addition to running it, you can also put it in your classpath to quickly access all the classes and interfaces you need below. Alternatively, if you use the [Apache Maven|http://maven.apache.org/] build system (which we recommend), you can set up your first hops project with the following dependenecies. 
+
+{code:xml} 
+<dependencies> 
+<!-- The JCR API --> 
+<dependency> 
+<groupId>javax.jcr</groupId> 
+<artifactId>jcr</artifactId> 
+<version>2.0</version> 
+</dependency> 
+
+<!-- Jackrabbit content repository --> 
+<dependency> 
+<groupId>org.apache.jackrabbit</groupId> 
+<artifactId>jackrabbit-core</artifactId> 
+<version>2.2.4</version> 
+</dependency> 
+
+<!-- Use Log4J for logging --> 
+<dependency> 
+<groupId>org.slf4j</groupId> 
+<artifactId>slf4j-log4j12</artifactId> 
+<version>1.5.11</version> 
+</dependency> 
+</dependencies> 
+{code} 
+
+{note} 
+You probably have an error in your classpath settings if you get a {{ClassNotFoundException}} message when trying to compile or run the examples below. 
+{note} 
+
+h2. Hop 1: Logging in to Jackrabbit 
+
+So let's get started. As a warm-up we'll create a Jackrabbit content repository and start a login session for accessing it. The full example application that does this is shown below, with line-by-line explanations following shortly after. 
+
+{code:title=FirstHop.java} 
+import javax.jcr.Repository; 
+import javax.jcr.Session; 
+import org.apache.jackrabbit.core.TransientRepository; 
+
+/** 
+* First hop example. Logs in to a content repository and prints a 
+* status message. 
+*/ 
+public class FirstHop { 
+
+/** 
+* The main entry point of the example application. 
+* 
+* @param args command line arguments (ignored) 
+* @throws Exception if an error occurs 
+*/ 
+public static void main(String[] args) throws Exception { 
+Repository repository = new TransientRepository(); 
+Session session = repository.login(); 
+try { 
+String user = session.getUserID(); 
+String name = repository.getDescriptor(Repository.REP_NAME_DESC); 
+System.out.println( 
+"Logged in as " + user + " to a " + name + " repository."); 
+} finally { 
+session.logout(); 
+} 
+} 
+
+} 
+{code} 
+
+You can also download the source file as FirstHop.java. If you have your classpath set up, you can compile the application with javac FirstHop.java and run it with java FirstHop to get the following output. 
+
+{code} 
+Logged in as anonymous to a Jackrabbit repository. 
+{code} 
+
+In addition to producing the above status line the application copies a default repository configuration file to repository.xml and creates an initial Jackrabbit content repository in the repository subdirectory. You can use the system properties {{org.apache.jackrabbit.repository.conf}} and {{org.apache.jackrabbit.repository.home}} to set alternative configuration file and repository directory locations. 
+
+Read on for a detailed breakdown of the FirstHop application: 
+
+{code} 
+import javax.jcr.Repository; 
+import javax.jcr.Session; 
+{code} 
+
+The JCR API interfaces are located in the javax.jcr package found in the jcr-1.0.jar library. The promise of the JCR API is that if you only use these interfaces in your content application, it should remain mostly independent of the underlying content repository implementation. 
+
+The [Repository|http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Repository.html?is-external=true] interface represents a given content repository instance and the [Session|http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Session.html?is-external=true] interface represents a single login session for accessing the repository. A session is needed to access any content within a repository. 
+
+Note that a Session instance is not guaranteed to be thread-safe so you should start multiple sessions if you need to access repository content simultaneously from different threads. This is especially important for things like web applications. 
+
+{code} 
+import org.apache.jackrabbit.core.TransientRepository; 
+{code} 
+
+The best practice for deploying Jackrabbit is to use JNDI or some other configuration mechanism in a container environment to keep the application code free of direct Jackrabbit dependencies, but since we are creating a simple standalone application we can take a shortcut by using the [TransientRepository|http://jackrabbit.apache.org/api/2.2/org/apache/jackrabbit/core/TransientRepository.html] class from Jackrabbit core. 
+
+{code} 
+public class FirstHop 
+public static void main(String[] args) throws Exception 
+{code} 
+
+The FirstHop example is a simple standalone application that fits nicely in the main() method and lets the JVM take care of the possible exceptions. More substantial content applications could also be written as web application or EJB components with different setup and error handling patterns. 
+
+{code} 
+Repository repository = new TransientRepository(); 
+{code} 
+
+The TransientRepository class implements the JCR Repository interface, so you can simply assign a TransientRepository instance to a Repository variable. The default constructor contains a utility feature that will take care of the initial configuration and repository construction when the first session is started. Thus there is no need for manual configuration for now unless you want direct control over the repository setup. 
+
+The TransientRepository implementation will automatically initialize the content repository when the first session is started and shut it down when the last session is closed. Thus there is no need for explicit repository shutdown as long as all sessions are properly closed. Note that a Jackrabbit repository directory contains a lock file that prevents it from being accessed simultaneously by multiple processes. You will see repository startup exceptions caused by the lock file if you fail to properly close all sessions or otherwise shut down the repository before leaving the process that accesses a repository. Normally you can just manually remove the lock file in such cases but such cases always present a chance of repository corruption especially if you use a non-transactional persistence manager. 
+
+{code} 
+Session session = repository.login(); 
+{code} 
+
+The default Repository.login() method starts a repository session using the default workspace and no user credentials. Jackrabbit tries to use the Java Authentication and Authorization Service (JAAS) configuration in such cases, but defaults to the anonymous user if a JAAS Subject is not found. 
+
+Since we use the TransientRepository class as the Repository implementation, this step will also cause the repository to be initialized. 
+
+{code} 
+try { ... } finally { session.logout(); } 
+{code} 
+
+It is a good practice to properly release all acquired resources, and the JCR sessions are no exception. The try-finally idiom is a good way to ensure that a resource really gets released, as the release method gets called even if the intervening code throws an exception or otherwise jumps outside the scope (for example using a return, break, or continue statement). 
+
+The Session.logout() method in the finally branch closes the session and since this is the only session we have started, the TransientRepository is automatically shut down. 
+
+{code} 
+String user = session.getUserID(); 
+{code} 
+
+The username or identifier of the user associated with a session is available using the Session.getUserID() method. Jackrabbit returns "anonymous" by default. 
+
+{code} 
+String name = repository.getDescriptor(Repository.REP_NAME_DESC); 
+{code} 
+
+Each content repository implementation publishes a number of string descriptors that describe the various implementation properties, like the implementation level and the supported optional JCR features. See the [Repository|http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Repository.html?is-external=true] interface for a list of the standard repository descriptors. The REP_NAME_DESC descriptor contains the name of the repository implementation, in this case "Jackrabbit". 
+
+h2. Hop 2: Working with content 
+
+The main function of a content repository is allow applications to store and retrieve content. The content in a JCR content repository consists of structured or unstructured data modeled as a hierarchy of nodes with properties that contain the actual data. 
+
+The following example application first stores some content to the initially empty content repository, then retrieves the stored content and outputs it, and finally removes the stored content. 
+
+{code:title=SecondHop.java} 
+import javax.jcr.Repository; 
+import javax.jcr.Session; 
+import javax.jcr.SimpleCredentials; 
+import javax.jcr.Node; 
+import org.apache.jackrabbit.core.TransientRepository; 
+
+/** 
+* Second hop example. Stores, retrieves, and removes example content. 
+*/ 
+public class SecondHop { 
+
+/** 
+* The main entry point of the example application. 
+* 
+* @param args command line arguments (ignored) 
+* @throws Exception if an error occurs 
+*/ 
+public static void main(String[] args) throws Exception { 
+Repository repository = new TransientRepository(); 
+Session session = repository.login( 
+new SimpleCredentials("username", "password".toCharArray())); 
+try { 
+Node root = session.getRootNode(); 
+
+// Store content 
+Node hello = root.addNode("hello"); 
+Node world = hello.addNode("world"); 
+world.setProperty("message", "Hello, World!"); 
+session.save(); 
+
+// Retrieve content 
+Node node = root.getNode("hello/world"); 
+System.out.println(node.getPath()); 
+System.out.println(node.getProperty("message").getString()); 
+
+// Remove content 
+root.getNode("hello").remove(); 
+session.save(); 
+} finally { 
+session.logout(); 
+} 
+} 
+
+} 
+{code} 
+
+Like in the first hop, this example source is also available as SecondHop.java. You can also compile and run this class just like you did in the first hop example. Running this example should produce the following output: 
+
+{code} 
+/hello/world 
+Hello, World! 
+{code} 
+
+The basic structure of this example application is the same as in the First Hop example, so let's just walk through the differences: 
+
+{code} 
+import javax.jcr.SimpleCredentials; 
+import javax.jcr.Node; 
+{code} 
+
+These are two new classes we need for this example. The [SimpleCredentials|http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/SimpleCredentials.html?is-external=true] class is a simple implementation of the [Credentials|http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Credentials.html?is-external=true] interface used for passing explicit user credentials to the Repository.login(Credentials) method. 
+
+The [Node|http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Node.html?is-external=true] interface is used to manage the content nodes in a repository. There is a related interface called [Property|http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Property.html?is-external=true] for managing content properties, but in this example we use the Property interface only indirectly. 
+
+{code} 
+new SimpleCredentials("username", "password".toCharArray()) 
+{code} 
+
+As discussed in the First Hop example, the default Repository.login() method returns an anonymous read-only session in the Jackrabbit default configuration. To be able to store and remove content we need to create a session with write access, and to do that we need to pass some credentials to the 
+
+{code} 
+Repository.login(Credentials credentials) method. 
+{code} 
+
+The default Jackrabbit login mechanism accepts any username and password as valid credentials and returns a session with full write access. Thus we only need to construct and use a SimpleCredentials instance with some dummy username and password, in this case "username" and "password". 
+
+The SimpleCredentials constructor follows the JAAS convention of representing the username as a normal String, but the password as a character array, so we need to use the String.toCharArray() method to satisfy the constructor. 
+
+{code} 
+Node root = session.getRootNode(); 
+{code} 
+
+Each JCR session is associated with a workspace that contains a single node tree. A simple way to access the root node is to call the Session.getRootNode() method. Having a reference to the root node allows us to easily store and retrieve content in the current workspace. 
+
+{code} 
+Node hello = root.addNode("hello"); 
+Node world = hello.addNode("world"); 
+{code} 
+
+New content nodes can be added using the Node.addNode(String relPath) method. The method takes the name (or relative path) of the node to be added and creates the named node in the transient storage associated with the current session. Until the transient storage is persisted, the added node is only visible within the current session and not within any other session that is concurrently accessing the content repository. 
+
+This code snippet creates two new nodes, called "hello" and "world", with "hello" being a child of the root node and "world" a child of the "hello" node. 
+
+{code} 
+world.setProperty("message", "Hello, World!"); 
+{code} 
+
+To add some content to the structure created using the "hello" and "world" nodes, we use the Node.setProperty(String name, String value) method to add a string property called "message" to the "world" node. The value of the property is the string "Hello, World!". 
+
+Like the added nodes, also the property is first created in the transient storage associated with the current session. If the named property already exists, then this method will change the value of that property. 
+
+{code} 
+session.save(); 
+{code} 
+
+Even though the rest of our example would work just fine using only the transient storage of the single session, we'd like to persist the changes we've made so far. This way other sessions could also access the example content we just created. If you like, you could even split the example application into three pieces for respectively storing, retrieving, and removing the example content. Such a split would not work unless we persisted the changes we make. 
+
+The Session.save() method persists all pending changes in the transient storage. The changes are written to the persistent repository storage and they become visible to all sessions accessing the same workspace. Without this call all changes will be lost forever when the session is closed. 
+
+{code} 
+Node node = root.getNode("hello/world"); 
+{code} 
+
+Since we are still using the same session, we could use the existing hello and world node references to access the stored content, but let's pretend that we've started another session and want to retrieve the content that was previously stored. 
+
+The Node.getNode(String relPath) method returns a reference to the node at the given path relative to this node. The path syntax follows common file system conventions: a forward slash separates node names, a single dot represents the current node, and a double dot the parent node. Thus the path "hello/world" identifies the "world" child node of the "hello" child node of the current node - in this case the root node. The end result is that the method returns a node instance that represents the same content node as the world instance created a few lines earlier. 
+
+{code} 
+System.out.println(node.getPath()); 
+{code} 
+
+Each content node and property is uniquely identified by its absolute path within the workspace. The absolute path starts with a forward slash and contains all the names of the ancestor nodes in order before the name of the current node or property. 
+
+The path of a node or property can be retrieved using the Item.getPath() method. The [Item|http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Item.html?is-external=true] inteface is a superinterface of Node and Property, and contains all the functionality shared by nodes and properties. 
+
+The node variable references the "world" node, so this statement will output the line "/hello/world". 
+
+{code} 
+System.out.println(node.getProperty("message").getString()); 
+{code} 
+
+Properties can be accessed using the Node.getProperty(String relPath) method that returns an instance of the [Property|http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Property.html?is-external=true] interface that represents the property at the given path relative to the current node. In this case the "message" property is the one we created a few lines earlier. 
+
+A JCR property can contain either a single or multiple values of a given type. There are property types for storing strings, numbers, dates, binary streams, node references, etc. We just want the single string value, so we use the Property.getString() method. The result of this statement is the line "Hello, World!" being outputted. 
+
+{code} 
+root.getNode("hello").remove(); 
+{code} 
+
+Nodes and properties can be removed using the Item.remove() method. The method removes the entire content subtree, so we only need to remove the topmost "hello" node to get rid of all the content we added before. 
+
+Removals are first stored in the session-local transient storage, just like added and changed content. Like before, the transient changes need to be explicitly saved for the content to be removed from the persistent storage. 
+
+h2. Hop 3: Importing content 
+
+TODO: Update to match the style of previous hops. 
+
+To add content a bit more efficiently, you may want to try JCR's import facilities, such as Session.importXML. The following XML document by Elliotte Rusty Harold provides an interesting example that demonstrates a repository's namespace capabilities: 
+
+{code:title=test.xml} 
+<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml" 
+xmlns:mathml="http://www.w3.org/1998/Math/MathML"> 
+<xhtml:head><xhtml:title>Three Namespaces</xhtml:title></xhtml:head> 
+<xhtml:body> 
+<xhtml:h1 align="center">An Ellipse and a Rectangle</xhtml:h1> 
+<svg:svg xmlns:svg="http://www.w3.org/2000/svg" 
+width="12cm" height="10cm"> 
+<svg:ellipse rx="110" ry="130" /> 
+<svg:rect x="4cm" y="1cm" width="3cm" height="6cm" /> 
+</svg:svg> 
+<xhtml:p>The equation for ellipses</xhtml:p> 
+<mathml:math> 
+<mathml:apply> 
+<mathml:eq/> 
+<mathml:cn> 1 </mathml:cn> 
+<mathml:apply> 
+<mathml:plus/> 
+<mathml:apply> 
+<mathml:divide/> 
+<mathml:apply> 
+<mathml:power/> 
+<mathml:ci> x </mathml:ci> 
+<mathml:cn> 2 </mathml:cn> 
+</mathml:apply> 
+<mathml:apply> 
+<mathml:power/> 
+<mathml:ci> a </mathml:ci> 
+<mathml:cn> 2 </mathml:cn> 
+</mathml:apply> 
+</mathml:apply> 
+<mathml:apply> 
+<mathml:divide/> 
+<mathml:apply> 
+<mathml:power/> 
+<mathml:ci> y </mathml:ci> 
+<mathml:cn> 2 </mathml:cn> 
+</mathml:apply> 
+<mathml:apply> 
+<mathml:power/> 
+<mathml:ci> b </mathml:ci> 
+<mathml:cn> 2 </mathml:cn> 
+</mathml:apply> 
+</mathml:apply> 
+</mathml:apply> 
+</mathml:apply> 
+</mathml:math> 
+<xhtml:hr/> 
+<xhtml:p>Last Modified January 10, 2002</xhtml:p> 
+</xhtml:body> 
+</xhtml:html> 
+{code} 
+
+The third example application shown below will import the XML file called test.xml from the current directory into a new content repository node called importxml. Once the XML content is imported, the application recursively dumps the contents of the entire workspace using the simple dump() method. 
+
+{code:title=ThirdHop.java} 
+import javax.jcr.*; 
+import org.apache.jackrabbit.core.TransientRepository; 
+import java.io.FileInputStream; 
+
+/** 
+* Third Jackrabbit example application. Imports an example XML file 
+* and outputs the contents of the entire workspace. 
+*/ 
+public class ThirdHop { 
+
+/**
+* The main entry point of the example application.
+*
+* @param args command line arguments (ignored)
+* @throws Exception if an error occurs
+*/
+public static void main(String[] args) throws Exception { 
+Repository repository = new TransientRepository(); 
+Session session = repository.login( 
+new SimpleCredentials("username", "password".toCharArray())); 
+try { 
+Node root = session.getRootNode(); 
+
+// Import the XML file unless already imported 
+if (!root.hasNode("importxml")) { 
+System.out.print("Importing xml... "); 
+
+// Create an unstructured node under which to import the XML 
+Node node = root.addNode("importxml", "nt:unstructured"); 
+
+// Import the file "test.xml" under the created node 
+FileInputStream xml = new FileInputStream("test.xml");
+session.importXML( 
+node.getPath(), xml, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW); 
+xml.close();
+session.save(); 
+System.out.println("done."); 
+} 
+
+//output the repository content
+dump(root); 
+} finally { 
+session.logout(); 
+} 
+} 
+
+/** Recursively outputs the contents of the given node. */ 
+private static void dump(Node node) throws RepositoryException { 
+// First output the node path 
+System.out.println(node.getPath()); 
+// Skip the virtual (and large!) jcr:system subtree 
+if (node.getName().equals("jcr:system")) { 
+return; 
+} 
+
+// Then output the properties 
+PropertyIterator properties = node.getProperties(); 
+while (properties.hasNext()) { 
+Property property = properties.nextProperty(); 
+if (property.getDefinition().isMultiple()) { 
+// A multi-valued property, print all values 
+Value[] values = property.getValues(); 
+for (int i = 0; i < values.length; i++) { 
+System.out.println( 
+property.getPath() + " = " + values[i].getString()); 
+} 
+} else { 
+// A single-valued property 
+System.out.println( 
+property.getPath() + " = " + property.getString()); 
+} 
+} 
+
+// Finally output all the child nodes recursively 
+NodeIterator nodes = node.getNodes(); 
+while (nodes.hasNext()) { 
+dump(nodes.nextNode()); 
+} 
+} 
+
+} 
+{code} 
+
+Running the ThirdHop class should produce output like the following: 
+
+{code} 
+Importing XML... done. 
+/ 
+/jcr:primaryType=rep:root 
+/jcr:system 
+/importxml 
+/importxml/jcr:primaryType=nt:unstructured 
+/importxml/xhtml:html 
+/importxml/xhtml:html/jcr:primaryType=nt:unstructured 
+/importxml/xhtml:html/xhtml:head 
+/importxml/xhtml:html/xhtml:head/jcr:primaryType=nt:unstructured 
+/importxml/xhtml:html/xhtml:head/xhtml:title 
+/importxml/xhtml:html/xhtml:head/xhtml:title/jcr:primaryType=nt:unstructured 
+/importxml/xhtml:html/xhtml:head/xhtml:title/jcr:xmltext 
+/importxml/xhtml:html/xhtml:head/xhtml:title/jcr:xmltext/jcr:primaryType=nt:unstructured 
+/importxml/xhtml:html/xhtml:head/xhtml:title/jcr:xmltext/jcr:xmlcharacters=Three Namespaces 
+/importxml/xhtml:html/xhtml:body 
+/importxml/xhtml:html/xhtml:body/jcr:primaryType=nt:unstructured 
+/importxml/xhtml:html/xhtml:body/xhtml:h1 
+/importxml/xhtml:html/xhtml:body/xhtml:h1/jcr:primaryType=nt:unstructured 
+/importxml/xhtml:html/xhtml:body/xhtml:h1/align=center 
+/importxml/xhtml:html/xhtml:body/xhtml:h1/jcr:xmltext 
+/importxml/xhtml:html/xhtml:body/xhtml:h1/jcr:xmltext/jcr:primaryType=nt:unstructured 
+/importxml/xhtml:html/xhtml:body/xhtml:h1/jcr:xmltext/jcr:xmlcharacters=An Ellipse and a Rectangle 
+/importxml/xhtml:html/xhtml:body/svg:svg 
+/importxml/xhtml:html/xhtml:body/svg:svg/jcr:primaryType=nt:unstructured 
+/importxml/xhtml:html/xhtml:body/svg:svg/width=12cm 
+/importxml/xhtml:html/xhtml:body/svg:svg/height=10cm 
+. 
+. 
+. 
+{code} 
+
+This hop has a lot of similarities with the Second Hop example: we create a new session with write access by loggin in, next we insert data into the repository, this time by importing an xml file and finally we output the entire repository content.
+
+By now you should be familiar with loggin into a repository (Repository.login), creating a new node (Node.addNode) under the repository root (Session.getRootNode) and saving the session so that our changes are persisted (Session.save).
+
+Let us look at the new methods used in this example, how to import xml content:
+
+{code} 
+session.importXML(node.getPath(), xml, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+{code} 
+
+This deserializes an XML document and adds the resulting item subgraph as a child of the node at the provided path.
+
+The flag [ImportUUIDBehavior|http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/ImportUUIDBehavior.html?is-external=true] governs how the identifiers of incoming nodes are handled. There are four options: 
+* ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW: Incoming nodes are added in the same way that new node is added with Node.addNode. That is, they are either assigned newly created identifiers upon addition or upon save. In either case, identifier collisions will not occur. 
+
+* ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING: If an incoming node has the same identifier as a node already existing in the workspace then the already existing node (and its subgraph) is removed from wherever it may be in the workspace before the incoming node is added. Note that this can result in nodes "disappearing" from locations in the workspace that are remote from the location to which the incoming subgraph is being written. Both the removal and the new addition will be dispatched on save.
+
+* ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING: If an incoming node has the same identifier as a node already existing in the workspace, then the already-existing node is replaced by the incoming node in the same position as the existing node. Note that this may result in the incoming subgraph being disaggregated and "spread around" to different locations in the workspace. In the most extreme case this behavior may result in no node at all being added as child of parentAbsPath. This will occur if the topmost element of the incoming XML has the same identifier as an existing node elsewhere in the workspace. The change will be dispatched on save.
+
+* ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW: If an incoming node has the same identifier as a node already existing in the workspace then an ItemExistsException is thrown.
+
+
+Another interesting method is 
+
+{code} 
+void dump(Node node)
+{code} 
+
+This can be used as an example of how to do a recursive traversal of all the repository, and check the properties of each node. 
+
+Notice how we have to pay special attention to the multi-value properties, beacuse that impacts the way we use them:
+
+{code} 
+property.getDefinition().isMultiple()
+{code} 
+
+if this yelds true, then we are dealing with an array of values:
+
+{code} 
+Value[] values = property.getValues();
+{code} 
+
+or else, we can use the provided api shortcuts, to get the desired value:
+
+{code} 
+property.getString()
+{code} 
+
+which is equivalent to 
+
+{code} 
+property.getValue().getString()
+{code} 
+
+A very good entry point for utilities related code examples is [JcrUtils|http://jackrabbit.apache.org/api/2.2/org/apache/jackrabbit/commons/JcrUtils.html].

Propchange: jackrabbit/site/trunk/content/first-hops.cwiki
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/site/trunk/content/first-hops.mdtext
URL: http://svn.apache.org/viewvc/jackrabbit/site/trunk/content/first-hops.mdtext?rev=1229679&view=auto
==============================================================================
--- jackrabbit/site/trunk/content/first-hops.mdtext (added)
+++ jackrabbit/site/trunk/content/first-hops.mdtext Tue Jan 10 18:50:59 2012
@@ -0,0 +1,733 @@
+Title: First Hops
+Welcome to your first hops into the world of Jackrabbit! This introduction
+gives you a hands-on experience with Jackrabbit and the JCR API. Once you
+have finished hopping through this document, you should be all set to
+continue on your own with the official JCR specification and the
+documentation on this site. 
+
+<a name="FirstHops-Hop0:Gettingstarted"></a>
+## Hop 0: Getting started 
+
+The easiest way to get started with Jackrabbit is to [download](downloads.html)
+ the runnable [Standalone Server]
+ jar. In addition to running it, you can also put it in your classpath to
+quickly access all the classes and interfaces you need below.
+Alternatively, if you use the [Apache Maven|http://maven.apache.org/]
+ build system (which we recommend), you can set up your first hops project
+with the following dependenecies. 
+
+
+    <dependencies> 
+    <!-- The JCR API --> 
+    <dependency> 
+    <groupId>javax.jcr</groupId> 
+    <artifactId>jcr</artifactId> 
+    <version>2.0</version> 
+    </dependency> 
+    
+    <!-- Jackrabbit content repository --> 
+    <dependency> 
+    <groupId>org.apache.jackrabbit</groupId> 
+    <artifactId>jackrabbit-core</artifactId> 
+    <version>2.2.4</version> 
+    </dependency> 
+    
+    <!-- Use Log4J for logging --> 
+    <dependency> 
+    <groupId>org.slf4j</groupId> 
+    <artifactId>slf4j-log4j12</artifactId> 
+    <version>1.5.11</version> 
+    </dependency> 
+    </dependencies> 
+
+
+{note} 
+You probably have an error in your classpath settings if you get a
+*ClassNotFoundException* message when trying to compile or run the
+examples below. 
+{note} 
+
+<a name="FirstHops-Hop1:LoggingintoJackrabbit"></a>
+## Hop 1: Logging in to Jackrabbit 
+
+So let's get started. As a warm-up we'll create a Jackrabbit content
+repository and start a login session for accessing it. The full example
+application that does this is shown below, with line-by-line explanations
+following shortly after. 
+
+<DIV class="code panel" style="border-style: solid;border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;border-bottom-style: solid;"><B>FirstHop.java</B></DIV><DIV class="codeContent panelContent">
+    import javax.jcr.Repository; 
+    import javax.jcr.Session; 
+    import org.apache.jackrabbit.core.TransientRepository; 
+    
+    /** 
+    * First hop example. Logs in to a content repository and prints a 
+    * status message. 
+    */ 
+    public class FirstHop { 
+    
+    /** 
+    * The main entry point of the example application. 
+    * 
+    * @param args command line arguments (ignored) 
+    * @throws Exception if an error occurs 
+    */ 
+    public static void main(String[]
+ args) throws Exception { 
+    Repository repository = new TransientRepository(); 
+    Session session = repository.login(); 
+    try { 
+    String user = session.getUserID(); 
+    String name = repository.getDescriptor(Repository.REP_NAME_DESC); 
+    System.out.println( 
+    "Logged in as " + user + " to a " + name + " repository."); 
+    } finally { 
+    session.logout(); 
+    } 
+    } 
+    
+    } 
+
+
+You can also download the source file as FirstHop.java. If you have your
+classpath set up, you can compile the application with javac FirstHop.java
+and run it with java FirstHop to get the following output. 
+
+
+    Logged in as anonymous to a Jackrabbit repository. 
+
+
+In addition to producing the above status line the application copies a
+default repository configuration file to repository.xml and creates an
+initial Jackrabbit content repository in the repository subdirectory. You
+can use the system properties *org.apache.jackrabbit.repository.conf* and
+*org.apache.jackrabbit.repository.home* to set alternative configuration
+file and repository directory locations. 
+
+Read on for a detailed breakdown of the FirstHop application: 
+
+
+    import javax.jcr.Repository; 
+    import javax.jcr.Session; 
+
+
+The JCR API interfaces are located in the javax.jcr package found in the
+jcr-1.0.jar library. The promise of the JCR API is that if you only use
+these interfaces in your content application, it should remain mostly
+independent of the underlying content repository implementation. 
+
+The [Repository](http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Repository.html?is-external=true)
+ interface represents a given content repository instance and the [Session|http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Session.html?is-external=true]
+ interface represents a single login session for accessing the repository.
+A session is needed to access any content within a repository. 
+
+Note that a Session instance is not guaranteed to be thread-safe so you
+should start multiple sessions if you need to access repository content
+simultaneously from different threads. This is especially important for
+things like web applications. 
+
+
+    import org.apache.jackrabbit.core.TransientRepository; 
+
+
+The best practice for deploying Jackrabbit is to use JNDI or some other
+configuration mechanism in a container environment to keep the application
+code free of direct Jackrabbit dependencies, but since we are creating a
+simple standalone application we can take a shortcut by using the [TransientRepository](http://jackrabbit.apache.org/api/2.2/org/apache/jackrabbit/core/TransientRepository.html)
+ class from Jackrabbit core. 
+
+
+    public class FirstHop 
+    public static void main(String[]
+ args) throws Exception 
+
+
+The FirstHop example is a simple standalone application that fits nicely in
+the main() method and lets the JVM take care of the possible exceptions.
+More substantial content applications could also be written as web
+application or EJB components with different setup and error handling
+patterns. 
+
+
+    Repository repository = new TransientRepository(); 
+
+
+The TransientRepository class implements the JCR Repository interface, so
+you can simply assign a TransientRepository instance to a Repository
+variable. The default constructor contains a utility feature that will take
+care of the initial configuration and repository construction when the
+first session is started. Thus there is no need for manual configuration
+for now unless you want direct control over the repository setup. 
+
+The TransientRepository implementation will automatically initialize the
+content repository when the first session is started and shut it down when
+the last session is closed. Thus there is no need for explicit repository
+shutdown as long as all sessions are properly closed. Note that a
+Jackrabbit repository directory contains a lock file that prevents it from
+being accessed simultaneously by multiple processes. You will see
+repository startup exceptions caused by the lock file if you fail to
+properly close all sessions or otherwise shut down the repository before
+leaving the process that accesses a repository. Normally you can just
+manually remove the lock file in such cases but such cases always present a
+chance of repository corruption especially if you use a non-transactional
+persistence manager. 
+
+
+    Session session = repository.login(); 
+
+
+The default Repository.login() method starts a repository session using the
+default workspace and no user credentials. Jackrabbit tries to use the Java
+Authentication and Authorization Service (JAAS) configuration in such
+cases, but defaults to the anonymous user if a JAAS Subject is not found. 
+
+Since we use the TransientRepository class as the Repository
+implementation, this step will also cause the repository to be initialized. 
+
+
+    try { ... } finally { session.logout(); } 
+
+
+It is a good practice to properly release all acquired resources, and the
+JCR sessions are no exception. The try-finally idiom is a good way to
+ensure that a resource really gets released, as the release method gets
+called even if the intervening code throws an exception or otherwise jumps
+outside the scope (for example using a return, break, or continue
+statement). 
+
+The Session.logout() method in the finally branch closes the session and
+since this is the only session we have started, the TransientRepository is
+automatically shut down. 
+
+
+    String user = session.getUserID(); 
+
+
+The username or identifier of the user associated with a session is
+available using the Session.getUserID() method. Jackrabbit returns
+"anonymous" by default. 
+
+
+    String name = repository.getDescriptor(Repository.REP_NAME_DESC); 
+
+
+Each content repository implementation publishes a number of string
+descriptors that describe the various implementation properties, like the
+implementation level and the supported optional JCR features. See the [Repository](http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Repository.html?is-external=true)
+ interface for a list of the standard repository descriptors. The
+REP_NAME_DESC descriptor contains the name of the repository
+implementation, in this case "Jackrabbit". 
+
+<a name="FirstHops-Hop2:Workingwithcontent"></a>
+## Hop 2: Working with content 
+
+The main function of a content repository is allow applications to store
+and retrieve content. The content in a JCR content repository consists of
+structured or unstructured data modeled as a hierarchy of nodes with
+properties that contain the actual data. 
+
+The following example application first stores some content to the
+initially empty content repository, then retrieves the stored content and
+outputs it, and finally removes the stored content. 
+
+<DIV class="code panel" style="border-style: solid;border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;border-bottom-style: solid;"><B>SecondHop.java</B></DIV><DIV class="codeContent panelContent">
+    import javax.jcr.Repository; 
+    import javax.jcr.Session; 
+    import javax.jcr.SimpleCredentials; 
+    import javax.jcr.Node; 
+    import org.apache.jackrabbit.core.TransientRepository; 
+    
+    /** 
+    * Second hop example. Stores, retrieves, and removes example content. 
+    */ 
+    public class SecondHop { 
+    
+    /** 
+    * The main entry point of the example application. 
+    * 
+    * @param args command line arguments (ignored) 
+    * @throws Exception if an error occurs 
+    */ 
+    public static void main(String[]
+ args) throws Exception { 
+    Repository repository = new TransientRepository(); 
+    Session session = repository.login( 
+    new SimpleCredentials("username", "password".toCharArray())); 
+    try { 
+    Node root = session.getRootNode(); 
+    
+    // Store content 
+    Node hello = root.addNode("hello"); 
+    Node world = hello.addNode("world"); 
+    world.setProperty("message", "Hello, World!"); 
+    session.save(); 
+    
+    // Retrieve content 
+    Node node = root.getNode("hello/world"); 
+    System.out.println(node.getPath()); 
+    System.out.println(node.getProperty("message").getString()); 
+    
+    // Remove content 
+    root.getNode("hello").remove(); 
+    session.save(); 
+    } finally { 
+    session.logout(); 
+    } 
+    } 
+    
+    } 
+
+
+Like in the first hop, this example source is also available as
+SecondHop.java. You can also compile and run this class just like you did
+in the first hop example. Running this example should produce the following
+output: 
+
+
+    /hello/world 
+    Hello, World! 
+
+
+The basic structure of this example application is the same as in the First
+Hop example, so let's just walk through the differences: 
+
+
+    import javax.jcr.SimpleCredentials; 
+    import javax.jcr.Node; 
+
+
+These are two new classes we need for this example. The [SimpleCredentials](http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/SimpleCredentials.html?is-external=true)
+ class is a simple implementation of the [Credentials|http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Credentials.html?is-external=true]
+ interface used for passing explicit user credentials to the
+Repository.login(Credentials) method. 
+
+The [Node](http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Node.html?is-external=true)
+ interface is used to manage the content nodes in a repository. There is a
+related interface called [Property|http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Property.html?is-external=true]
+ for managing content properties, but in this example we use the Property
+interface only indirectly. 
+
+
+    new SimpleCredentials("username", "password".toCharArray()) 
+
+
+As discussed in the First Hop example, the default Repository.login()
+method returns an anonymous read-only session in the Jackrabbit default
+configuration. To be able to store and remove content we need to create a
+session with write access, and to do that we need to pass some credentials
+to the 
+
+
+    Repository.login(Credentials credentials) method. 
+
+
+The default Jackrabbit login mechanism accepts any username and password as
+valid credentials and returns a session with full write access. Thus we
+only need to construct and use a SimpleCredentials instance with some dummy
+username and password, in this case "username" and "password". 
+
+The SimpleCredentials constructor follows the JAAS convention of
+representing the username as a normal String, but the password as a
+character array, so we need to use the String.toCharArray() method to
+satisfy the constructor. 
+
+
+    Node root = session.getRootNode(); 
+
+
+Each JCR session is associated with a workspace that contains a single node
+tree. A simple way to access the root node is to call the
+Session.getRootNode() method. Having a reference to the root node allows us
+to easily store and retrieve content in the current workspace. 
+
+
+    Node hello = root.addNode("hello"); 
+    Node world = hello.addNode("world"); 
+
+
+New content nodes can be added using the Node.addNode(String relPath)
+method. The method takes the name (or relative path) of the node to be
+added and creates the named node in the transient storage associated with
+the current session. Until the transient storage is persisted, the added
+node is only visible within the current session and not within any other
+session that is concurrently accessing the content repository. 
+
+This code snippet creates two new nodes, called "hello" and "world", with
+"hello" being a child of the root node and "world" a child of the "hello"
+node. 
+
+
+    world.setProperty("message", "Hello, World!"); 
+
+
+To add some content to the structure created using the "hello" and "world"
+nodes, we use the Node.setProperty(String name, String value) method to add
+a string property called "message" to the "world" node. The value of the
+property is the string "Hello, World!". 
+
+Like the added nodes, also the property is first created in the transient
+storage associated with the current session. If the named property already
+exists, then this method will change the value of that property. 
+
+
+    session.save(); 
+
+
+Even though the rest of our example would work just fine using only the
+transient storage of the single session, we'd like to persist the changes
+we've made so far. This way other sessions could also access the example
+content we just created. If you like, you could even split the example
+application into three pieces for respectively storing, retrieving, and
+removing the example content. Such a split would not work unless we
+persisted the changes we make. 
+
+The Session.save() method persists all pending changes in the transient
+storage. The changes are written to the persistent repository storage and
+they become visible to all sessions accessing the same workspace. Without
+this call all changes will be lost forever when the session is closed. 
+
+
+    Node node = root.getNode("hello/world"); 
+
+
+Since we are still using the same session, we could use the existing hello
+and world node references to access the stored content, but let's pretend
+that we've started another session and want to retrieve the content that
+was previously stored. 
+
+The Node.getNode(String relPath) method returns a reference to the node at
+the given path relative to this node. The path syntax follows common file
+system conventions: a forward slash separates node names, a single dot
+represents the current node, and a double dot the parent node. Thus the
+path "hello/world" identifies the "world" child node of the "hello" child
+node of the current node - in this case the root node. The end result is
+that the method returns a node instance that represents the same content
+node as the world instance created a few lines earlier. 
+
+
+    System.out.println(node.getPath()); 
+
+
+Each content node and property is uniquely identified by its absolute path
+within the workspace. The absolute path starts with a forward slash and
+contains all the names of the ancestor nodes in order before the name of
+the current node or property. 
+
+The path of a node or property can be retrieved using the Item.getPath()
+method. The [Item](http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Item.html?is-external=true)
+ inteface is a superinterface of Node and Property, and contains all the
+functionality shared by nodes and properties. 
+
+The node variable references the "world" node, so this statement will
+output the line "/hello/world". 
+
+
+    System.out.println(node.getProperty("message").getString()); 
+
+
+Properties can be accessed using the Node.getProperty(String relPath)
+method that returns an instance of the [Property](http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Property.html?is-external=true)
+ interface that represents the property at the given path relative to the
+current node. In this case the "message" property is the one we created a
+few lines earlier. 
+
+A JCR property can contain either a single or multiple values of a given
+type. There are property types for storing strings, numbers, dates, binary
+streams, node references, etc. We just want the single string value, so we
+use the Property.getString() method. The result of this statement is the
+line "Hello, World!" being outputted. 
+
+
+    root.getNode("hello").remove(); 
+
+
+Nodes and properties can be removed using the Item.remove() method. The
+method removes the entire content subtree, so we only need to remove the
+topmost "hello" node to get rid of all the content we added before. 
+
+Removals are first stored in the session-local transient storage, just like
+added and changed content. Like before, the transient changes need to be
+explicitly saved for the content to be removed from the persistent storage. 
+
+<a name="FirstHops-Hop3:Importingcontent"></a>
+## Hop 3: Importing content 
+
+TODO: Update to match the style of previous hops. 
+
+To add content a bit more efficiently, you may want to try JCR's import
+facilities, such as Session.importXML. The following XML document by
+Elliotte Rusty Harold provides an interesting example that demonstrates a
+repository's namespace capabilities: 
+
+<DIV class="code panel" style="border-style: solid;border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;border-bottom-style: solid;"><B>test.xml</B></DIV><DIV class="codeContent panelContent">
+    <xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml" 
+    xmlns:mathml="http://www.w3.org/1998/Math/MathML"> 
+    <xhtml:head><xhtml:title>Three Namespaces</xhtml:title></xhtml:head> 
+    <xhtml:body> 
+    <xhtml:h1 align="center">An Ellipse and a Rectangle</xhtml:h1> 
+    <svg:svg xmlns:svg="http://www.w3.org/2000/svg" 
+    width="12cm" height="10cm"> 
+    <svg:ellipse rx="110" ry="130" /> 
+    <svg:rect x="4cm" y="1cm" width="3cm" height="6cm" /> 
+    </svg:svg> 
+    <xhtml:p>The equation for ellipses</xhtml:p> 
+    <mathml:math> 
+    <mathml:apply> 
+    <mathml:eq/> 
+    <mathml:cn> 1 </mathml:cn> 
+    <mathml:apply> 
+    <mathml:plus/> 
+    <mathml:apply> 
+    <mathml:divide/> 
+    <mathml:apply> 
+    <mathml:power/> 
+    <mathml:ci> x </mathml:ci> 
+    <mathml:cn> 2 </mathml:cn> 
+    </mathml:apply> 
+    <mathml:apply> 
+    <mathml:power/> 
+    <mathml:ci> a </mathml:ci> 
+    <mathml:cn> 2 </mathml:cn> 
+    </mathml:apply> 
+    </mathml:apply> 
+    <mathml:apply> 
+    <mathml:divide/> 
+    <mathml:apply> 
+    <mathml:power/> 
+    <mathml:ci> y </mathml:ci> 
+    <mathml:cn> 2 </mathml:cn> 
+    </mathml:apply> 
+    <mathml:apply> 
+    <mathml:power/> 
+    <mathml:ci> b </mathml:ci> 
+    <mathml:cn> 2 </mathml:cn> 
+    </mathml:apply> 
+    </mathml:apply> 
+    </mathml:apply> 
+    </mathml:apply> 
+    </mathml:math> 
+    <xhtml:hr/> 
+    <xhtml:p>Last Modified January 10, 2002</xhtml:p> 
+    </xhtml:body> 
+    </xhtml:html> 
+
+
+The third example application shown below will import the XML file called
+test.xml from the current directory into a new content repository node
+called importxml. Once the XML content is imported, the application
+recursively dumps the contents of the entire workspace using the simple
+dump() method. 
+
+<DIV class="code panel" style="border-style: solid;border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;border-bottom-style: solid;"><B>ThirdHop.java</B></DIV><DIV class="codeContent panelContent">
+    import javax.jcr.*; 
+    import org.apache.jackrabbit.core.TransientRepository; 
+    import java.io.FileInputStream; 
+    
+    /** 
+    * Third Jackrabbit example application. Imports an example XML file 
+    * and outputs the contents of the entire workspace. 
+    */ 
+    public class ThirdHop { 
+    
+    /**
+    * The main entry point of the example application.
+    *
+    * @param args command line arguments (ignored)
+    * @throws Exception if an error occurs
+    */
+    public static void main(String[]
+ args) throws Exception { 
+    Repository repository = new TransientRepository(); 
+    Session session = repository.login( 
+    new SimpleCredentials("username", "password".toCharArray())); 
+    try { 
+    Node root = session.getRootNode(); 
+    
+    // Import the XML file unless already imported 
+    if (!root.hasNode("importxml")) { 
+    System.out.print("Importing xml... "); 
+    
+    // Create an unstructured node under which to import the XML 
+    Node node = root.addNode("importxml", "nt:unstructured"); 
+    
+    // Import the file "test.xml" under the created node 
+    FileInputStream xml = new FileInputStream("test.xml");
+    session.importXML( 
+    node.getPath(), xml, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW); 
+    xml.close();
+    session.save(); 
+    System.out.println("done."); 
+    } 
+    
+    //output the repository content
+    dump(root); 
+    } finally { 
+    session.logout(); 
+    } 
+    } 
+    
+    /** Recursively outputs the contents of the given node. */ 
+    private static void dump(Node node) throws RepositoryException { 
+    // First output the node path 
+    System.out.println(node.getPath()); 
+    // Skip the virtual (and large!) jcr:system subtree 
+    if (node.getName().equals("jcr:system")) { 
+    return; 
+    } 
+    
+    // Then output the properties 
+    PropertyIterator properties = node.getProperties(); 
+    while (properties.hasNext()) { 
+    Property property = properties.nextProperty(); 
+    if (property.getDefinition().isMultiple()) { 
+    // A multi-valued property, print all values 
+    Value[]
+ values = property.getValues(); 
+    for (int i = 0; i < values.length; i++) { 
+    System.out.println( 
+    property.getPath() + " = " + values[i]
+.getString()); 
+    } 
+    } else { 
+    // A single-valued property 
+    System.out.println( 
+    property.getPath() + " = " + property.getString()); 
+    } 
+    } 
+    
+    // Finally output all the child nodes recursively 
+    NodeIterator nodes = node.getNodes(); 
+    while (nodes.hasNext()) { 
+    dump(nodes.nextNode()); 
+    } 
+    } 
+    
+    } 
+
+
+Running the ThirdHop class should produce output like the following: 
+
+
+    Importing XML... done. 
+    / 
+    /jcr:primaryType=rep:root 
+    /jcr:system 
+    /importxml 
+    /importxml/jcr:primaryType=nt:unstructured 
+    /importxml/xhtml:html 
+    /importxml/xhtml:html/jcr:primaryType=nt:unstructured 
+    /importxml/xhtml:html/xhtml:head 
+    /importxml/xhtml:html/xhtml:head/jcr:primaryType=nt:unstructured 
+    /importxml/xhtml:html/xhtml:head/xhtml:title 
+    /importxml/xhtml:html/xhtml:head/xhtml:title/jcr:primaryType=nt:unstructured 
+    /importxml/xhtml:html/xhtml:head/xhtml:title/jcr:xmltext 
+    /importxml/xhtml:html/xhtml:head/xhtml:title/jcr:xmltext/jcr:primaryType=nt:unstructured 
+    /importxml/xhtml:html/xhtml:head/xhtml:title/jcr:xmltext/jcr:xmlcharacters=Three
+Namespaces 
+    /importxml/xhtml:html/xhtml:body 
+    /importxml/xhtml:html/xhtml:body/jcr:primaryType=nt:unstructured 
+    /importxml/xhtml:html/xhtml:body/xhtml:h1 
+    /importxml/xhtml:html/xhtml:body/xhtml:h1/jcr:primaryType=nt:unstructured 
+    /importxml/xhtml:html/xhtml:body/xhtml:h1/align=center 
+    /importxml/xhtml:html/xhtml:body/xhtml:h1/jcr:xmltext 
+    /importxml/xhtml:html/xhtml:body/xhtml:h1/jcr:xmltext/jcr:primaryType=nt:unstructured 
+    /importxml/xhtml:html/xhtml:body/xhtml:h1/jcr:xmltext/jcr:xmlcharacters=An
+Ellipse and a Rectangle 
+    /importxml/xhtml:html/xhtml:body/svg:svg 
+    /importxml/xhtml:html/xhtml:body/svg:svg/jcr:primaryType=nt:unstructured 
+    /importxml/xhtml:html/xhtml:body/svg:svg/width=12cm 
+    /importxml/xhtml:html/xhtml:body/svg:svg/height=10cm 
+    . 
+    . 
+    . 
+
+
+This hop has a lot of similarities with the Second Hop example: we create a
+new session with write access by loggin in, next we insert data into the
+repository, this time by importing an xml file and finally we output the
+entire repository content.
+
+By now you should be familiar with loggin into a repository
+(Repository.login), creating a new node (Node.addNode) under the repository
+root (Session.getRootNode) and saving the session so that our changes are
+persisted (Session.save).
+
+Let us look at the new methods used in this example, how to import xml
+content:
+
+
+    session.importXML(node.getPath(), xml,
+ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+
+
+This deserializes an XML document and adds the resulting item subgraph as a
+child of the node at the provided path.
+
+The flag [ImportUUIDBehavior](http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/ImportUUIDBehavior.html?is-external=true)
+ governs how the identifiers of incoming nodes are handled. There are four
+options: 
+* ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW: Incoming nodes are added in
+the same way that new node is added with Node.addNode. That is, they are
+either assigned newly created identifiers upon addition or upon save. In
+either case, identifier collisions will not occur. 
+
+* ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING: If an incoming
+node has the same identifier as a node already existing in the workspace
+then the already existing node (and its subgraph) is removed from wherever
+it may be in the workspace before the incoming node is added. Note that
+this can result in nodes "disappearing" from locations in the workspace
+that are remote from the location to which the incoming subgraph is being
+written. Both the removal and the new addition will be dispatched on save.
+
+* ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING: If an incoming
+node has the same identifier as a node already existing in the workspace,
+then the already-existing node is replaced by the incoming node in the same
+position as the existing node. Note that this may result in the incoming
+subgraph being disaggregated and "spread around" to different locations in
+the workspace. In the most extreme case this behavior may result in no node
+at all being added as child of parentAbsPath. This will occur if the
+topmost element of the incoming XML has the same identifier as an existing
+node elsewhere in the workspace. The change will be dispatched on save.
+
+* ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW: If an incoming node has
+the same identifier as a node already existing in the workspace then an
+ItemExistsException is thrown.
+
+
+Another interesting method is 
+
+
+    void dump(Node node)
+
+
+This can be used as an example of how to do a recursive traversal of all
+the repository, and check the properties of each node. 
+
+Notice how we have to pay special attention to the multi-value properties,
+beacuse that impacts the way we use them:
+
+
+    property.getDefinition().isMultiple()
+
+
+if this yelds true, then we are dealing with an array of values:
+
+
+    Value[]
+ values = property.getValues();
+
+
+or else, we can use the provided api shortcuts, to get the desired value:
+
+
+    property.getString()
+
+
+which is equivalent to 
+
+
+    property.getValue().getString()
+
+
+A very good entry point for utilities related code examples is [JcrUtils](http://jackrabbit.apache.org/api/2.2/org/apache/jackrabbit/commons/JcrUtils.html)
+.

Propchange: jackrabbit/site/trunk/content/first-hops.mdtext
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/site/trunk/content/frequently-asked-questions.cwiki
URL: http://svn.apache.org/viewvc/jackrabbit/site/trunk/content/frequently-asked-questions.cwiki?rev=1229679&view=auto
==============================================================================
--- jackrabbit/site/trunk/content/frequently-asked-questions.cwiki (added)
+++ jackrabbit/site/trunk/content/frequently-asked-questions.cwiki Tue Jan 10 18:50:59 2012
@@ -0,0 +1,142 @@
+h2. General
+
+h3. What is JCR?
+
+JCR is the acronym of the Content Repository for Java technology API, a standard interface for accessing content repositories. JCR version 1.0 was specified in Java Specification Request 170 ([JSR 170|http://jcp.org/en/jsr/detail?id=170]), and version 2.0 is currently under work in [JSR 283|http://jcp.org/en/jsr/detail?id=283].
+
+h3. What is a content repository?
+
+A content repository is an information management system that provides various services for storing, accessing, and managing content. In addition to a hierarchically structured storage, common services of a content repository are versioning, access control, full text searching, and event monitoring. A content repository is not a content management system (CMS), although most existing CMSs contain a custom content repository implementation, often based on the file system or a relational database.
+
+h3. What is Apache Jackrabbit?
+
+Apache Jackrabbit is a fully featured content repository that implements the entire JCR API.  The Jackrabbit project was started when Day Software, the JSR-170 specification lead, licensed their initial implementation of the JCR reference implementation. The Jackrabbit codebase was used for the official reference implementation (RI) and technology compatibility kit (TCK) released along with the final JCR API.
+
+h3. What do I do if I have a question?
+
+Please ask questions on the [Jackrabbit mailing lists|http://jackrabbit.apache.org/mailing-lists.html]. There is the users list for questions around using JCR and Jackrabbit and the dev list for the development of Jackrabbit itself and for people starting to extend Jackrabbit or other advanced topics.
+
+
+h2. Building Jackrabbit
+
+h3. How do I build the Apache Jackrabbit sources?
+
+See the [Building Jackrabbit] page for detailed build instructions.
+
+h2. Using Jackrabbit
+
+h3. How do I do X with JCR/Jackrabbit?
+
+See the JCR specification, the JCR API documentation, or the Examples page on the Jackrabbit wiki for information on how to perform various operation using the JCR API.
+
+For Jackrabbit features (like access control and node type management) not covered by the JCR API, see the Examples page on the wiki, the Jackrabbit javadocs, or contact the Jackrabbit mailing list.
+
+h3. How do I use transactions with JCR?
+
+See the mailing list announcement for a simple example on using the JTA support in Jackrabbit. For a more complete explanation of the transaction features, please           see section 8.1 Transactions of the JCR specification.
+
+h3. How do I create new workspaces in Jackrabbit?
+
+The JCR 2.0 API has two [Workspace.createWorkspace()|http://www.day.com/maven/jsr170/javadocs/jcr-2.0/javax/jcr/Workspace.html#createWorkspace(java.lang.String)] methods for that.
+
+The JCR 1.0 API does not contain features for creating or managing workspaces, so you need to use Jackrabbit-specific functionality for creating new workspaces. You can create a new workspace either manually or programmatically.
+
+The manual way is to create a new workspace directory within the repository home directory and to place a new workspace.xml configuration file in that folder. You can use the configuration file of an existing workspace as an example, just remember to change the name of the workspace           in the Workspace name="..." tag. See the [Jackrabbit Configuration] page for configuration details. Note also that you need to restart the repository instance to access the new workspace.
+
+The programmatic way is to acquire a Workspace instance using the normal JCR API and to cast the instance to the JackrabbitWorkspace interface. You can then use the createWorkspace(String) method to create new workspaces.
+
+h3. How do I delete a workspace in Jackrabbit?
+
+There is currently no programmatic way to delete workspaces. You can delete a workspace by manually removing the workspace directory when the repository instance is not running.
+
+h3. How do I deploy Jackrabbit into Tomcat?
+
+* Download [jcr-1.0.jar|http://www.day.com/maven/javax.jcr/jars/jcr-1.0.jar] and put it into {{<tomcat-install-dir>/shared/lib}}.
+* Get the WAR distribution from the [Downloads] page and deploy it into Tomcat.
+* Point your browser to {{http://}}{{localhost:8080/jackrabbit-webapp-<version>/}}
+
+h2. Access control
+
+h3. How do I use LDAP, Kerberos, or some other authentication mechanism         with Jackrabbit?
+
+Jackrabbit uses the Java Authentication and Authorization Service (JAAS) for authenticating users. You should be able to use any           JAAS LoginModule implementation (e.g. the LoginModules in thecom.sum.security.auth.modulepackage) for authentication. See the JAAS documentation for           configuration instructions.
+
+h3. How do I manage the access rights of authenticated users?
+
+The current JackrabbitSimpleAccessManager class only supports three access levels: anonymous, normal, and           system. Anonymous users have read access while normal and system           users have full read-write access. You need to implement a custom AccessManager class to get more fine-grained access control.
+
+
+h2. Persistence managers
+
+h3. What is a persistence manager?
+
+A persistence manager (PM) is an internal Jackrabbit           component that handles the persistent storage of content nodes           and properties. Each workspace of a Jackrabbit content repository           uses a separate persistence manager to store the content in that           workspace. Also the Jackrabbit version handler uses a separate           persistence manager.The persistence manager sits at the very bottom layer of the           Jackrabbit system architecture. Reliability, integrity and           performance of the PM are crucial to the overall           stability and performance of the repository. If e.g. the data           that a PM is based upon is allowed to change through external           means the integrity of the repository would be at risk           (think of referential integrity / node references e.g.).
+
+In practice, a persistence manager is any Java class that           implements the PersistenceManager            interface and the associated behavoural contracts. Jackrabbit           contains a set of built-in persistence manager classes that cover           most of the deployment needs. There are also a few contributed           persistence managers that give additional flexibility.
+
+h3. What is a Jackrabbit file system?
+
+A Jackrabbbit file system (FS) is an internal component that           implements standard file system operations on top of some underlying           storage mechanism (a normal file system, a database, a webdav server,           or a custom file format). A file system component is any Java class           that implements the FileSystem            interface and the associated behavioral contracts. File systems           are used in Jackrabbit both as subcomponents of the persistence           managers and for general storage needs (for example to store the           full text indexes).
+
+h3. Can I use a persistence manager to access an existing data source?
+
+No. The persistence manager interface was never intended as being           a general SPI that you could implement in order to integrate           external data sources with proprietary formats (e.g. a customers           database). The reason why we abstracted the PM interface was           to leave room for future performance optimizations that would           not affect the rest of the implementation (e.g. by storing the           raw data in a b-tree based database instead of individual file).
+
+h3. How smart should a persistence manager be?
+
+A persistence manager should not be intelligent, i.e.           it should not interpret the content it is managing.           The only thing it should care about is to efficiently,           consistently, and reliably store and read the content encapsulated           in the passed NodeState and PropertyState objects. Though it           might be feasible to write a custom persistence manager to           represent existing legacy data in a level-1 (read-only) repository,           I don't think the same is possible for a level-2 repository and           I certainly would not recommend it.
+
+h2. Query
+
+h3. I've configured textFilterClasses but my query still doesn't work, what's wrong?
+
+Make sure you changed existing workspace.xml files as well. The workspace element in repository.xml only acts as a template for new workspaces.
+
+Verify that you also put the jar files into the classpath that jackrabbit depends on for text extraction. You can find all required jar files inside the jackrabbit-webapp war file (the {{WEB-INF/lib}} folder). Go to the [downloads|Downloads] page to get the war file.
+
+Some documents may still not be searchable for various reasons: the document is corrupt, bug in one of the libraries that extract text, document is encrypted or otherwise protected, etc.
+
+h3. Why doesn't {{//*\[jcr:contains(@jcr:data, 'foo')]}} return matches for binary content?
+
+Extracted text from binary content is only indexed on the parent node of the @jcr:data property. Use jcr:contains() on the nt:resource node.
+Examples:
+{noformat}
+//element(*, nt:resource)[jcr:contains(., 'foo')] 
+//element(*, nt:file)[jcr:contains(jcr:content, 'foo')] 
+{noformat}
+
+h3. Can I use the Lucene field syntax in jcr:contains()?
+
+No, you cannot. Even though Jackrabbit uses a Lucene index, the fields for JCR properties do not map 1:1 to Lucene fields. Instead you can use the following:
+
+{noformat}
+//element(*, book)[jcr:contains(@title, 'jackrabbit') and jcr:contains(@text, 'query')]
+{noformat}
+
+h3. My XPath query returns no results when I add a path constraint, what's wrong?
+
+You probably forgot to prefix your statement with {{/jcr:root}}.
+
+JSR 170 says in section 6.6.4.3:
+{quote}
+The context node of an XPath query is the XML node relative to which the query expression is evaluated.
+
+A relative XPath statement (one that does not have a leading /) will be interpreted relative to the root node of the workspace, which, in the XML document view is the top-most XML element, <jcr:root>. This means that one should not include jcr:root as the first segment in a relative XPath statement, since that element is already the default context node.
+
+An absolute XPath (one with a leading /), in contrast, will be interpreted relative to a position one level above <jcr:root>. This means that an absolute XPath must either begin with // or with /jcr:root in order to match anything at all.
+{quote}
+
+h3. How do I force a consistency check on the search index?
+
+Forcing a consistency check may be useful when you think the index is inconsistent. You need to add two parameters to the SearchIndex section in the workspace.xml configuration file:
+
+{noformat}
+<param name="enableConsistencyCheck" value="true"/>
+<param name="forceConsistencyCheck" value="true"/>
+{noformat}
+
+Then restart Jackrabbit and watch the log file for possible repair messages. Don't forget to remove the parameters again when you are done.
+
+h3. Why is the size of my query result -1?
+
+A JCR implementation may return -1 when the size is unknown. Starting with 2.0 Jackrabbit will return -1 for some query statements when there is potential for a more optimized query execution. If you still want a size information you can append an order by clause to your statement. This will force Jackrabbit to calculate the result size.

Propchange: jackrabbit/site/trunk/content/frequently-asked-questions.cwiki
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/site/trunk/content/frequently-asked-questions.mdtext
URL: http://svn.apache.org/viewvc/jackrabbit/site/trunk/content/frequently-asked-questions.mdtext?rev=1229679&view=auto
==============================================================================
--- jackrabbit/site/trunk/content/frequently-asked-questions.mdtext (added)
+++ jackrabbit/site/trunk/content/frequently-asked-questions.mdtext Tue Jan 10 18:50:59 2012
@@ -0,0 +1,282 @@
+Title: Frequently Asked Questions
+<a name="FrequentlyAskedQuestions-General"></a>
+## General
+
+<a name="FrequentlyAskedQuestions-WhatisJCR?"></a>
+### What is JCR?
+
+JCR is the acronym of the Content Repository for Java technology API, a standard interface for accessing content repositories. JCR version 1.0 was specified in Java Specification Request 170 ([JSR 170](http://jcp.org/en/jsr/detail?id=170)
+), and version 2.0 is currently under work in [JSR 283|http://jcp.org/en/jsr/detail?id=283]
+.
+
+<a name="FrequentlyAskedQuestions-Whatisacontentrepository?"></a>
+### What is a content repository?
+
+A content repository is an information management system that provides
+various services for storing, accessing, and managing content. In addition
+to a hierarchically structured storage, common services of a content
+repository are versioning, access control, full text searching, and event
+monitoring. A content repository is not a content management system (CMS),
+although most existing CMSs contain a custom content repository
+implementation, often based on the file system or a relational database.
+
+<a name="FrequentlyAskedQuestions-WhatisApacheJackrabbit?"></a>
+### What is Apache Jackrabbit?
+
+Apache Jackrabbit is a fully featured content repository that implements
+the entire JCR API.  The Jackrabbit project was started when Day Software,
+the JSR-170 specification lead, licensed their initial implementation of
+the JCR reference implementation. The Jackrabbit codebase was used for the
+official reference implementation (RI) and technology compatibility kit
+(TCK) released along with the final JCR API.
+
+<a name="FrequentlyAskedQuestions-WhatdoIdoifIhaveaquestion?"></a>
+### What do I do if I have a question?
+
+Please ask questions on the [Jackrabbit mailing lists](http://jackrabbit.apache.org/mailing-lists.html)
+. There is the users list for questions around using JCR and Jackrabbit and
+the dev list for the development of Jackrabbit itself and for people
+starting to extend Jackrabbit or other advanced topics.
+
+
+<a name="FrequentlyAskedQuestions-BuildingJackrabbit"></a>
+## Building Jackrabbit
+
+<a name="FrequentlyAskedQuestions-HowdoIbuildtheApacheJackrabbitsources?"></a>
+### How do I build the Apache Jackrabbit sources?
+
+See the [Building Jackrabbit](building-jackrabbit.html)
+ page for detailed build instructions.
+
+<a name="FrequentlyAskedQuestions-UsingJackrabbit"></a>
+## Using Jackrabbit
+
+<a name="FrequentlyAskedQuestions-HowdoIdoXwithJCR/Jackrabbit?"></a>
+### How do I do X with JCR/Jackrabbit?
+
+See the JCR specification, the JCR API documentation, or the Examples page
+on the Jackrabbit wiki for information on how to perform various operation
+using the JCR API.
+
+For Jackrabbit features (like access control and node type management) not
+covered by the JCR API, see the Examples page on the wiki, the Jackrabbit
+javadocs, or contact the Jackrabbit mailing list.
+
+<a name="FrequentlyAskedQuestions-HowdoIusetransactionswithJCR?"></a>
+### How do I use transactions with JCR?
+
+See the mailing list announcement for a simple example on using the JTA
+support in Jackrabbit. For a more complete explanation of the transaction
+features, please	   see section 8.1 Transactions of the JCR
+specification.
+
+<a name="FrequentlyAskedQuestions-HowdoIcreatenewworkspacesinJackrabbit?"></a>
+### How do I create new workspaces in Jackrabbit?
+
+The JCR 2.0 API has two [Workspace.createWorkspace()](http://www.day.com/maven/jsr170/javadocs/jcr-2.0/javax/jcr/Workspace.html#createWorkspace(java.lang.String))
+ methods for that.
+
+The JCR 1.0 API does not contain features for creating or managing
+workspaces, so you need to use Jackrabbit-specific functionality for
+creating new workspaces. You can create a new workspace either manually or
+programmatically.
+
+The manual way is to create a new workspace directory within the repository
+home directory and to place a new workspace.xml configuration file in that
+folder. You can use the configuration file of an existing workspace as an
+example, just remember to change the name of the workspace	     in the
+Workspace name="..." tag. See the [Jackrabbit Configuration](jackrabbit-configuration.html)
+ page for configuration details. Note also that you need to restart the
+repository instance to access the new workspace.
+
+The programmatic way is to acquire a Workspace instance using the normal
+JCR API and to cast the instance to the JackrabbitWorkspace interface. You
+can then use the createWorkspace(String) method to create new workspaces.
+
+<a name="FrequentlyAskedQuestions-HowdoIdeleteaworkspaceinJackrabbit?"></a>
+### How do I delete a workspace in Jackrabbit?
+
+There is currently no programmatic way to delete workspaces. You can delete
+a workspace by manually removing the workspace directory when the
+repository instance is not running.
+
+<a name="FrequentlyAskedQuestions-HowdoIdeployJackrabbitintoTomcat?"></a>
+### How do I deploy Jackrabbit into Tomcat?
+
+* Download [jcr-1.0.jar](http://www.day.com/maven/javax.jcr/jars/jcr-1.0.jar)
+ and put it into *<tomcat-install-dir>/shared/lib*.
+* Get the WAR distribution from the [Downloads](downloads.html)
+ page and deploy it into Tomcat.
+* Point your browser to
+*http://**localhost:8080/jackrabbit-webapp-<version>/*
+
+<a name="FrequentlyAskedQuestions-Accesscontrol"></a>
+## Access control
+
+h3. How do I use LDAP, Kerberos, or some other authentication mechanism    
+    with Jackrabbit?
+
+Jackrabbit uses the Java Authentication and Authorization Service (JAAS)
+for authenticating users. You should be able to use any 	  JAAS
+LoginModule implementation (e.g. the LoginModules in
+thecom.sum.security.auth.modulepackage) for authentication. See the JAAS
+documentation for	    configuration instructions.
+
+<a name="FrequentlyAskedQuestions-HowdoImanagetheaccessrightsofauthenticatedusers?"></a>
+### How do I manage the access rights of authenticated users?
+
+The current JackrabbitSimpleAccessManager class only supports three access
+levels: anonymous, normal, and		 system. Anonymous users have read
+access while normal and system		 users have full read-write access.
+You need to implement a custom AccessManager class to get more fine-grained
+access control.
+
+
+<a name="FrequentlyAskedQuestions-Persistencemanagers"></a>
+## Persistence managers
+
+<a name="FrequentlyAskedQuestions-Whatisapersistencemanager?"></a>
+### What is a persistence manager?
+
+A persistence manager (PM) is an internal Jackrabbit	       component
+that handles the persistent storage of content nodes	       and
+properties. Each workspace of a Jackrabbit content repository	       
+uses a separate persistence manager to store the content in that	  
+workspace. Also the Jackrabbit version handler uses a separate		
+persistence manager.The persistence manager sits at the very bottom layer
+of the		 Jackrabbit system architecture. Reliability, integrity and
+	  performance of the PM are crucial to the overall	    
+stability and performance of the repository. If e.g. the data	       
+that a PM is based upon is allowed to change through external	       
+means the integrity of the repository would be at risk		 (think of
+referential integrity / node references e.g.).
+
+In practice, a persistence manager is any Java class that	   
+implements the PersistenceManager	     interface and the associated
+behavoural contracts. Jackrabbit	   contains a set of built-in
+persistence manager classes that cover		 most of the deployment
+needs. There are also a few contributed 	  persistence managers that
+give additional flexibility.
+
+<a name="FrequentlyAskedQuestions-WhatisaJackrabbitfilesystem?"></a>
+### What is a Jackrabbit file system?
+
+A Jackrabbbit file system (FS) is an internal component that	      
+implements standard file system operations on top of some underlying	   
+   storage mechanism (a normal file system, a database, a webdav server,   
+       or a custom file format). A file system component is any Java class 
+	 that implements the FileSystem 	   interface and the
+associated behavioral contracts. File systems		are used in
+Jackrabbit both as subcomponents of the persistence	      managers and
+for general storage needs (for example to store the	      full text
+indexes).
+
+<a name="FrequentlyAskedQuestions-CanIuseapersistencemanagertoaccessanexistingdatasource?"></a>
+### Can I use a persistence manager to access an existing data source?
+
+No. The persistence manager interface was never intended as being	   
+a general SPI that you could implement in order to integrate	      
+external data sources with proprietary formats (e.g. a customers	  
+database). The reason why we abstracted the PM interface was	       to
+leave room for future performance optimizations that would	     not
+affect the rest of the implementation (e.g. by storing the	     raw
+data in a b-tree based database instead of individual file).
+
+<a name="FrequentlyAskedQuestions-Howsmartshouldapersistencemanagerbe?"></a>
+### How smart should a persistence manager be?
+
+A persistence manager should not be intelligent, i.e.		it should
+not interpret the content it is managing.	    The only thing it
+should care about is to efficiently,	       consistently, and reliably
+store and read the content encapsulated 	  in the passed NodeState
+and PropertyState objects. Though it	       might be feasible to write a
+custom persistence manager to		represent existing legacy data in a
+level-1 (read-only) repository, 	  I don't think the same is
+possible for a level-2 repository and		I certainly would not
+recommend it.
+
+<a name="FrequentlyAskedQuestions-Query"></a>
+## Query
+
+h3. I've configured textFilterClasses but my query still doesn't work,
+what's wrong?
+
+Make sure you changed existing workspace.xml files as well. The workspace
+element in repository.xml only acts as a template for new workspaces.
+
+Verify that you also put the jar files into the classpath that jackrabbit
+depends on for text extraction. You can find all required jar files inside
+the jackrabbit-webapp war file (the *WEB-INF/lib* folder). Go to the [downloads](downloads.html)
+ page to get the war file.
+
+Some documents may still not be searchable for various reasons: the
+document is corrupt, bug in one of the libraries that extract text,
+document is encrypted or otherwise protected, etc.
+
+h3. Why doesn't {{//*\[jcr:contains(@jcr:data, 'foo')](jcr:contains(@jcr:data,-'foo').html)
+}} return matches for binary content?
+
+Extracted text from binary content is only indexed on the parent node of
+the @jcr:data property. Use jcr:contains() on the nt:resource node.
+Examples:
+
+    //element(*, nt:resource)[jcr:contains(., 'foo')]
+    //element(*, nt:file)[jcr:contains(jcr:content, 'foo')]
+
+
+<a name="FrequentlyAskedQuestions-CanIusetheLucenefieldsyntaxinjcr:contains()?"></a>
+### Can I use the Lucene field syntax in jcr:contains()?
+
+No, you cannot. Even though Jackrabbit uses a Lucene index, the fields for
+JCR properties do not map 1:1 to Lucene fields. Instead you can use the
+following:
+
+
+    //element(*, book)[jcr:contains(@title, 'jackrabbit') and jcr:contains(@text, 'query')]
+
+
+h3. My XPath query returns no results when I add a path constraint, what's
+wrong?
+
+You probably forgot to prefix your statement with */jcr:root*.
+
+JSR 170 says in section 6.6.4.3:
+{quote}
+The context node of an XPath query is the XML node relative to which the
+query expression is evaluated.
+
+A relative XPath statement (one that does not have a leading /) will be
+interpreted relative to the root node of the workspace, which, in the XML
+document view is the top-most XML element, <jcr:root>. This means that one
+should not include jcr:root as the first segment in a relative XPath
+statement, since that element is already the default context node.
+
+An absolute XPath (one with a leading /), in contrast, will be interpreted
+relative to a position one level above <jcr:root>. This means that an
+absolute XPath must either begin with // or with /jcr:root in order to
+match anything at all.
+{quote}
+
+<a name="FrequentlyAskedQuestions-HowdoIforceaconsistencycheckonthesearchindex?"></a>
+### How do I force a consistency check on the search index?
+
+Forcing a consistency check may be useful when you think the index is
+inconsistent. You need to add two parameters to the SearchIndex section in
+the workspace.xml configuration file:
+
+
+    <param name="enableConsistencyCheck" value="true"/>
+    <param name="forceConsistencyCheck" value="true"/>
+
+
+Then restart Jackrabbit and watch the log file for possible repair
+messages. Don't forget to remove the parameters again when you are done.
+
+<a name="FrequentlyAskedQuestions-Whyisthesizeofmyqueryresult-1?"></a>
+### Why is the size of my query result -1?
+
+A JCR implementation may return -1 when the size is unknown. Starting with
+2.0 Jackrabbit will return -1 for some query statements when there is
+potential for a more optimized query execution. If you still want a size
+information you can append an order by clause to your statement. This will
+force Jackrabbit to calculate the result size.

Propchange: jackrabbit/site/trunk/content/frequently-asked-questions.mdtext
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/site/trunk/content/getting-started-with-apache-jackrabbit.cwiki
URL: http://svn.apache.org/viewvc/jackrabbit/site/trunk/content/getting-started-with-apache-jackrabbit.cwiki?rev=1229679&view=auto
==============================================================================
--- jackrabbit/site/trunk/content/getting-started-with-apache-jackrabbit.cwiki (added)
+++ jackrabbit/site/trunk/content/getting-started-with-apache-jackrabbit.cwiki Tue Jan 10 18:50:59 2012
@@ -0,0 +1,19 @@
+To get started with Jackrabbit you should first become familiar with the JCR API. Download the [JSR 170 specification|http://jcp.org/aboutJava/communityprocess/final/jsr170/index.html], browse the [API documentation|http://www.day.com/maven/jsr170/javadocs/jcr-1.0/], check our introduction to JCR levels,         or read some of the JCR articles to understand the content repository model that Jackrabbit implements.         You can also take a look at the various JCR and Jackrabbit applications to get an idea of what to do with a content repository.
+
+ If you are interested in using Jackrabbit, you should check the Jackrabbit architecture and         try out the First Hops examples we         have prepared. You can either download a binary release or build Jackrabbit         from sources.
+
+ Take a look at the Frequently Asked Questions or browse the         archives of the user and development mailing lists (see also the searchable archives at The Mail Archive, Gmane, and Nabble) for answers to questions not covered by the         documentation pages. See the Mailing Lists page if you want to         subscribe or unsubscribe the Jackrabbit mailing lists.
+
+ Apache Jackrabbit is an open source project and welcomes all contributions.         You can participate by answering questions on the mailing list, filing bug reports for any problems or improvement ideas         you come up with, contributing to the Jackrabbit Wiki, or writing documentation and code. See the How the ASF works page for background         information on the Apache Software Foundation and the way we work.
+
+h2. Content Repository for Java Technology API (JCR)
+
+ Jackrabbit is a complete implementation of the JCR API, so the         primary API for Jackrabbit application developers is to be found         in the JCR section of the          Documentation.
+
+h2. Jackrabbit architecture and Deployment Models
+
+ Find out more about the Jackrabbit Architecture or         learn more about the Jackrabbit deployment Options be         it as an embedded content repository to be          delivered with you are application, a shared repository for example in a J2EE environment or a classical content repository server setup.
+
+h2. Node Types
+
+ To learn about the content modeling system used in Jackrabbit, read the section on node types.

Propchange: jackrabbit/site/trunk/content/getting-started-with-apache-jackrabbit.cwiki
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/site/trunk/content/getting-started-with-apache-jackrabbit.mdtext
URL: http://svn.apache.org/viewvc/jackrabbit/site/trunk/content/getting-started-with-apache-jackrabbit.mdtext?rev=1229679&view=auto
==============================================================================
--- jackrabbit/site/trunk/content/getting-started-with-apache-jackrabbit.mdtext (added)
+++ jackrabbit/site/trunk/content/getting-started-with-apache-jackrabbit.mdtext Tue Jan 10 18:50:59 2012
@@ -0,0 +1,50 @@
+Title: Getting Started with Apache Jackrabbit
+To get started with Jackrabbit you should first become familiar with the
+JCR API. Download the [JSR 170 specification](http://jcp.org/aboutJava/communityprocess/final/jsr170/index.html)
+, browse the [API documentation|http://www.day.com/maven/jsr170/javadocs/jcr-1.0/]
+, check our introduction to JCR levels, 	or read some of the JCR
+articles to understand the content repository model that Jackrabbit
+implements.	    You can also take a look at the various JCR and
+Jackrabbit applications to get an idea of what to do with a content
+repository.
+
+ If you are interested in using Jackrabbit, you should check the Jackrabbit
+architecture and	 try out the First Hops examples we	    have
+prepared. You can either download a binary release or build Jackrabbit	   
+   from sources.
+
+ Take a look at the Frequently Asked Questions or browse the	    
+archives of the user and development mailing lists (see also the searchable
+archives at The Mail Archive, Gmane, and Nabble) for answers to questions
+not covered by the	   documentation pages. See the Mailing Lists page
+if you want to	       subscribe or unsubscribe the Jackrabbit mailing
+lists.
+
+ Apache Jackrabbit is an open source project and welcomes all
+contributions.	       You can participate by answering questions on the
+mailing list, filing bug reports for any problems or improvement ideas	   
+   you come up with, contributing to the Jackrabbit Wiki, or writing
+documentation and code. See the How the ASF works page for background	   
+  information on the Apache Software Foundation and the way we work.
+
+<a name="GettingStartedwithApacheJackrabbit-ContentRepositoryforJavaTechnologyAPI(JCR)"></a>
+## Content Repository for Java Technology API (JCR)
+
+ Jackrabbit is a complete implementation of the JCR API, so the        
+primary API for Jackrabbit application developers is to be found	 in
+the JCR section of the		Documentation.
+
+<a name="GettingStartedwithApacheJackrabbit-JackrabbitarchitectureandDeploymentModels"></a>
+## Jackrabbit architecture and Deployment Models
+
+ Find out more about the Jackrabbit Architecture or	    learn more
+about the Jackrabbit deployment Options be	   it as an embedded
+content repository to be	  delivered with you are application, a
+shared repository for example in a J2EE environment or a classical content
+repository server setup.
+
+<a name="GettingStartedwithApacheJackrabbit-NodeTypes"></a>
+## Node Types
+
+ To learn about the content modeling system used in Jackrabbit, read the
+section on node types.