You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by at...@apache.org on 2012/08/27 13:23:20 UTC

svn commit: r1377645 - in /rave/sandbox/content-services: ./ demo-portal/ demo-portal/src/main/webapp/WEB-INF/ rave-jcr-config/ rave-jcr-config/src/main/java/org/apache/jackrabbit/core/ rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ r...

Author: ate
Date: Mon Aug 27 11:23:18 2012
New Revision: 1377645

URL: http://svn.apache.org/viewvc?rev=1377645&view=rev
Log:
RAVE-603: System bootstrap for jcr content services
- restructured initialization logic and order moving content services bootstrapping to a separate and standalone feature (no longer depending/needing jackrabbit classes nor classloader)
- wiring repository initialization and usage through new LazyRepositoryFactory with callback listeners to be invoked in order (of registration) when repository becomes available (and is shutdown)
  wiring now no longer is initialized through servlets (web.xml) but can be plugged in and managed through spring configuration only

Added:
    rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/Bootstrap.java   (with props)
    rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/RaveBoostrap.java   (with props)
    rave/sandbox/content-services/rave-jcr-integration/test/src/test/resources/repositoryStubImpl.properties
      - copied, changed from r1376541, rave/sandbox/content-services/rave-jcr-integration/test/src/test/resources/repositoryStubImpl.properties
    rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/LazyRepositoryFactory.java   (with props)
    rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/LazyRepositoryFactoryListener.java   (with props)
    rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/servlet/ServletContextRepositoryFactory.java   (with props)
    rave/sandbox/content-services/rave-jcr/src/main/java/
    rave/sandbox/content-services/rave-jcr/src/main/java/org/
    rave/sandbox/content-services/rave-jcr/src/main/java/org/apache/
    rave/sandbox/content-services/rave-jcr/src/main/java/org/apache/rave/
    rave/sandbox/content-services/rave-jcr/src/main/java/org/apache/rave/jcr/
    rave/sandbox/content-services/rave-jcr/src/main/java/org/apache/rave/jcr/jackrabbit/
      - copied from r1376541, rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/servlet/jackrabbit/
Removed:
    rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/jackrabbit/core/
    rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/jackrabbit/
    rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/servlet/jackrabbit/
    rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/config/
    rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/jackrabbit/
    rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/servlet/ContextRepositoryServlet.java
Modified:
    rave/sandbox/content-services/demo-portal/pom.xml
    rave/sandbox/content-services/demo-portal/src/main/webapp/WEB-INF/dispatcher-servlet.xml
    rave/sandbox/content-services/demo-portal/src/main/webapp/WEB-INF/web.xml
    rave/sandbox/content-services/pom.xml
    rave/sandbox/content-services/rave-jcr-config/pom.xml
    rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/test/AbstractRaveJCRTest.java
    rave/sandbox/content-services/rave-jcr-integration/test/src/test/java/org/apache/rave/jcr/RaveRepositoryTest.java
    rave/sandbox/content-services/rave-jcr-service/pom.xml
    rave/sandbox/content-services/rave-jcr/pom.xml
    rave/sandbox/content-services/rave-jcr/src/main/java/org/apache/rave/jcr/jackrabbit/JackrabbitRepositoryServlet.java
    rave/sandbox/content-services/rave-jcr/src/main/webapp/WEB-INF/web.xml
    rave/sandbox/content-services/rave-web-hmvc/pom.xml
    rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/hmvc/HmvcHandlerMethodMappingByConfig.java

Modified: rave/sandbox/content-services/demo-portal/pom.xml
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/demo-portal/pom.xml?rev=1377645&r1=1377644&r2=1377645&view=diff
==============================================================================
--- rave/sandbox/content-services/demo-portal/pom.xml (original)
+++ rave/sandbox/content-services/demo-portal/pom.xml Mon Aug 27 11:23:18 2012
@@ -99,6 +99,11 @@
     </dependency>
     <dependency>
       <groupId>org.apache.rave.sandbox.jcr</groupId>
+      <artifactId>rave-jcr-config</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.rave.sandbox.jcr</groupId>
       <artifactId>rave-jcr-service</artifactId>
       <version>${project.version}</version>
     </dependency>
@@ -179,6 +184,7 @@
             </properties>
             <home>${project.build.directory}/tomcat6x</home>
             <deployables>
+              <!-- disabled for development speed-up
               <deployable>
                 <groupId>org.apache.wookie</groupId>
                 <artifactId>wookie</artifactId>
@@ -189,6 +195,15 @@
               </deployable>
               <deployable>
                 <groupId>org.apache.rave</groupId>
+                <artifactId>rave-demo-gadgets</artifactId>
+                <type>war</type>
+                <properties>
+                  <context>/demogadgets</context>
+                </properties>
+              </deployable>
+              -->
+              <deployable>
+                <groupId>org.apache.rave</groupId>
                 <artifactId>rave-shindig</artifactId>
                 <type>war</type>
                 <properties>
@@ -212,14 +227,6 @@
                 </properties>
               </deployable>
               <deployable>
-                <groupId>org.apache.rave</groupId>
-                <artifactId>rave-demo-gadgets</artifactId>
-                <type>war</type>
-                <properties>
-                  <context>/demogadgets</context>
-                </properties>
-              </deployable>
-              <deployable>
                 <groupId>org.apache.rave.sandbox.jcr</groupId>
                 <artifactId>rave-demo-portal</artifactId>
                 <type>war</type>

Modified: rave/sandbox/content-services/demo-portal/src/main/webapp/WEB-INF/dispatcher-servlet.xml
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/demo-portal/src/main/webapp/WEB-INF/dispatcher-servlet.xml?rev=1377645&r1=1377644&r2=1377645&view=diff
==============================================================================
--- rave/sandbox/content-services/demo-portal/src/main/webapp/WEB-INF/dispatcher-servlet.xml (original)
+++ rave/sandbox/content-services/demo-portal/src/main/webapp/WEB-INF/dispatcher-servlet.xml Mon Aug 27 11:23:18 2012
@@ -136,13 +136,12 @@
     </bean>
   -->
 
-  <!-- JCR LOADING -->
-  <bean name="hmvcHandlerMappingByConfig" class="org.apache.rave.portal.web.hmvc.HmvcHandlerMethodMappingByConfig">
-    <property name="order" value="-1"/>
-    <property name="configurationName" value="myConfiguration"/>
-    <property name="configurationPath" value="/raveconfig"/>
-    <property name="configManager" ref="fileConfigurationManager"/>
-    <property name="credentials" ref="jcrCredentials"/>
+  <bean name="lazyRepositoryFactory" class="org.apache.rave.jcr.LazyRepositoryFactory">
+    <constructor-arg>
+      <bean class="org.apache.rave.jcr.servlet.ServletContextRepositoryFactory">
+        <constructor-arg value="#{servletContext}"/>
+      </bean>
+    </constructor-arg>
   </bean>
 
   <!-- JCR LOGIN -->
@@ -151,6 +150,25 @@
     <constructor-arg index="1" value="admin"/>
   </bean>
 
+  <!--JCR Bootstrap -->
+  <bean name="repositoryBootstrap" class="org.apache.rave.jcr.bootstrapping.RaveBoostrap" destroy-method="shutdown">
+    <constructor-arg index="0" value="#{servletContext}"/>
+    <constructor-arg index="1" ref="lazyRepositoryFactory"/>
+    <constructor-arg index="2" ref="jcrCredentials"/>
+    <constructor-arg index="3" value="default"/>
+    <constructor-arg index="4" value="true"/>
+  </bean>
+
+  <!-- JCR LOADING -->
+  <bean name="hmvcHandlerMappingByConfig" class="org.apache.rave.portal.web.hmvc.HmvcHandlerMethodMappingByConfig" depends-on="repositoryBootstrap" destroy-method="shutdown">
+    <property name="order" value="-1"/>
+    <property name="configurationName" value="myConfiguration"/>
+    <property name="configurationPath" value="/raveconfig"/>
+    <property name="configManager" ref="fileConfigurationManager"/>
+    <property name="credentials" ref="jcrCredentials"/>
+    <property name="lazyRepositoryFactory" ref="lazyRepositoryFactory"/>
+  </bean>
+
   <bean id="fileConfigurationManager" class="org.apache.rave.jcr.config.FileConfigManager"/>
 
   <bean name="hmvcHandlerMapping" class="org.apache.rave.portal.web.hmvc.HmvcHandlerMethodMapping">

Modified: rave/sandbox/content-services/demo-portal/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/demo-portal/src/main/webapp/WEB-INF/web.xml?rev=1377645&r1=1377644&r2=1377645&view=diff
==============================================================================
--- rave/sandbox/content-services/demo-portal/src/main/webapp/WEB-INF/web.xml (original)
+++ rave/sandbox/content-services/demo-portal/src/main/webapp/WEB-INF/web.xml Mon Aug 27 11:23:18 2012
@@ -27,41 +27,6 @@
 
   <display-name>Rave Demo Portal</display-name>
 
-  <servlet>
-    <servlet-name>Repository</servlet-name>
-    <servlet-class>org.apache.rave.jcr.servlet.jackrabbit.JackrabbitRepositoryServlet</servlet-class>
-    <!--
-        <init-param>
-          <description>The Servlet context attribute name under which to expose the repository.
-          Default value is javax.jcr.Repository if undefined.
-          Also, this parameter can be overriden with a system property named 'repository.context.attribute'.</description>
-          <param-name>repository.context.attribute</param-name>
-          <param-value>javax.jcr.Repository</param-value>
-        </init-param>
-    -->
-    <init-param>
-      <description>The location for the repository files. Unless the location starts
-        with file: or /, the location is resolved as context relative.
-        Also, this parameter can be overriden with a system property named 'repository.home'.
-      </description>
-      <param-name>repository.home</param-name>
-      <param-value>WEB-INF/storage</param-value>
-    </init-param>
-    <!--
-        <init-param>
-          <description>The location of the repository configuration file. Unless the location
-          starts with file: or /, the location is resolved as context relative.
-          Also, this parameter can be overriden with a system property named 'repository.config'.
-          If undefined, the default is to lookup or create a repository.xml file under the repository.home location.
-          </description>
-          <param-name>repository.config</param-name>
-          <param-value>WEB-INF/repository.xml</param-value>
-        </init-param>
-    -->
-    <load-on-startup>0</load-on-startup>
-  </servlet>
-
-
   <context-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>
@@ -75,34 +40,27 @@
     <listener-class>org.apache.rave.portal.web.context.RaveContextLoaderListener</listener-class>
   </listener>
 
-  <!-- Filter to ensure Content Repository is loaded -->
+  <!-- Filter to ensure Content Repository is loaded
   <filter>
     <filter-name>contentRepositoryAvailableFilter</filter-name>
     <filter-class>org.apache.rave.jcr.servlet.ContextRepositoryAvailableFilter</filter-class>
   </filter>
-
+-->
   <filter>
     <filter-name>springSecurityFilterChain</filter-name>
     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
   </filter>
-
+<!--
   <filter-mapping>
     <filter-name>contentRepositoryAvailableFilter</filter-name>
     <url-pattern>/jcr/*</url-pattern>
   </filter-mapping>
-
+-->
   <filter-mapping>
     <filter-name>springSecurityFilterChain</filter-name>
     <url-pattern>/*</url-pattern>
   </filter-mapping>
 
-  <!-- Exposes rave-jcr content repository -->
-  <servlet>
-    <servlet-name>contextRepository</servlet-name>
-    <servlet-class>org.apache.rave.jcr.servlet.ContextRepositoryServlet</servlet-class>
-    <load-on-startup>1</load-on-startup>
-  </servlet>
-
   <!-- Handles all + hmvc requests into the application -->
   <servlet>
     <servlet-name>dispatcher</servlet-name>
@@ -110,12 +68,6 @@
     <load-on-startup>1</load-on-startup>
   </servlet>
 
-  <!-- temporary exposure of ContextRepositoryServlet to show dynamic access to repository descriptor values -->
-  <servlet-mapping>
-    <servlet-name>contextRepository</servlet-name>
-    <url-pattern>/jcr/*</url-pattern>
-  </servlet-mapping>
-
   <servlet-mapping>
     <servlet-name>dispatcher</servlet-name>
     <url-pattern>/app/*</url-pattern>

Modified: rave/sandbox/content-services/pom.xml
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/pom.xml?rev=1377645&r1=1377644&r2=1377645&view=diff
==============================================================================
--- rave/sandbox/content-services/pom.xml (original)
+++ rave/sandbox/content-services/pom.xml Mon Aug 27 11:23:18 2012
@@ -53,6 +53,7 @@
     <el-api.version>1.0</el-api.version>
     <javax.mail.version>1.4.4</javax.mail.version>
     <javax.activation.version>1.1</javax.activation.version>
+    <commons-io.version>1.4</commons-io.version>
 
     <easymock.version>3.0</easymock.version>
     <jackson.version>2.0.0</jackson.version>

Modified: rave/sandbox/content-services/rave-jcr-config/pom.xml
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/pom.xml?rev=1377645&r1=1377644&r2=1377645&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/pom.xml (original)
+++ rave/sandbox/content-services/rave-jcr-config/pom.xml Mon Aug 27 11:23:18 2012
@@ -58,25 +58,26 @@
       <version>${apache.jackrabbit.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.apache.jackrabbit</groupId>
-      <artifactId>jackrabbit-spi-commons</artifactId>
-      <version>${apache.jackrabbit.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.jackrabbit</groupId>
-      <artifactId>jackrabbit-jcr-servlet</artifactId>
-      <version>${apache.jackrabbit.version}</version>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <version>${commons-io.version}</version>
     </dependency>
     <dependency>
       <groupId>org.apache.jackrabbit</groupId>
       <artifactId>jackrabbit-core</artifactId>
       <version>${apache.jackrabbit.version}</version>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.rave.sandbox.jcr</groupId>
       <artifactId>rave-jcr-utils</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.rave.sandbox.jcr</groupId>
+      <artifactId>rave-jcr-service</artifactId>
+      <version>${project.version}</version>
+    </dependency>
 
     <!-- Test -->
     <dependency>

Added: rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/Bootstrap.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/Bootstrap.java?rev=1377645&view=auto
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/Bootstrap.java (added)
+++ rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/Bootstrap.java Mon Aug 27 11:23:18 2012
@@ -0,0 +1,201 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*   http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied.  See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+package org.apache.rave.jcr.bootstrapping;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import javax.jcr.Credentials;
+import javax.jcr.NamespaceException;
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Workspace;
+import javax.servlet.ServletContext;
+
+import org.apache.rave.jcr.LazyRepositoryFactory;
+import org.apache.rave.jcr.LazyRepositoryFactoryListener;
+import org.apache.rave.jcr.importing.MimeTypeResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Bootstrap implements LazyRepositoryFactoryListener {
+
+    private static final Logger log = LoggerFactory.getLogger(Bootstrap.class);
+
+    private ServletContext servletContext;
+    private LazyRepositoryFactory repositoryFactory;
+    private Credentials credentials;
+    private String workspaceName;
+    private boolean reload;
+    private String namespacePrefix;
+    private String namespaceUri;
+    private boolean bootstrapped;
+
+    public Bootstrap(final ServletContext servletContext, LazyRepositoryFactory repositoryFactory, final Credentials credentials, final String workspaceName,
+                     final boolean reload, final String namespacePrefix, final String namespaceUri) throws RepositoryException, BootstrapException {
+
+        this.servletContext = servletContext;
+        this.repositoryFactory = repositoryFactory;
+        this.credentials = credentials;
+        this.workspaceName = workspaceName;
+        this.reload = reload;
+        this.namespacePrefix = namespacePrefix;
+        this.namespaceUri = namespaceUri;
+        Repository repository = repositoryFactory.getRepository(this);
+        if (repository != null) {
+            repositoryAvailable(repositoryFactory.getFactoryKey(), repository);
+        }
+    }
+
+    @Override
+    public synchronized void repositoryAvailable(final Object factoryKey, final Repository repository) {
+        if (!bootstrapped) {
+            bootstrapped = true;
+            try {
+                Session session = getSession(repository, credentials, workspaceName);
+                initializeSystem(session, namespacePrefix, namespaceUri);
+                updateModules(session, namespacePrefix);
+                importModules(servletContext, repository, session, credentials, reload, namespacePrefix);
+            }
+            catch (Exception e) {
+                log.error("Failure bootstrapping", e);
+            }
+        }
+    }
+
+    @Override
+    public void repositoryNotAvailable(final Object factoryKey) {
+    }
+
+    public void shutdown() {
+        repositoryFactory.removeListener(this);
+    }
+
+    protected void initializeSystem(Session session, String namespacePrefix, String namespaceUri) throws RepositoryException {
+        try {
+            try {
+                session.getWorkspace().getNamespaceRegistry().registerNamespace(namespacePrefix, namespaceUri);
+            }
+            catch (NamespaceException ignore) {}
+            Node system;
+            if (!session.nodeExists("/" + namespacePrefix + ":system")) {
+                system = session.getRootNode().addNode(namespacePrefix + ":system");
+            }
+            else {
+                system = session.getNode("/" + namespacePrefix + ":system");
+            }
+            if (!system.hasNode("modules")) {
+                system.addNode("modules");
+                session.save();
+            }
+        } finally {
+            session.refresh(false);
+        }
+    }
+
+    protected void updateModules(Session session, String namespacePrefix) throws RepositoryException, BootstrapException {
+        try {
+            final ModuleScanner moduleScanner = new ModuleScanner(namespacePrefix);
+            final ModuleRegistry moduleRegistry = new ModuleRegistry(session, "/" + namespacePrefix + ":system");
+            final Map<String, Module> current = moduleScanner.scan();
+
+            final Map<String, Module> previous = moduleRegistry.readModules();
+
+            final Collection<Module> added = getAddedModules(current, previous);
+            for (Module module : added) {
+                moduleRegistry.writeModule(module);
+            }
+
+            for (Map.Entry<String, Module> entry : previous.entrySet()) {
+                if (current.containsKey(entry.getKey())) {
+                    moduleRegistry.updateModule(current.get(entry.getKey()), entry.getValue());
+                }
+            }
+        } finally {
+            session.refresh(false);
+        }
+    }
+
+    protected void importModules(final ServletContext servletContext, final Repository repository, Session session,
+                                 final Credentials credentials, boolean reload, String namespacePrefix) throws RepositoryException, BootstrapException {
+        try {
+            final ModuleRegistry moduleRegistry = new ModuleRegistry(session, "/" + namespacePrefix + ":system");
+            final Map<String, Module> moduleMap = moduleRegistry.readModules();
+            final ModuleImporter importer = new ModuleImporter(new SessionProvider() {
+                @Override
+                public Session getSession(String workspaceName) throws RepositoryException {
+                    return repository.login(credentials, workspaceName);
+                }
+            }, moduleRegistry, moduleMap.values(), reload, new MimeTypeResolver() {
+                @Override
+                public String getMimeType(final String file) {
+                    return servletContext.getMimeType(file);
+                }
+            });
+            importer.prepare();
+            importer.execute();
+        } finally {
+            session.refresh(false);
+        }
+    }
+
+    protected Session getSession(Repository repository, Credentials credentials, String targetWorkspaceName) throws RepositoryException {
+        Session defaultWorkspaceSession = repository.login(credentials);
+        Session targetWorkspaceSession = defaultWorkspaceSession;
+        try {
+            Workspace defaultWorkspace = defaultWorkspaceSession.getWorkspace();
+            if (defaultWorkspace.getName().equals(targetWorkspaceName)) {
+                // don't logout: matching default workspace
+                defaultWorkspaceSession = null;
+            }
+            else {
+                for (String name : defaultWorkspace.getAccessibleWorkspaceNames()) {
+                    if (name.equals(targetWorkspaceName)) {
+                        // target workspace already exists, no longer need defaultWorkspace
+                        defaultWorkspace = null;
+                        break;
+                    }
+                }
+                if (defaultWorkspace != null) {
+                    defaultWorkspace.createWorkspace(targetWorkspaceName);
+                }
+                targetWorkspaceSession = repository.login(credentials, targetWorkspaceName);
+            }
+        }
+        finally {
+            if (defaultWorkspaceSession != null) {
+                defaultWorkspaceSession.logout();
+            }
+        }
+        return targetWorkspaceSession;
+    }
+
+    private static Collection<Module> getAddedModules(Map<String, Module> current, Map<String, Module> previous) {
+        Collection<Module> added = new ArrayList<Module>();
+        for (String moduleName : current.keySet()) {
+            if (!previous.containsKey(moduleName)) {
+                added.add(current.get(moduleName));
+            }
+        }
+        return added;
+    }
+}

Propchange: rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/Bootstrap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/Bootstrap.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/RaveBoostrap.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/RaveBoostrap.java?rev=1377645&view=auto
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/RaveBoostrap.java (added)
+++ rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/RaveBoostrap.java Mon Aug 27 11:23:18 2012
@@ -0,0 +1,35 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*   http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied.  See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+package org.apache.rave.jcr.bootstrapping;
+
+import javax.jcr.Credentials;
+import javax.jcr.RepositoryException;
+import javax.servlet.ServletContext;
+
+import org.apache.rave.jcr.LazyRepositoryFactory;
+
+public class RaveBoostrap extends Bootstrap {
+    public static String RAVE_NAMESPACE_PREFIX = "rave";
+    public static String RAVE_NAMESPACE_URI = "http://rave.apache.org/jcr/1.0";
+
+    public RaveBoostrap(ServletContext servletContext, LazyRepositoryFactory repositoryFactory, Credentials credentials,
+                          String workspaceName, boolean reload) throws RepositoryException, BootstrapException {
+        super(servletContext, repositoryFactory, credentials, workspaceName, reload, RAVE_NAMESPACE_PREFIX, RAVE_NAMESPACE_URI);
+    }
+}

Propchange: rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/RaveBoostrap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/RaveBoostrap.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/test/AbstractRaveJCRTest.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/test/AbstractRaveJCRTest.java?rev=1377645&r1=1377644&r2=1377645&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/test/AbstractRaveJCRTest.java (original)
+++ rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/test/AbstractRaveJCRTest.java Mon Aug 27 11:23:18 2012
@@ -1,15 +1,27 @@
 package org.apache.rave.jcr.test;
 
 import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.Set;
 
 import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
 import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
 
 import org.apache.jackrabbit.test.AbstractJCRTest;
+import org.apache.rave.jcr.LazyRepositoryFactory;
 import org.apache.rave.jcr.importing.ContentImporter;
 import org.apache.rave.jcr.importing.ImportBehavior;
-import org.apache.rave.jcr.jackrabbit.RaveRepositoryImpl;
-import org.apache.rave.jcr.jackrabbit.RaveRepositoryStub;
+import org.apache.rave.jcr.bootstrapping.RaveBoostrap;
 
 /**
  * Abstract base class for tests that want to run against a rave-bootstrapped repository.
@@ -24,11 +36,9 @@ public abstract class AbstractRaveJCRTes
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        final Repository repository = getHelper().getRepository();
-        if (!(repository instanceof RaveRepositoryImpl)) {
-            throw new IllegalStateException("Expected a RaveRepositoryImpl: make sure you are using " + RaveRepositoryStub.class.getName());
-        }
-        ((RaveRepositoryImpl) repository).bootstrap(false);
+        Repository repository = getHelper().getRepository();
+        new RaveBoostrap(new MockServletContext(), new LazyRepositoryFactory(new SimpleRepositoryFactory(repository)),
+                new SimpleCredentials("admin", "admin".toCharArray()), "default", false);
     }
 
     /**
@@ -45,4 +55,142 @@ public abstract class AbstractRaveJCRTes
         importer.importContent("/testroot", nodeName, content, ImportBehavior.REPLACE);
         session.save();
     }
+
+    private static class SimpleRepositoryFactory implements RepositoryFactory {
+
+        private Repository repository;
+
+        public SimpleRepositoryFactory(Repository repository) {
+            this.repository = repository;
+        }
+        @Override
+        public Repository getRepository(final Map parameters) throws RepositoryException {
+            return repository;
+        }
+    }
+
+
+    private static class MockServletContext implements ServletContext {
+
+        @Override
+        public String getContextPath() {
+            return null;
+        }
+
+        @Override
+        public ServletContext getContext(final String s) {
+            return null;
+        }
+
+        @Override
+        public int getMajorVersion() {
+            return 0;
+        }
+
+        @Override
+        public int getMinorVersion() {
+            return 0;
+        }
+
+        @Override
+        public String getMimeType(final String file) {
+            return null;
+        }
+
+        @Override
+        public Set getResourcePaths(final String s) {
+            return null;
+        }
+
+        @Override
+        public URL getResource(final String s) throws MalformedURLException {
+            return null;
+        }
+
+        @Override
+        public InputStream getResourceAsStream(final String s) {
+            return null;
+        }
+
+        @Override
+        public RequestDispatcher getRequestDispatcher(final String s) {
+            return null;
+        }
+
+        @Override
+        public RequestDispatcher getNamedDispatcher(final String s) {
+            return null;
+        }
+
+        @Override
+        public Servlet getServlet(final String s) throws ServletException {
+            return null;
+        }
+
+        @Override
+        public Enumeration getServlets() {
+            return null;
+        }
+
+        @Override
+        public Enumeration getServletNames() {
+            return null;
+        }
+
+        @Override
+        public void log(final String s) {
+        }
+
+        @Override
+        public void log(final Exception e, final String s) {
+        }
+
+        @Override
+        public void log(final String s, final Throwable throwable) {
+        }
+
+        @Override
+        public String getRealPath(final String s) {
+            return null;
+        }
+
+        @Override
+        public String getServerInfo() {
+            return null;
+        }
+
+        @Override
+        public String getInitParameter(final String s) {
+            return null;
+        }
+
+        @Override
+        public Enumeration getInitParameterNames() {
+            return null;
+        }
+
+        @Override
+        public Object getAttribute(final String s) {
+            return null;
+        }
+
+        @Override
+        public Enumeration getAttributeNames() {
+            return null;
+        }
+
+        @Override
+        public void setAttribute(final String s, final Object o) {
+        }
+
+        @Override
+        public void removeAttribute(final String s) {
+        }
+
+        @Override
+        public String getServletContextName() {
+            return null;
+        }
+
+    }
 }

Modified: rave/sandbox/content-services/rave-jcr-integration/test/src/test/java/org/apache/rave/jcr/RaveRepositoryTest.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-integration/test/src/test/java/org/apache/rave/jcr/RaveRepositoryTest.java?rev=1377645&r1=1377644&r2=1377645&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr-integration/test/src/test/java/org/apache/rave/jcr/RaveRepositoryTest.java (original)
+++ rave/sandbox/content-services/rave-jcr-integration/test/src/test/java/org/apache/rave/jcr/RaveRepositoryTest.java Mon Aug 27 11:23:18 2012
@@ -5,10 +5,9 @@ import javax.jcr.Node;
 import javax.jcr.Property;
 import javax.jcr.Session;
 
-import org.apache.jackrabbit.test.AbstractJCRTest;
-import org.apache.rave.jcr.jackrabbit.RaveRepositoryImpl;
+import org.apache.rave.jcr.test.AbstractRaveJCRTest;
 
-public class RaveRepositoryTest extends AbstractJCRTest {
+public class RaveRepositoryTest extends AbstractRaveJCRTest {
 
     @Override
     public void tearDown() throws Exception {
@@ -25,7 +24,7 @@ public class RaveRepositoryTest extends 
 
     public void testBootstrap() throws Exception {
         Session session = getHelper().getReadOnlySession();
-        ((RaveRepositoryImpl) session.getRepository()).bootstrap(false);
+//        ((RaveRepositoryImpl) session.getRepository()).bootstrap(false);
 
         assertTrue(session.nodeExists("/testroot/foo"));
         final Node foo = session.getNode("/testroot/foo");

Copied: rave/sandbox/content-services/rave-jcr-integration/test/src/test/resources/repositoryStubImpl.properties (from r1376541, rave/sandbox/content-services/rave-jcr-integration/test/src/test/resources/repositoryStubImpl.properties)
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-integration/test/src/test/resources/repositoryStubImpl.properties?p2=rave/sandbox/content-services/rave-jcr-integration/test/src/test/resources/repositoryStubImpl.properties&p1=rave/sandbox/content-services/rave-jcr-integration/test/src/test/resources/repositoryStubImpl.properties&r1=1376541&r2=1377645&rev=1377645&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr-integration/test/src/test/resources/repositoryStubImpl.properties (original)
+++ rave/sandbox/content-services/rave-jcr-integration/test/src/test/resources/repositoryStubImpl.properties Mon Aug 27 11:23:18 2012
@@ -14,4 +14,4 @@
 #  limitations under the License.
 
 # Stub implementation class
-javax.jcr.tck.repository_stub_impl=org.apache.rave.jcr.jackrabbit.RaveRepositoryStub
+javax.jcr.tck.repository_stub_impl=org.apache.jackrabbit.core.JackrabbitRepositoryStub

Modified: rave/sandbox/content-services/rave-jcr-service/pom.xml
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-service/pom.xml?rev=1377645&r1=1377644&r2=1377645&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr-service/pom.xml (original)
+++ rave/sandbox/content-services/rave-jcr-service/pom.xml Mon Aug 27 11:23:18 2012
@@ -36,12 +36,6 @@
   <packaging>jar</packaging>
 
   <dependencies>
-
-    <dependency>
-      <groupId>org.apache.jackrabbit</groupId>
-      <artifactId>jackrabbit-jcr-servlet</artifactId>
-      <version>${apache.jackrabbit.version}</version>
-    </dependency>
   </dependencies>
 
 </project>

Added: rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/LazyRepositoryFactory.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/LazyRepositoryFactory.java?rev=1377645&view=auto
==============================================================================
--- rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/LazyRepositoryFactory.java (added)
+++ rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/LazyRepositoryFactory.java Mon Aug 27 11:23:18 2012
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rave.jcr;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+
+public class LazyRepositoryFactory implements RepositoryFactory {
+
+    private static volatile int nextFactoryKey = 0;
+
+    private final Integer factoryKey;
+    private final RepositoryFactory factory;
+    private final LinkedList<LazyRepositoryFactoryListener> listeners = new LinkedList<LazyRepositoryFactoryListener>();
+
+    private Repository repository;
+
+    public LazyRepositoryFactory(RepositoryFactory factory) {
+        synchronized (listeners) {
+            factoryKey = new Integer(nextFactoryKey++);
+        }
+        this.factory = factory;
+    }
+
+    public Object getFactoryKey() {
+        return factoryKey;
+    }
+
+    public void addListener(LazyRepositoryFactoryListener listener) {
+        synchronized (listeners) {
+            if (this != listener && !listeners.contains(listener)) {
+                listeners.add(listener);
+            }
+        }
+    }
+
+    public void removeListener(LazyRepositoryFactoryListener listener) {
+        synchronized (listeners) {
+            listeners.remove(listener);
+        }
+    }
+
+    @Override
+    public Repository getRepository(final Map parameters) throws RepositoryException {
+        return getRepository();
+    }
+
+    public Repository getRepository() {
+        return getRepository((LazyRepositoryFactoryListener)null);
+    }
+
+    public Repository getRepository(LazyRepositoryFactoryListener listener) {
+        synchronized (listeners) {
+            try {
+                Repository checkRepository = factory.getRepository(null);
+                if (checkRepository != null && checkRepository.getDescriptor(Repository.SPEC_VERSION_DESC) != null) {
+                    // repository available
+                    if (repository == null) {
+                        // notify repository available
+                        repository = checkRepository;
+                        notifyRepositoryAvailable(listener);
+                    }
+                }
+                else {
+                    if (repository != null) {
+                        repository = null;
+                        // notify repository no longer available
+                        notifyRepositoryNotAvailable();
+                    }
+                }
+            }
+            catch (RepositoryException e) {
+                if (repository != null) {
+                    repository = null;
+                    // notify repository no longer available
+                    notifyRepositoryNotAvailable();
+                }
+            }
+            addListener(listener);
+            return repository;
+        }
+    }
+
+    protected void notifyRepositoryAvailable(LazyRepositoryFactoryListener current) {
+        LazyRepositoryFactoryListener[] la = listeners.toArray(new LazyRepositoryFactoryListener[listeners.size()]);
+        for (LazyRepositoryFactoryListener listener : la) {
+            if (current == null || !current.equals(listener))
+            try {
+                listener.repositoryAvailable(factoryKey, repository);
+            }
+            catch (Throwable t) {
+                // TODO: log
+            }
+        }
+    }
+
+    protected void notifyRepositoryNotAvailable() {
+        LazyRepositoryFactoryListener[] la = listeners.toArray(new LazyRepositoryFactoryListener[listeners.size()]);
+        for (int i = la.length -1; i > -1 ; i--) {
+            try {
+                la[i].repositoryNotAvailable(factoryKey);
+            }
+            catch (Throwable t) {
+                // TODO: log
+            }
+        }
+    }
+}

Propchange: rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/LazyRepositoryFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/LazyRepositoryFactory.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/LazyRepositoryFactoryListener.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/LazyRepositoryFactoryListener.java?rev=1377645&view=auto
==============================================================================
--- rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/LazyRepositoryFactoryListener.java (added)
+++ rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/LazyRepositoryFactoryListener.java Mon Aug 27 11:23:18 2012
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rave.jcr;
+
+import javax.jcr.Repository;
+
+public interface LazyRepositoryFactoryListener {
+    void repositoryAvailable(Object factoryKey, Repository repository);
+    void repositoryNotAvailable(Object factoryKey);
+}

Propchange: rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/LazyRepositoryFactoryListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/LazyRepositoryFactoryListener.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/servlet/ServletContextRepositoryFactory.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/servlet/ServletContextRepositoryFactory.java?rev=1377645&view=auto
==============================================================================
--- rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/servlet/ServletContextRepositoryFactory.java (added)
+++ rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/servlet/ServletContextRepositoryFactory.java Mon Aug 27 11:23:18 2012
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rave.jcr.servlet;
+
+import java.util.Map;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryFactory;
+import javax.servlet.ServletContext;
+
+import org.apache.rave.jcr.LazyRepositoryFactoryListener;
+
+public class ServletContextRepositoryFactory implements RepositoryFactory {
+
+    public static final String REPOSITORY_PATH_PARAM = "repository.context.path";
+    public static final String DEFAULT_NAME = "javax.jcr.Repository";
+
+    private boolean initialized;
+    private ServletContext servletContext;
+    private String repositoryContextPath;
+    private String attributeName = DEFAULT_NAME;
+    private LazyRepositoryFactoryListener listener;
+
+    public ServletContextRepositoryFactory(ServletContext servletContext) {
+        this.servletContext = servletContext;
+    }
+
+    private void initialize() {
+        if (!initialized) {
+            String contextPath = servletContext.getContextPath();
+            if (contextPath.startsWith("/")) {
+                contextPath = contextPath.substring(1);
+            }
+            if (!contextPath.isEmpty()) {
+                contextPath = "." + contextPath;
+            }
+            // first check for a context specific system property named REPOSITORY_PATH_PARAM.<context path name>
+            contextPath = System.getProperty(REPOSITORY_PATH_PARAM+contextPath);
+            if (isEmpty(contextPath)) {
+                // Check for a global system property named REPOSITORY_PATH_PARAM
+                contextPath = System.getProperty(REPOSITORY_PATH_PARAM);
+            }
+            if (isEmpty(contextPath)) {
+                // Check for a (default) configured contextPath on this bean
+                contextPath = repositoryContextPath;
+            }
+            if (isEmpty(contextPath)) {
+                // Finally check for a servlet context init parameter named REPOSITORY_PATH_PARAM
+                contextPath = servletContext.getInitParameter(REPOSITORY_PATH_PARAM);
+            }
+            if (isEmpty(contextPath)) {
+                contextPath = null;
+            }
+            repositoryContextPath = contextPath;
+        }
+    }
+
+    public void setRepositoryContextPath(String repositoryContextPath) {
+        this.repositoryContextPath = repositoryContextPath;
+    }
+
+    public void setAttributeName(String attributeName) {
+        if (isEmpty(attributeName)) {
+            attributeName = DEFAULT_NAME;
+        }
+        this.attributeName = attributeName;
+    }
+
+    private boolean isEmpty(String value) {
+        return value == null || value.isEmpty();
+    }
+
+    @Override
+    public Repository getRepository(final Map parameters) {
+        initialize();
+        ServletContext context = this.servletContext;
+        if (repositoryContextPath != null) {
+            context = context.getContext(repositoryContextPath);
+        }
+        if (context != null) {
+            Object o = context.getAttribute(this.attributeName);
+            if (o != null && o instanceof Repository && ((Repository)o).getDescriptor(Repository.SPEC_VERSION_DESC) != null) {
+                return (Repository)o;
+            }
+        }
+        return null;
+    }
+}

Propchange: rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/servlet/ServletContextRepositoryFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: rave/sandbox/content-services/rave-jcr-service/src/main/java/org/apache/rave/jcr/servlet/ServletContextRepositoryFactory.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: rave/sandbox/content-services/rave-jcr/pom.xml
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr/pom.xml?rev=1377645&r1=1377644&r2=1377645&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr/pom.xml (original)
+++ rave/sandbox/content-services/rave-jcr/pom.xml Mon Aug 27 11:23:18 2012
@@ -56,6 +56,11 @@
       <scope>runtime</scope>
     </dependency>
     <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>jackrabbit-jcr-servlet</artifactId>
+      <version>${apache.jackrabbit.version}</version>
+    </dependency>
+    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-log4j12</artifactId>
       <scope>compile</scope>

Modified: rave/sandbox/content-services/rave-jcr/src/main/java/org/apache/rave/jcr/jackrabbit/JackrabbitRepositoryServlet.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr/src/main/java/org/apache/rave/jcr/jackrabbit/JackrabbitRepositoryServlet.java?rev=1377645&r1=1376541&r2=1377645&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr/src/main/java/org/apache/rave/jcr/jackrabbit/JackrabbitRepositoryServlet.java (original)
+++ rave/sandbox/content-services/rave-jcr/src/main/java/org/apache/rave/jcr/jackrabbit/JackrabbitRepositoryServlet.java Mon Aug 27 11:23:18 2012
@@ -16,58 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.rave.jcr.servlet.jackrabbit;
+package org.apache.rave.jcr.jackrabbit;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
 
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
 
-import org.apache.jackrabbit.core.RepositoryImpl;
-import org.apache.jackrabbit.core.config.RepositoryConfig;
-import org.apache.jackrabbit.servlet.AbstractRepositoryServlet;
-import org.apache.rave.jcr.bootstrapping.BootstrapException;
-import org.apache.rave.jcr.jackrabbit.RaveRepositoryImpl;
-
-
 /**
- * Servlet that makes a Jackrabbit repository available as a servlet context
- * attribute. The repository is started during servlet initialization and
- * shut down when the servlet is destroyed.
- * <p>
- * The supported initialization parameters of this servlet are:
- * <dl>
- *   <dt>javax.jcr.Repository</dt>
- *   <dd>
- *     Name of the servlet context attribute to put the repository in.
- *     The default value is "<code>javax.jcr.Repository</code>".
- *   </dd>
- *   <dt>repository.home</dt>
- *   <dd>
- *     Path of the repository home directory. The home directory is
- *     automatically created during servlet initialization if it does
- *     not already exist.
- *   </dd>
- *   <dt>repository.config</dt>
- *   <dd>
- *     Path of the repository configuration file. The default value is
- *     "<code>repository.xml</code>" within the configured repository home
- *     directory. A standard configuration file is automatically copied to
- *     the configured location during servlet initialization if the file
- *     does not already exist.
- *   </dd>
- * </dl>
- * <p>
- * The values of the repository.home and repository.config parameters can be overriden:
- * </p>
+ * Extended version of the JackrabbitRepositoryServlet to allow overriding of the
+ * <code>repository.home</code> and <code>repository.config</code> location init parameters through system properties.
  * <p>
  * First a context specific system property will be evaluated using a postfix
  * of the context path without leading /, separated by a . (dot).<br/>
@@ -88,13 +47,10 @@ import org.apache.rave.jcr.jackrabbit.Ra
  *   <li><code>repository.home: WEB-INF/storage</code></li>
  * </ul>
  * </p>
-
- * The repository servlet can also be mapped to the URL space. See
- * {@link AbstractRepositoryServlet} for the details.
  *
  * @version $Id$
  */
-public class JackrabbitRepositoryServlet extends AbstractRepositoryServlet {
+public class JackrabbitRepositoryServlet extends org.apache.jackrabbit.servlet.jackrabbit.JackrabbitRepositoryServlet {
 
     private static final long serialVersionUID = 1L;
 
@@ -107,64 +63,11 @@ public class JackrabbitRepositoryServlet
     /** Default repository storage directory */
     public static final String DEFAULT_REPOSITORY_DIRECTORY = "WEB-INF/storage";
 
-    private RaveRepositoryImpl raveRepository;
-
     private String repositoryDirectory;
     private String repositoryConfig;
 
-    @Override
-    public void init(ServletConfig config) throws ServletException {
-        repositoryDirectory = getLocationParam(config, REPOSITORY_DIRECTORY_PARAM, DEFAULT_REPOSITORY_DIRECTORY);
-        repositoryConfig = getLocationParam(config, REPOSITORY_CONFIG_PARAM, null);
-        super.init(config);
-    }
-
-    @Override
-    public void init() throws ServletException {
-        try {
-            final File home = new File(getInitParameter(REPOSITORY_DIRECTORY_PARAM, DEFAULT_REPOSITORY_DIRECTORY));
-            if (!home.exists()) {
-                log("Creating repository home directory: " + home);
-                home.mkdirs();
-            }
-
-            final File config = new File(getInitParameter(REPOSITORY_CONFIG_PARAM, new File(home, "repository.xml").getPath()));
-            if (!config.exists()) {
-                log("Creating default repository configuration: " + config);
-                createDefaultConfiguration(config);
-            }
-
-            raveRepository = new RaveRepositoryImpl(RepositoryConfig.create(config.toURI(), home.getPath()), getServletContext());
-            raveRepository.bootstrap(true);
-
-        } catch (RepositoryException e) {
-            throw new ServletException("Failed to start Jackrabbit", e);
-        } catch (BootstrapException e) {
-            throw new ServletException("Failed to start Jackrabbit", e);
-        }
-
-        super.init();
-    }
-
-    public void destroy() {
-        super.destroy();
-        raveRepository.shutdown();
-    }
-
-    @Override
-    protected Repository getRepository() throws RepositoryException {
-        return raveRepository;
-    }
-
-    @Override
-    protected String getInitParameter(String name, String def) {
-        if (REPOSITORY_DIRECTORY_PARAM.equals(name) && !isEmpty(repositoryDirectory)) {
-            return repositoryDirectory;
-        }
-        else if (REPOSITORY_CONFIG_PARAM.equals(name) && !isEmpty(repositoryConfig)) {
-            return repositoryConfig;
-        }
-        return super.getInitParameter(name, def);
+    protected boolean isEmpty(String value) {
+        return value == null || value.isEmpty();
     }
 
     protected String getLocationParam(ServletConfig config, String parameterName, String defaultValue) throws ServletException {
@@ -218,40 +121,21 @@ public class JackrabbitRepositoryServlet
         return location;
     }
 
-    private boolean isEmpty(String value) {
-        return value == null || value.isEmpty();
-    }
-
-    /**
-     * Copies the default repository configuration file to the given location.
-     *
-     * @param config path of the configuration file
-     * @throws ServletException if the configuration file could not be copied
-     */
-    private void createDefaultConfiguration(File config)
-            throws ServletException {
-        try {
-            OutputStream output = new FileOutputStream(config);
-            try {
-                InputStream input =
-                        RepositoryImpl.class.getResourceAsStream("repository.xml");
-                try {
-                    byte[] buffer = new byte[8192];
-                    int n = input.read(buffer);
-                    while (n != -1) {
-                        output.write(buffer, 0, n);
-                        n = input.read(buffer);
-                    }
-                } finally {
-                    input.close();
-                }
-            } finally {
-                output.close();
-            }
-        } catch (IOException e) {
-            throw new ServletException(
-                    "Failed to copy default configuration: " + config, e);
+    @Override
+    protected String getInitParameter(String name, String def) {
+        if (REPOSITORY_DIRECTORY_PARAM.equals(name) && !isEmpty(repositoryDirectory)) {
+            return repositoryDirectory;
+        }
+        else if (REPOSITORY_CONFIG_PARAM.equals(name) && !isEmpty(repositoryConfig)) {
+            return repositoryConfig;
         }
+        return super.getInitParameter(name, def);
     }
 
-}
+    @Override
+    public void init(ServletConfig config) throws ServletException {
+        repositoryDirectory = getLocationParam(config, REPOSITORY_DIRECTORY_PARAM, DEFAULT_REPOSITORY_DIRECTORY);
+        repositoryConfig = getLocationParam(config, REPOSITORY_CONFIG_PARAM, null);
+        super.init(config);
+    }
+}
\ No newline at end of file

Modified: rave/sandbox/content-services/rave-jcr/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr/src/main/webapp/WEB-INF/web.xml?rev=1377645&r1=1377644&r2=1377645&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr/src/main/webapp/WEB-INF/web.xml (original)
+++ rave/sandbox/content-services/rave-jcr/src/main/webapp/WEB-INF/web.xml Mon Aug 27 11:23:18 2012
@@ -28,7 +28,7 @@
 
   <servlet>
     <servlet-name>Repository</servlet-name>
-    <servlet-class>org.apache.rave.jcr.servlet.jackrabbit.JackrabbitRepositoryServlet</servlet-class>
+    <servlet-class>org.apache.rave.jcr.jackrabbit.JackrabbitRepositoryServlet</servlet-class>
 <!--    
     <init-param>
       <description>The Servlet context attribute name under which to expose the repository.

Modified: rave/sandbox/content-services/rave-web-hmvc/pom.xml
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/pom.xml?rev=1377645&r1=1377644&r2=1377645&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/pom.xml (original)
+++ rave/sandbox/content-services/rave-web-hmvc/pom.xml Mon Aug 27 11:23:18 2012
@@ -37,12 +37,12 @@
   <dependencies>
     <dependency>
       <groupId>org.apache.rave.sandbox.jcr</groupId>
-      <artifactId>rave-jcr-config</artifactId>
+      <artifactId>rave-jcr-page-configuration</artifactId>
       <version>${project.version}</version>
     </dependency>
     <dependency>
       <groupId>org.apache.rave.sandbox.jcr</groupId>
-      <artifactId>rave-jcr-page-configuration</artifactId>
+      <artifactId>rave-jcr-service</artifactId>
       <version>${project.version}</version>
     </dependency>
     <dependency>

Modified: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/hmvc/HmvcHandlerMethodMappingByConfig.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/hmvc/HmvcHandlerMethodMappingByConfig.java?rev=1377645&r1=1377644&r2=1377645&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/hmvc/HmvcHandlerMethodMappingByConfig.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/hmvc/HmvcHandlerMethodMappingByConfig.java Mon Aug 27 11:23:18 2012
@@ -30,6 +30,8 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.servlet.ServletContext;
 
+import org.apache.rave.jcr.LazyRepositoryFactory;
+import org.apache.rave.jcr.LazyRepositoryFactoryListener;
 import org.apache.rave.jcr.config.ConfigManager;
 import org.apache.rave.jcr.config.JcrConfigManager;
 import org.apache.rave.jcr.config.model.api.PageConfiguration;
@@ -41,7 +43,6 @@ import org.slf4j.LoggerFactory;
 import org.springframework.core.annotation.AnnotationUtils;
 import org.springframework.util.ClassUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.context.ServletContextAware;
 import org.springframework.web.method.HandlerMethod;
 import org.springframework.web.servlet.mvc.condition.ConsumesRequestCondition;
 import org.springframework.web.servlet.mvc.condition.HeadersRequestCondition;
@@ -54,10 +55,11 @@ import org.springframework.web.servlet.m
 /**
  * @version "$Id$"
  */
-public class HmvcHandlerMethodMappingByConfig extends HmvcHandlerMethodMapping implements ServletContextAware {
+public class HmvcHandlerMethodMappingByConfig extends HmvcHandlerMethodMapping implements LazyRepositoryFactoryListener {
 
     private static final Logger log = LoggerFactory.getLogger(HmvcHandlerMethodMappingByConfig.class);
 
+    private LazyRepositoryFactory repositoryFactory;
 
     private ConfigManager configManager;
 
@@ -77,22 +79,10 @@ public class HmvcHandlerMethodMappingByC
     protected void initHandlerMethods() {
         // TODO: figure out better way to inject JcrConfigManager
         if (credentials != null) {
-            ServletContext context = getServletContext();
-            Repository repo = (Repository) context.getAttribute("javax.jcr.Repository");
-            Session session = null;
-            try {
-                session = repo.login(credentials);
-                configManager = new JcrConfigManager(session, configurationPath);
-                final PageConfiguration configuration = configManager.loadConfiguration(configurationName);
-                log.info("configuration {}", configuration);
 
-
-            } catch (RepositoryException e) {
-                log.error("Error obtaining session", e);
-            } finally {
-                if (session != null) {
-                    session.logout();
-                }
+            Repository repository = repositoryFactory.getRepository(this);
+            if (repository != null) {
+                repositoryAvailable(repositoryFactory.getFactoryKey(), repository);
             }
 
         } else {
@@ -103,6 +93,35 @@ public class HmvcHandlerMethodMappingByC
         }
     }
 
+    @Override
+    public void repositoryAvailable(final Object factoryKey, final Repository repository) {
+        Session session = null;
+        try {
+            session = repository.login(credentials);
+            configManager = new JcrConfigManager(session, configurationPath);
+            final PageConfiguration configuration = configManager.loadConfiguration(configurationName);
+            log.info("configuration {}", configuration);
+            // TODO use urlConfig
+//            final UrlConfiguration urlConfig = configManager.loadUrlConfig(urlMappingsPath, configuration);
+            processConfiguration(configuration);
+        } catch (RepositoryException e) {
+            log.error("Error obtaining session", e);
+        } finally {
+            if (session != null) {
+                session.logout();
+            }
+        }
+    }
+
+    @Override
+    public void repositoryNotAvailable(final Object factoryKey) {
+        // TODO
+    }
+
+    public void shutdown() {
+        repositoryFactory.removeListener(this);
+    }
+
     private void processConfiguration(PageConfiguration configuration) {
         final List<PageDefinition> pageDefinitions = configuration.getPageDefinitions();
 
@@ -223,4 +242,8 @@ public class HmvcHandlerMethodMappingByC
     public void setCredentials(Credentials credentials) {
         this.credentials = credentials;
     }
+
+    public void setLazyRepositoryFactory(LazyRepositoryFactory repositoryFactory) {
+        this.repositoryFactory = repositoryFactory;
+    }
 }
\ No newline at end of file