jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tri...@apache.org
Subject svn commit: r1670829 [2/7] - in /jackrabbit/site/trunk: ./ attic/ attic/cgi-bin/ attic/content/ attic/lib/ attic/templates/ cgi-bin/ content/ lib/ src/ src/site/ src/site/markdown/ src/site/resources/ src/site/resources/css/ src/site/resources/images/ ...
Date Thu, 02 Apr 2015 07:13:58 GMT
Added: jackrabbit/site/trunk/src/site/markdown/embedded-repository.md
URL: http://svn.apache.org/viewvc/jackrabbit/site/trunk/src/site/markdown/embedded-repository.md?rev=1670829&view=auto
==============================================================================
--- jackrabbit/site/trunk/src/site/markdown/embedded-repository.md (added)
+++ jackrabbit/site/trunk/src/site/markdown/embedded-repository.md Thu Apr  2 07:13:56 2015
@@ -0,0 +1,279 @@
+Title: Embedded Repository
+You can run Jackrabbit in embedded mode inside your application if you only
+(or mostly) access a repository from that one application. In this
+deployment model the Jackrabbit dependencies are included directly in your
+classpath and your application is in full control of the repository
+lifecycle. To use this deployment model you need to add the appropriate
+dependencies to your application and include a few lines of
+Jackrabbit-specific code to start and stop a repository. You can then use
+the standard JCR API to access and manage content inside the repository.
+
+This page describes how to embed Jackrabbit in your application.
+
+{toc:minLevel=2}
+
+<a name="EmbeddedRepository-Jackrabbitdependencies"></a>
+## Jackrabbit dependencies
+
+To use Jackrabbit in embedded mode you need to make sure that the JCR API
+and all required Jackrabbit libraries are included in your classpath. If
+you use [Maven 2](http://maven.apache.org/)
+, you can achieve this by specifying the following dependencies.
+
+
+    <dependency>
+      <groupId>javax.jcr</groupId>
+      <artifactId>jcr</artifactId>
+      <version>1.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>jackrabbit-core</artifactId>
+      <version>1.5.0</version>
+      <exclusions>
+        <exclusion>
+          <groupId>commons-logging</groupId>
+          <artifactId>commons-logging</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <version>1.5.3</version>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <version>1.5.3</version>
+    </dependency>
+
+
+The jcr dependency includes the JCR 1.0 API in your classpath. You need to
+explicitly declare this dependency as in jackrabbit-core the JCR API
+dependency scope is _provided_ to work better in deployment models where
+the JCR API is shared between multiple applications.
+
+The jackrabbit-core dependency pulls in the Jackrabbit content repository
+implementation and a set of transitive dependencies needed by Jackrabbit.
+See the [Downloads](downloads.html)
+ page for the latest available version.
+
+Jackrabbit uses the [SLF4J](http://www.slf4j.org/)
+ for logging and leaves it up to the embedding application to decide which
+underlying logging library to use. In the example above we use the
+slf4j-log4j12 library which uses [log4j 1.2|http://logging.apache.org/log4j/1.2/]
+ for handling the log messages. Note that the commons-logging dependency
+(which is a transitive dependency from [Apache POI|http://poi.apache.org/]
+) is explicitly replaced with the jcl-over-slf4j dependency that routes
+also all [Commons Logging|http://commons.apache.org/logging/]
+ log messages through the selected SLF4J implementation. Jackrabbit 1.5.x
+uses SLF4J version 1.5.3.
+
+The full set of compile-scope dependencies included by the above
+declaration is shown below. If you use a build tool like [Ant](http://ant.apache.org/)
+ where you need to explicitly include all dependencies, you can use this
+list to correctly configure your classpath.
+
+
+    +- javax.jcr:jcr:jar:1.0:compile
+    +- org.apache.jackrabbit:jackrabbit-core:jar:1.5.0:compile
+    |  +- concurrent:concurrent:jar:1.3.4:compile
+    |  +- commons-collections:commons-collections:jar:3.1:compile
+    |  +- commons-io:commons-io:jar:1.4:compile
+    |  +- org.apache.jackrabbit:jackrabbit-api:jar:1.5.0:compile
+    |  +- org.apache.jackrabbit:jackrabbit-jcr-commons:jar:1.5.0:compile
+    |  +- org.apache.jackrabbit:jackrabbit-spi-commons:jar:1.5.0:compile
+    |  +- org.apache.jackrabbit:jackrabbit-spi:jar:1.5.0:compile
+    |  +- org.apache.jackrabbit:jackrabbit-text-extractors:jar:1.5.0:compile
+    |  |  +- org.apache.poi:poi:jar:3.0.2-FINAL:compile
+    |  |  +- org.apache.poi:poi-scratchpad:jar:3.0.2-FINAL:compile
+    |  |  +- pdfbox:pdfbox:jar:0.7.3:compile
+    |  |  |  +- org.fontbox:fontbox:jar:0.1.0:compile
+    |  |  |  \- org.jempbox:jempbox:jar:0.2.0:compile
+    |  |  \- net.sourceforge.nekohtml:nekohtml:jar:1.9.7:compile
+    |  |	 \- xerces:xercesImpl:jar:2.8.1:compile
+    |  |	    \- xml-apis:xml-apis:jar:1.3.03:compile
+    |  +- org.slf4j:slf4j-api:jar:1.5.3:compile
+    |  +- org.apache.lucene:lucene-core:jar:2.3.2:compile
+    |  \- org.apache.derby:derby:jar:10.2.1.6:compile
+    +- org.slf4j:jcl-over-slf4j:jar:1.5.3:compile
+    \- org.slf4j:slf4j-log4j12:jar:1.5.3:compile
+       \- log4j:log4j:jar:1.2.14:compile
+
+
+Note that some of the transitive dependencies listed above may conflict
+with some other dependencies of our application. In such cases you may want
+to consider switching to a deployment model that uses separate class
+loaders for your application and the Jackrabbit content repository.
+
+<a name="EmbeddedRepository-Startingtherepository"></a>
+## Starting the repository
+
+Once you have your classpath configured you can start the repository with
+the following piece of code.
+
+{code:java}
+import javax.jcr.Repository;
+import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.core.config.RepositoryConfig;
+
+String xml = "/path/to/repository/configuration.xml";
+String dir = "/path/to/repository/directory";
+RepositoryConfig config = RepositoryConfig.create(xml, dir);
+Repository repository = RepositoryImpl.create(config);
+
+    
+    See the [Jackrabbit Configuration]
+ page for more information on repository configuration. See the [RepositoryConfig|http://jackrabbit.apache.org/api/1.5/org/apache/jackrabbit/core/config/RepositoryConfig.html]
+ and [RepositoryImpl|http://jackrabbit.apache.org/api/1.5/org/apache/jackrabbit/core/RepositoryImpl.html]
+ javadocs for more details on these classes.
+    
+    h2. Shutting down the repository
+    
+    When your application no longer needs the content repository, you can shut
+it down with the following code.
+    
+    {code:java}
+    ((RepositoryImpl) repository).shutdown();
+
+
+This will forcibly close all open sessions and make sure that all
+repository content is safely stored on disk.
+
+<a name="EmbeddedRepository-TheTransientRepositoryclass"></a>
+## The TransientRepository class
+
+Jackrabbit comes with a [TransientRepository](http://jackrabbit.apache.org/api/1.5/org/apache/jackrabbit/core/TransientRepository.html)
+ class that makes it even easier to get started with a content repository.
+This class is especially handy for quick prototyping, but using the
+RepositoryImpl class as described above gives you better control over the
+repository lifecycle and is typically a better alternative for production
+code.
+
+{code:java}
+import javax.jcr.Repository;
+import org.apache.jackrabbit.core.TransientRepository;
+
+Repository repository = new TransientRepository();
+
+    
+    This creates a repository instance that starts up when the first session is
+created and automatically shuts down when the last session is closed. By
+default the repository will be created in a "jackrabbit" subdirectory using
+a default configuration file in "jackrabbit/repository.xml". See the
+TransientRepository javadocs for the ways to override these defaults.
+    
+    h2. Enabling remote access
+    
+    Even if you mostly use the content repository in embedded mode within your
+application, it may occasionally be useful to be able to access the
+repository for example from an external administration tool while your
+application is still running. You can use the jackrabbit-jcr-rmi library to
+make this possible. To do this, you first need to add the appropriate
+dependency.
+    
+    {code:xml}
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>jackrabbit-jcr-rmi</artifactId>
+      <version>1.5.0</version>
+    </dependency>
+
+
+Make sure that you have [rmiregistry](http://java.sun.com/j2se/1.5.0/docs/tooldocs/solaris/rmiregistry.html)
+ running, and use the following code to export the repository. Note that
+you need to include the JCR API and the jackrabbit-jcr-rmi libraries in the
+rmiregistry classpath for the binding to work without extra RMI codebase
+settings.
+
+{code:java}
+import java.rmi.Naming;
+import org.apache.jackrabbit.rmi.server.RemoteAdapterFactory;
+import org.apache.jackrabbit.rmi.server.RemoteRepository;
+import org.apache.jackrabbit.rmi.jackrabbit.JackrabbitRemoteAdapterFactory;
+
+String url = "//localhost/javax/jcr/Repository"; // RMI URL of the
+repository
+RemoteAdapterFactory factory = new JackrabbitRemoteAdapterFactory();
+RemoteRepository remote = factory.getRemoteRepository(repository);
+Naming.bind(url, remote);
+
+    
+    Use the following code to remote the repository binding from the RMI
+registry before you shutdown the repository.
+    
+    {code:java}
+    Naming.unbind(url);
+
+
+You need to keep a direct reference to the RemoteRepository instance in
+your code until you call Naming.unbind as otherwise it could get garbage
+collected before a remote client connects to it.
+
+See the [Repository Server](repository-server.html)
+ page for instructions on how to access such a remote repository.
+
+<a name="EmbeddedRepository-Embeddedrepositoryinawebapplication"></a>
+## Embedded repository in a web application
+
+If your want to embed Jackrabbit in a web application, you can use the
+classes in the jackrabbit-jcr-servlet library to avoid the above startup
+and shutdown code. To do this, you first need to include
+jackrabbit-jcr-servlet as a dependency.
+
+
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>jackrabbit-jcr-servlet</artifactId>
+      <version>1.5.0</version>
+    </dependency>
+
+
+Then you can instruct the servlet container to automatically start and stop
+the repository as a part of your webapp lifecycle by including the
+following servlet configuration in your web.xml file.
+
+
+    <servlet>
+        <servlet-name>ContentRepository</servlet-name>
+        <servlet-class>org.apache.jackrabbit.servlet.jackrabbit.JackrabbitRepositoryServlet</servlet-class>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
+
+See the [JackrabbitRepositoryServlet](http://jackrabbit.apache.org/api/1.5/org/apache/jackrabbit/servlet/jackrabbit/JackrabbitRepositoryServlet.html)
+ javadocs for the available configuration options.
+
+You can then access the repository in your own servlet classes using the
+following piece of code without worrying about the repository lifecycle.
+
+{code:java}
+import javax.jcr.Repository;
+import org.apache.jackrabbit.servlet.ServletRepository;
+
+Repository repository = new ServletRepository(this); // "this" is the
+containing servlet
+
+    
+    The benefit of this approach over directly using the RepositoryImpl or
+TransientRepository classes as described above is that you can later on
+switch to a different deployment model without any code changes simply by
+modifying the servlet configuration in your web.xml.
+    
+    With this approach it is also easier to make your repository remotely
+available. Add the following configuration to your web.xml and your
+repository is automatically made available as a remote repository at
+.../rmi in the URL space of your webapp.
+    
+    <servlet>
+        <servlet-name>RemoteRepository</servlet-name>
+        <servlet-class>org.apache.jackrabbit.servlet.remote.RemoteBindingServlet</servlet-class>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>RemoteRepository</servlet-name>
+        <url-pattern>/rmi</url-pattern>
+    </servlet-mapping>
+
+Note that you also need the jackrabbit-jcr-rmi dependency in your
+application for the above configuration to work.

Added: jackrabbit/site/trunk/src/site/markdown/first-hops-with-apache-jackrabbit.md
URL: http://svn.apache.org/viewvc/jackrabbit/site/trunk/src/site/markdown/first-hops-with-apache-jackrabbit.md?rev=1670829&view=auto
==============================================================================
--- jackrabbit/site/trunk/src/site/markdown/first-hops-with-apache-jackrabbit.md (added)
+++ jackrabbit/site/trunk/src/site/markdown/first-hops-with-apache-jackrabbit.md Thu Apr  2 07:13:56 2015
@@ -0,0 +1,634 @@
+Title: First Hops with Apache Jackrabbit
+Welcome to your first hops into the world of Apache 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="FirstHopswithApacheJackrabbit-Hop0:Gettingstarted"></a>
+## Hop 0: Getting started
+
+Before you can start using Jackrabbit, you need to have it installed on
+your computer. You can do this either by downloading a binary release and
+all the required dependencies or by building the Jackrabbit sources.
+
+Once you have Jackrabbit available locally, you should make sure that you
+have at least version 1.4 of the Java 2 Platform, Standard Edition (J2SE)
+installed and the following libraries configured in your Java classpath:
+
+    <table>
+    <tr><th> Library </th><th> Comments </th></tr>
+    <tr><td> jackrabbit-1.0.jar </td><td> depending on whether you use a binary release or a
+    locally compiled version </td></tr>
+    <tr><td> jcr-1.0.jar </td><td> for the JCR 1.0 API </td></tr>
+    <tr><td> slf4j-log4j12-1.0.jar and log4j-1.2.8.jar </td><td> for logging using SLF4J with
+    Log4J (you should be fine with any Log4J 1.2.x version, or you could even
+    replace both of these jars with another SLF4J implementation) </td></tr>
+    <tr><td> commons-collections-3.1.jar </td><td> for advanced data structures used by
+    Jackrabbit </td></tr>
+    <tr><td> xercesImpl-2.6.2.jar and xmlParserApis-2.0.2.jar </td><td> for advanced XML
+    support (you should be fine with any recent Xerces2 Java Parser
+    implementation and the extra XML API library is only needed for JDK 1.4) </td></tr>
+    <tr><td> derby-10.1.3.1.jar </td><td> or any recent Derby release for embedded database
+    storage </td></tr>
+    <tr><td> concurrent-1.3.4.jar </td><td> for advanced thread synchronization </td></tr>
+    <tr><td> lucene-1.4.3.jar </td><td> for full text indexing and searching </td></tr>
+    </table>
+
+You should also add the current directory in your classpath to make it easy
+to compile and run the example classes. You may also want to copy the
+following log4j.properties file to the current directory to avoid warnings
+of missing log configuration. If you want to see the internal Jackrabbit
+log, just change the log level to INFO or even DEBUG.
+
+    log4j.logger.org.apache.jackrabbit=WARN,stdout
+    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+    log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
+
+
+{tip}
+If you have build Jackrabbit from sources with Maven 1.x, you can get all
+the runtime dependencies (and some extra libraries) copied to target/lib by
+running maven copy-deps in the Jackrabbit project directory.
+{tip}
+
+{tip}
+You probably have an error in your classpath if you get a
+ClassNotFoundException message when trying to compile or run the examples
+below.
+{tip}
+
+<a name="FirstHopswithApacheJackrabbit-Hop1:LoggingintoJackrabbit"></a>
+## Hop 1: Logging in to Jackrabbit
+
+Once you are done with the setup tasks, we can start doing some real work.
+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.
+
+    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 interface represents a given content repository instance
+and the Session 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 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 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="FirstHopswithApacheJackrabbit-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.
+
+
+    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 class is a simple implementation of the Credentials
+interface used for passing explicit user credentials to the
+Repository.login(Credentials) method.
+
+    The Node interface is used to manage the content nodes in a repository.
+There is a related interface called Property 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
+represenenting 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 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 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="FirstHopswithApacheJackrabbit-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:
+
+        <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.
+
+    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 {
+    
+        /** Runs the ThirdHop example. */
+        public static void main(String[] args) throws Exception {
+            // Set up a Jackrabbit repository with the specified
+            // configuration file and repository directory
+            Repository repository = new TransientRepository();
+        
+            // Login to the default workspace as a dummy user
+            Session session = repository.login(
+                new SimpleCredentials("username", "password".toCharArray()));
+            try {
+                // Use the root node as a starting point
+                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( "/importxml", xml, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+                    xml.close();
+                    // Save the changes to the repository
+                    session.save();
+                    System.out.println("done.");
+                }
+        
+                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
+    /testnode
+    /testnode/jcr:primaryType=nt:unstructured
+    /testnode/testprop=Hello, World.
+    /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
+    .
+    .
+    .
+

Added: jackrabbit/site/trunk/src/site/markdown/first-hops.md
URL: http://svn.apache.org/viewvc/jackrabbit/site/trunk/src/site/markdown/first-hops.md?rev=1670829&view=auto
==============================================================================
--- jackrabbit/site/trunk/src/site/markdown/first-hops.md (added)
+++ jackrabbit/site/trunk/src/site/markdown/first-hops.md Thu Apr  2 07:13:56 2015
@@ -0,0 +1,720 @@
+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. 
+
+    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. 
+
+    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: 
+
+    <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. 
+
+    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)
+.

Added: jackrabbit/site/trunk/src/site/markdown/frequently-asked-questions.md
URL: http://svn.apache.org/viewvc/jackrabbit/site/trunk/src/site/markdown/frequently-asked-questions.md?rev=1670829&view=auto
==============================================================================
--- jackrabbit/site/trunk/src/site/markdown/frequently-asked-questions.md (added)
+++ jackrabbit/site/trunk/src/site/markdown/frequently-asked-questions.md Thu Apr  2 07:13:56 2015
@@ -0,0 +1,255 @@
+Title: Frequently Asked Questions
+## General
+
+### 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].
+
+### 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.
+
+### 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.
+
+### 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.
+
+
+## Building Jackrabbit
+
+### How do I build the Apache Jackrabbit sources?
+
+See the [Building Jackrabbit](building-jackrabbit.html)
+ page for detailed build instructions.
+
+## Using Jackrabbit
+
+### 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.
+
+### 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.
+
+### 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.
+
+### 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.
+
+### 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>`
+
+## 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.
+
+### 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.
+
+
+## Persistence managers
+
+### 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.
+
+### 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).
+
+### 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).
+
+### 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.
+
+## 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')]
+
+
+### 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}
+
+### 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.
+
+### 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.

Added: jackrabbit/site/trunk/src/site/markdown/getting-started-with-apache-jackrabbit.md
URL: http://svn.apache.org/viewvc/jackrabbit/site/trunk/src/site/markdown/getting-started-with-apache-jackrabbit.md?rev=1670829&view=auto
==============================================================================
--- jackrabbit/site/trunk/src/site/markdown/getting-started-with-apache-jackrabbit.md (added)
+++ jackrabbit/site/trunk/src/site/markdown/getting-started-with-apache-jackrabbit.md Thu Apr  2 07:13:56 2015
@@ -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.

Added: jackrabbit/site/trunk/src/site/markdown/how-jackrabbit-works.md
URL: http://svn.apache.org/viewvc/jackrabbit/site/trunk/src/site/markdown/how-jackrabbit-works.md?rev=1670829&view=auto
==============================================================================
--- jackrabbit/site/trunk/src/site/markdown/how-jackrabbit-works.md (added)
+++ jackrabbit/site/trunk/src/site/markdown/how-jackrabbit-works.md Thu Apr  2 07:13:56 2015
@@ -0,0 +1,46 @@
+Title: How Jackrabbit works
+The diagram on the left explains which components of the Jackrabbit are
+used when a user of the JCR API modified content in the content repository.
+This is a simple and very common operation, that touches a large portion of
+the components in the Jackrabbit implementation. Please keep in mind that
+this implementation architecture is not mandated by JCR, but has been
+designed from scratch based on JCR.
+
+{center}!jackrabbit-ism_small.jpg!{center}
+
+The used components and their respective functions in the order of their
+appearance in the use case of writing or modifying content in the content
+repository:
+
+* *Transient Item State Manager* Once content items are read by a session
+they are cached in the Transient Item State Manager. When those items are
+modified the modification is only visible to that same session, in the
+so-called "transient" space.
+* *Transactional Item State Manager* When the Application persists the
+modified items using the JCR Item.save() or Session.save() the transient
+Items are promoted into the Transactional ISM. The modifications are still
+only visible within the scope of this transaction, meaning that other
+sessions will not see the modification until they are committed. The commit
+is implicit if the Content Repository is not running in an XA environment.
+* *Shared Item State Manager* Once a transaction is committed the Shared
+Item State Manager receives the changelog and publishes the changes to all
+the sessions logged into the same workspace. This means that all the Item
+States that are cached and referenced by other sessions are notified and
+possibly updated or invalidated. The Shared Item State Manager also
+triggers the observation and hands the changelog over to the persistence
+manager that is configured for this workspace.
+* *Persistence Manager* The Persistence Manager persists all the Item
+States in the changelog passed by the Shared ISM. The persistence manager
+is a very simple, fast and transactional interface that is very low-level
+and does not need to understand the complexities of the repository
+operations, but basically just needs to be able persist and retrieve a
+given item based on its item id.
+* *Observation* When a transaction is committed the Shared Item State
+Manager triggers the Observation mechanism. This allows applications to
+asynchronously subscribe changes in the workspace. Jackrabbit also
+non-standard offers a synchronous observation.
+* *Query Manager / Index* Through a synchronous observation event the Query
+Manager is instructed to index the new or modified items. A content
+repository index is much more complex than a classical RDB index since it
+deals with content repository features like the item hierarchy, nodetype
+inheritance or fulltext searches.



Mime
View raw message