You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by md...@apache.org on 2009/09/18 00:52:15 UTC

svn commit: r816402 - in /jackrabbit/trunk: jackrabbit-jcr-client/ jackrabbit-jcr-client/src/main/java/org/apache/jackrabbit/client/ jackrabbit-jcr-client/src/main/java/org/apache/jackrabbit/client/spi2dav/ jackrabbit-jcr-client/src/main/java/org/apach...

Author: mduerig
Date: Thu Sep 17 22:52:14 2009
New Revision: 816402

URL: http://svn.apache.org/viewvc?rev=816402&view=rev
Log:
JCR-2042: RepositoryFactory implementation for jcr2spi
JCR-2309: Remove excessive dependencies from jcr-client module

Added:
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/Jcr2spiRepositoryFactory.java   (with props)
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/resources/
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/resources/META-INF/
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/resources/META-INF/services/
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/resources/META-INF/services/javax.jcr.RepositoryFactory
    jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryServiceFactory.java   (with props)
    jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/Spi2davRepositoryServiceFactory.java   (with props)
    jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/Spi2davexRepositoryServiceFactory.java   (with props)
    jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/Spi2jcrRepositoryServiceFactory.java   (with props)
Removed:
    jackrabbit/trunk/jackrabbit-jcr-client/src/main/java/org/apache/jackrabbit/client/spi2dav/
    jackrabbit/trunk/jackrabbit-jcr-client/src/main/java/org/apache/jackrabbit/client/spi2davex/
    jackrabbit/trunk/jackrabbit-jcr-client/src/main/java/org/apache/jackrabbit/client/spi2jcr/
    jackrabbit/trunk/jackrabbit-jcr-client/src/main/java/org/apache/jackrabbit/client/spilogger/
Modified:
    jackrabbit/trunk/jackrabbit-jcr-client/pom.xml
    jackrabbit/trunk/jackrabbit-jcr-client/src/main/java/org/apache/jackrabbit/client/RepositoryFactoryImpl.java
    jackrabbit/trunk/jackrabbit-jcr-client/src/test/java/org/apache/jackrabbit/client/RepositoryFactoryImplTest.java

Modified: jackrabbit/trunk/jackrabbit-jcr-client/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-client/pom.xml?rev=816402&r1=816401&r2=816402&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-client/pom.xml (original)
+++ jackrabbit/trunk/jackrabbit-jcr-client/pom.xml Thu Sep 17 22:52:14 2009
@@ -68,35 +68,45 @@
             <artifactId>jcr</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        
+        <dependency>
             <groupId>org.apache.jackrabbit</groupId>
-            <artifactId>jackrabbit-jcr2spi</artifactId>
+            <artifactId>jackrabbit-spi2dav</artifactId>
             <version>2.0-SNAPSHOT</version>
-            <classifier></classifier>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.jackrabbit</groupId>
-            <artifactId>jackrabbit-spi</artifactId>
+            <artifactId>jackrabbit-spi2jcr</artifactId>
             <version>2.0-SNAPSHOT</version>
-            <classifier></classifier>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.jackrabbit</groupId>
-            <artifactId>jackrabbit-spi-commons</artifactId>
+            <artifactId>jackrabbit-core</artifactId>
             <version>2.0-SNAPSHOT</version>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.jackrabbit</groupId>
-            <artifactId>jackrabbit-spi2jcr</artifactId>
+            <artifactId>jackrabbit-spi-commons</artifactId>
             <version>2.0-SNAPSHOT</version>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.jackrabbit</groupId>
-            <artifactId>jackrabbit-spi2dav</artifactId>
+            <artifactId>jackrabbit-jcr2spi</artifactId>
             <version>2.0-SNAPSHOT</version>
+            <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>jackrabbit-spi</artifactId>
+            <version>2.0-SNAPSHOT</version>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>junit</groupId>

Modified: jackrabbit/trunk/jackrabbit-jcr-client/src/main/java/org/apache/jackrabbit/client/RepositoryFactoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-client/src/main/java/org/apache/jackrabbit/client/RepositoryFactoryImpl.java?rev=816402&r1=816401&r2=816402&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-client/src/main/java/org/apache/jackrabbit/client/RepositoryFactoryImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-client/src/main/java/org/apache/jackrabbit/client/RepositoryFactoryImpl.java Thu Sep 17 22:52:14 2009
@@ -22,74 +22,60 @@
 import javax.jcr.RepositoryException;
 import javax.jcr.RepositoryFactory;
 
-import org.apache.jackrabbit.jcr2spi.RepositoryImpl;
-import org.apache.jackrabbit.jcr2spi.config.RepositoryConfig;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 /**
- * <code>RepositoryFactoryImpl</code>...
+ * This {@link RepositoryFactory} implementations is capable of creating any
+ * repository which is covered by the Apache Jackrabbit project. It does so by
+ * delegating back to secondary RepositoryFactory implementations. The
+ * parameters passed to the {@link #getRepository(Map)} method determine which
+ * secondare RepositoryFactory this factory delegates to.
  */
 public class RepositoryFactoryImpl implements RepositoryFactory {
 
-    private static Logger log = LoggerFactory.getLogger(RepositoryFactoryImpl.class);
+    /**
+     * When this key parameter is present, this factory delegates to
+     * {@link org.apache.jackrabbit.jcr2spi.Jcr2spiRepositoryFactory}
+     */
+    public static final String PARAM_REPOSITORY_SERVICE_FACTORY = "org.apache.jackrabbit.spi.RepositoryServiceFactory";
 
-    public static final String REPOSITORY_CONFIG = "org.apache.jackrabbit.repository.config";
+    /**
+     * When this key parameter is present, this factory delegates to
+     * {@link org.apache.jackrabbit.jcr2spi.Jcr2spiRepositoryFactory}
+     */
+    public static final String PARAM_REPOSITORY_CONFIG = "org.apache.jackrabbit.jcr2spi.RepositoryConfig";
 
-    //--------------------------------------------------< RepositoryFactory >---
     /**
      * Creates a JCR repository from the given <code>parameters</code>.
-     * If the <code>parameters</code> map is <code>null</code> the default
-     * repository  (i.e. JCR2SPI repository on top of SPI2DAVex) is returned.<p/>
-     * If the <code>parameters</code> map contains a {@link #REPOSITORY_CONFIG}
-     * entry it's value is expected to be a implementation of
-     * {@link org.apache.jackrabbit.jcr2spi.config.RepositoryConfig} and the
-     * repository will be created based on this configuration.<p/>
-     * If the <code>parameters</code> map does not contain a {@link #REPOSITORY_CONFIG}
-     * entry or if the corresponding value isn't a valid <code>RepositoryConfig</code>
-     * an attempt is made to create a
-     * {@link org.apache.jackrabbit.jcr2spi.config.RepositoryConfig} for any of
-     * the known SPI implementations:
-     * <ul>
-     * <li>SPI2DAVex (see jackrabbit-spi2dav module)</li>
-     * <li>SPI2DAV (see jackrabbit-spi2dav module)</li>
-     * <li>SPI2JCR (see jackrabbit-spi2jcr module)</li>
-     * </ul>
-     * NOTE: If the <code>parameters</code> map contains an
-     * {@link org.apache.jackrabbit.client.spilogger.RepositoryConfigImpl#PARAM_LOG_WRITER_PROVIDER PARAM_LOG_WRITER_PROVIDER}
-     * entry the {@link org.apache.jackrabbit.spi.RepositoryService RepositoryService} obtained
-     * from the configuration is wrapped by a SPI logger. See the
-     * {@link org.apache.jackrabbit.spi.commons.logging.SpiLoggerFactory SpiLoggerFactory}
-     * for details.
+     * If either {@link #PARAM_REPOSITORY_SERVICE_FACTORY} or
+     * {@link #PARAM_REPOSITORY_CONFIG} is present, this factory delegates
+     * to {@link org.apache.jackrabbit.jcr2spi.Jcr2spiRepositoryFactory}.
+     * Otherwise it delegates to
+     * {@link org.apache.jackrabbit.core.RepositoryFactoryImpl}.
      *
      * @see RepositoryFactory#getRepository(java.util.Map)
      */
-    public Repository getRepository(Map parameters) throws RepositoryException {
-        RepositoryConfig config = null;
-        if (parameters == null) {
-            config = org.apache.jackrabbit.client.spi2davex.RepositoryConfigImpl.create((Map) null);
-        } else {
-            Object param = parameters.get(REPOSITORY_CONFIG);
-            if (param != null && param instanceof RepositoryConfig) {
-                config = (RepositoryConfig) param;
-            }
-            if (config == null) {
-                config = org.apache.jackrabbit.client.spi2davex.RepositoryConfigImpl.create(parameters);
-                if (config == null) {
-                    config = org.apache.jackrabbit.client.spi2dav.RepositoryConfigImpl.create(parameters);
-                }
-                if (config == null) {
-                    config = org.apache.jackrabbit.client.spi2jcr.RepositoryConfigImpl.create(parameters);
-                }
-            }
+    public Repository getRepository(@SuppressWarnings("unchecked") Map parameters) throws RepositoryException {
+        String repositoryFactoryName = parameters != null && (
+                                       parameters.containsKey(PARAM_REPOSITORY_SERVICE_FACTORY) ||
+                                       parameters.containsKey(PARAM_REPOSITORY_CONFIG))
+                ? "org.apache.jackrabbit.jcr2spi.Jcr2spiRepositoryFactory"
+                : "org.apache.jackrabbit.core.RepositoryFactoryImpl";
+
+        Object repositoryFactory;
+        try {
+            Class<?> repositoryFactoryClass = Class.forName(repositoryFactoryName, true,
+                    Thread.currentThread().getContextClassLoader());
+
+            repositoryFactory = repositoryFactoryClass.newInstance();
+        }
+        catch (Exception e) {
+            throw new RepositoryException(e);
         }
 
-        if (config != null) {
-            config = org.apache.jackrabbit.client.spilogger.RepositoryConfigImpl.create(config, parameters);
-            return RepositoryImpl.create(config);
-        } else {
-            log.debug("Unable to create Repository: Unknown parameters.");
-            return null;
+        if (repositoryFactory instanceof RepositoryFactory) {
+            return ((RepositoryFactory) repositoryFactory).getRepository(parameters);
+        }
+        else {
+            throw new RepositoryException(repositoryFactory + " is not a RepositoryFactory");
         }
     }
 }
\ No newline at end of file

Modified: jackrabbit/trunk/jackrabbit-jcr-client/src/test/java/org/apache/jackrabbit/client/RepositoryFactoryImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-client/src/test/java/org/apache/jackrabbit/client/RepositoryFactoryImplTest.java?rev=816402&r1=816401&r2=816402&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-client/src/test/java/org/apache/jackrabbit/client/RepositoryFactoryImplTest.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-client/src/test/java/org/apache/jackrabbit/client/RepositoryFactoryImplTest.java Thu Sep 17 22:52:14 2009
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.client;
 
 import java.io.InputStream;
+import java.net.ConnectException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -50,13 +51,15 @@
 
 import junit.framework.TestCase;
 
-import org.apache.jackrabbit.client.spilogger.RepositoryConfigImpl;
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 import org.apache.jackrabbit.jcr2spi.config.RepositoryConfig;
 import org.apache.jackrabbit.spi.Batch;
+import org.apache.jackrabbit.spi.ChildInfo;
 import org.apache.jackrabbit.spi.EventBundle;
 import org.apache.jackrabbit.spi.EventFilter;
 import org.apache.jackrabbit.spi.IdFactory;
 import org.apache.jackrabbit.spi.ItemId;
+import org.apache.jackrabbit.spi.ItemInfo;
 import org.apache.jackrabbit.spi.LockInfo;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.NameFactory;
@@ -73,80 +76,159 @@
 import org.apache.jackrabbit.spi.QValueFactory;
 import org.apache.jackrabbit.spi.QueryInfo;
 import org.apache.jackrabbit.spi.RepositoryService;
+import org.apache.jackrabbit.spi.RepositoryServiceFactory;
 import org.apache.jackrabbit.spi.SessionInfo;
 import org.apache.jackrabbit.spi.Subscription;
 import org.apache.jackrabbit.spi.commons.logging.Slf4jLogWriterProvider;
 
-/**
- * <code>RepositoryFactoryImplTest</code>...
- */
 public class RepositoryFactoryImplTest extends TestCase {
-
     private final RepositoryFactory factory = new RepositoryFactoryImpl();
-    private final RepositoryService service = new RepositoryServiceImpl();
 
-    public void testGetDefaultRepository() throws RepositoryException {
-        try {
-            Repository repo = factory.getRepository(null);
-            assertNotNull(repo);
-        } catch (RepositoryException e) {
-            // repository on top of spi2davex can only be initialized if the
-            // server is running. ok.
-        }
+    public void testGetRepositoryFromServiceFactory() throws RepositoryException {
+        Map<String, RepositoryServiceFactory> parameters = Collections.singletonMap(
+                "org.apache.jackrabbit.spi.RepositoryServiceFactory",
+                RepositoryServiceFactoryImpl.INSTANCE);
 
-        try {
-            System.setProperty(org.apache.jackrabbit.client.spi2davex.RepositoryConfigImpl.REPOSITORY_SPI2DAVEX_URI, org.apache.jackrabbit.client.spi2davex.RepositoryConfigImpl.DEFAULT_URI);
-            Repository repo = factory.getRepository(null);
-            assertNotNull(repo);
-        } catch (RepositoryException e) {
-            // repository on top of spi2davex can only be initialized if the
-            // server is running. ok.
-        }
+        Repository repo = factory.getRepository(parameters);
+        assertNotNull(repo);
     }
 
-    public void testGetRepository() throws RepositoryException {
-        RepositoryConfig config = new AbstractRepositoryConfig() {
-            public RepositoryService getRepositoryService() throws RepositoryException {
-                return service;
-            }
-        };
+    public void testGetRepositoryFromRepositoryConfig() throws RepositoryException {
+        Map<String, RepositoryConfig> parameters = Collections.singletonMap(
+                "org.apache.jackrabbit.jcr2spi.RepositoryConfig",
+                RepositoryConfigImpl.INSTANCE);
 
-        Repository repo = factory.getRepository(Collections.singletonMap(RepositoryFactoryImpl.REPOSITORY_CONFIG, config));
+        Repository repo = factory.getRepository(parameters);
         assertNotNull(repo);
     }
 
     public void testGetRepositoryWithLogger() throws RepositoryException {
-        RepositoryConfig config = new AbstractRepositoryConfig() {
-            public RepositoryService getRepositoryService() throws RepositoryException {
-                return service;
-            }
-        };
-
-        List lwprovider = new ArrayList();
+        List<Object> lwprovider = new ArrayList<Object>();
         lwprovider.add(null);
         lwprovider.add(new Boolean(true));
         lwprovider.add(new Slf4jLogWriterProvider());
 
-        Map params = new HashMap();
-        params.put(RepositoryFactoryImpl.REPOSITORY_CONFIG, config);
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put("org.apache.jackrabbit.jcr2spi.RepositoryConfig", RepositoryConfigImpl.INSTANCE);
 
         for (int i = 0; i < lwprovider.size(); i++) {
-            params.put(RepositoryConfigImpl.PARAM_LOG_WRITER_PROVIDER, lwprovider.get(i));
+            params.put("org.apache.jackrabbit.spi.commons.logging.LogWriterProvider", lwprovider.get(i));
             Repository repo = factory.getRepository(params);
             assertNotNull(repo);
         }
     }
 
+    public void testGetDefaultRepository() throws RepositoryException {
+        Repository repo = factory.getRepository(null);
+        assertNotNull(repo);
+        assertEquals("Jackrabbit", repo.getDescriptor(Repository.REP_NAME_DESC));
+    }
+
+    public void testGetSpi2jcrRepository() throws RepositoryException {
+        Repository coreRepo = factory.getRepository(null);
+
+        HashMap<String, Object> parameters = new HashMap<String, Object>();
+        parameters.put("org.apache.jackrabbit.spi.RepositoryServiceFactory",
+                       "org.apache.jackrabbit.spi2jcr.Spi2jcrRepositoryServiceFactory");
+        parameters.put("org.apache.jackrabbit.spi2jcr.Repository", coreRepo);
+
+        Repository jcr2spiRepo = factory.getRepository(parameters);
+        assertNotNull(jcr2spiRepo);
+        assertEquals("Jackrabbit", jcr2spiRepo.getDescriptor(Repository.REP_NAME_DESC));
+    }
+
+    public void testGetSpi2davRepository() throws RepositoryException {
+        Map<String, String> parameters = new HashMap<String, String>();
+
+        parameters.put("org.apache.jackrabbit.spi.RepositoryServiceFactory",
+                       "org.apache.jackrabbit.spi2dav.Spi2davRepositoryServiceFactory");
+        parameters.put("org.apache.jackrabbit.spi2dav.uri",
+                       "http://localhost/");
+
+        try {
+            Repository repo = factory.getRepository(parameters);
+            assertNotNull(repo);
+        } catch (RepositoryException e) {
+            if (!ConnectException.class.isInstance(e.getCause())) {
+                throw e;
+            }
+        }
+    }
+
+    public void testGetSpi2davexRepository() throws RepositoryException {
+        Map<String, String> parameters = Collections.singletonMap(
+                "org.apache.jackrabbit.spi.RepositoryServiceFactory",
+                "org.apache.jackrabbit.spi2davex.Spi2davexRepositoryServiceFactory");
+
+        try {
+            Repository repo = factory.getRepository(parameters);
+            assertNotNull(repo);
+        } catch (RepositoryException e) {
+            if (!ConnectException.class.isInstance(e.getCause())) {
+                throw e;
+            }
+        }
+    }
+
     public void testGetRepositoryUnknownParams() throws RepositoryException {
         Repository repo = factory.getRepository(Collections.EMPTY_MAP);
         assertNull(repo);
     }
 
-    //--------------------------------------------------------------------------
+    // -----------------------------------------------------< private >---
+
+    /**
+     * Dummy RepositoryServiceFactory
+     */
+    private static final class RepositoryServiceFactoryImpl implements RepositoryServiceFactory {
+        public static final RepositoryServiceFactory INSTANCE = new RepositoryServiceFactoryImpl();
+
+        private RepositoryServiceFactoryImpl() {
+            super();
+        }
+
+        public RepositoryService createRepositoryService(Map<?, ?> parameters) throws RepositoryException {
+            return RepositoryServiceImpl.INSTANCE;
+        }
+    }
+
+    /**
+     * Dummy RepositoryConfig
+     */
+    private static final class RepositoryConfigImpl implements RepositoryConfig {
+        public static final RepositoryConfig INSTANCE = new RepositoryConfigImpl();
+
+        private RepositoryConfigImpl() {
+            super();
+        }
+
+        public CacheBehaviour getCacheBehaviour() {
+            return CacheBehaviour.INVALIDATE;
+        }
+
+        public int getItemCacheSize() {
+            return 1234;
+        }
+
+        public int getPollTimeout() {
+            return 1234;
+        }
+
+        public RepositoryService getRepositoryService() throws RepositoryException {
+            return RepositoryServiceImpl.INSTANCE;
+        }
+
+    }
+
     /**
      * Dummy RepositoryService
      */
     private static final class RepositoryServiceImpl implements RepositoryService {
+        public static final RepositoryService INSTANCE = new RepositoryServiceImpl();
+
+        private RepositoryServiceImpl() {
+            super();
+        }
 
         public IdFactory getIdFactory() throws RepositoryException {
             return null;
@@ -181,6 +263,7 @@
         }
 
         public void dispose(SessionInfo sessionInfo) throws RepositoryException {
+            // empty
         }
 
         public String[] getWorkspaceNames(SessionInfo sessionInfo) throws RepositoryException {
@@ -203,11 +286,11 @@
             return null;
         }
 
-        public Iterator getItemInfos(SessionInfo sessionInfo, NodeId nodeId) throws ItemNotFoundException, RepositoryException {
+        public Iterator<? extends ItemInfo> getItemInfos(SessionInfo sessionInfo, NodeId nodeId) throws ItemNotFoundException, RepositoryException {
             return null;
         }
 
-        public Iterator getChildInfos(SessionInfo sessionInfo, NodeId parentId) throws ItemNotFoundException, RepositoryException {
+        public Iterator<ChildInfo> getChildInfos(SessionInfo sessionInfo, NodeId parentId) throws ItemNotFoundException, RepositoryException {
             return null;
         }
 
@@ -224,21 +307,27 @@
         }
 
         public void submit(Batch batch) throws PathNotFoundException, ItemNotFoundException, NoSuchNodeTypeException, ValueFormatException, VersionException, LockException, ConstraintViolationException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
+            // empty
         }
 
         public void importXml(SessionInfo sessionInfo, NodeId parentId, InputStream xmlStream, int uuidBehaviour) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
+            // empty
         }
 
         public void move(SessionInfo sessionInfo, NodeId srcNodeId, NodeId destParentNodeId, Name destName) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
+            // empty
         }
 
         public void copy(SessionInfo sessionInfo, String srcWorkspaceName, NodeId srcNodeId, NodeId destParentNodeId, Name destName) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, UnsupportedRepositoryOperationException, RepositoryException {
+            // empty
         }
 
         public void update(SessionInfo sessionInfo, NodeId nodeId, String srcWorkspaceName) throws NoSuchWorkspaceException, AccessDeniedException, LockException, InvalidItemStateException, RepositoryException {
+            // empty
         }
 
         public void clone(SessionInfo sessionInfo, String srcWorkspaceName, NodeId srcNodeId, NodeId destParentNodeId, Name destName, boolean removeExisting) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, UnsupportedRepositoryOperationException, RepositoryException {
+            // empty
         }
 
         public LockInfo getLockInfo(SessionInfo sessionInfo, NodeId nodeId) throws AccessDeniedException, RepositoryException {
@@ -254,9 +343,11 @@
         }
 
         public void refreshLock(SessionInfo sessionInfo, NodeId nodeId) throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, RepositoryException {
+            // empty
         }
 
         public void unlock(SessionInfo sessionInfo, NodeId nodeId) throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, RepositoryException {
+            // empty
         }
 
         public NodeId checkin(SessionInfo sessionInfo, NodeId nodeId) throws VersionException, UnsupportedRepositoryOperationException, InvalidItemStateException, LockException, RepositoryException {
@@ -264,9 +355,11 @@
         }
 
         public void checkout(SessionInfo sessionInfo, NodeId nodeId) throws UnsupportedRepositoryOperationException, LockException, RepositoryException {
+            // empty
         }
 
         public void checkout(SessionInfo sessionInfo, NodeId nodeId, NodeId activityId) throws UnsupportedRepositoryOperationException, LockException, RepositoryException {
+            // empty
         }
 
         public NodeId checkpoint(SessionInfo sessionInfo, NodeId nodeId) throws UnsupportedRepositoryOperationException, RepositoryException {
@@ -274,29 +367,35 @@
         }
 
         public void removeVersion(SessionInfo sessionInfo, NodeId versionHistoryId, NodeId versionId) throws ReferentialIntegrityException, AccessDeniedException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
+            // empty
         }
 
         public void restore(SessionInfo sessionInfo, NodeId nodeId, NodeId versionId, boolean removeExisting) throws VersionException, PathNotFoundException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
+            // empty
         }
 
         public void restore(SessionInfo sessionInfo, NodeId[] versionIds, boolean removeExisting) throws ItemExistsException, UnsupportedRepositoryOperationException, VersionException, LockException, InvalidItemStateException, RepositoryException {
+            // empty
         }
 
-        public Iterator merge(SessionInfo sessionInfo, NodeId nodeId, String srcWorkspaceName, boolean bestEffort) throws NoSuchWorkspaceException, AccessDeniedException, MergeException, LockException, InvalidItemStateException, RepositoryException {
+        public Iterator<NodeId> merge(SessionInfo sessionInfo, NodeId nodeId, String srcWorkspaceName, boolean bestEffort) throws NoSuchWorkspaceException, AccessDeniedException, MergeException, LockException, InvalidItemStateException, RepositoryException {
             return null;
         }
 
-        public Iterator merge(SessionInfo sessionInfo, NodeId nodeId, String srcWorkspaceName, boolean bestEffort, boolean isShallow) throws NoSuchWorkspaceException, AccessDeniedException, MergeException, LockException, InvalidItemStateException, RepositoryException {
+        public Iterator<NodeId> merge(SessionInfo sessionInfo, NodeId nodeId, String srcWorkspaceName, boolean bestEffort, boolean isShallow) throws NoSuchWorkspaceException, AccessDeniedException, MergeException, LockException, InvalidItemStateException, RepositoryException {
             return null;
         }
 
         public void resolveMergeConflict(SessionInfo sessionInfo, NodeId nodeId, NodeId[] mergeFailedIds, NodeId[] predecessorIds) throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException {
+            // empty
         }
 
         public void addVersionLabel(SessionInfo sessionInfo, NodeId versionHistoryId, NodeId versionId, Name label, boolean moveLabel) throws VersionException, RepositoryException {
+            // empty
         }
 
         public void removeVersionLabel(SessionInfo sessionInfo, NodeId versionHistoryId, NodeId versionId, Name label) throws VersionException, RepositoryException {
+            // empty
         }
 
         public NodeId createActivity(SessionInfo sessionInfo, String title) throws UnsupportedRepositoryOperationException, RepositoryException {
@@ -304,10 +403,10 @@
         }
 
         public void removeActivity(SessionInfo sessionInfo, NodeId activityId) throws UnsupportedRepositoryOperationException, RepositoryException {
-
+            // empty
         }
 
-        public Iterator mergeActivity(SessionInfo sessionInfo, NodeId activityId) throws UnsupportedRepositoryOperationException, RepositoryException {
+        public Iterator<NodeId> mergeActivity(SessionInfo sessionInfo, NodeId activityId) throws UnsupportedRepositoryOperationException, RepositoryException {
             return null;
         }
 
@@ -319,7 +418,7 @@
             return new String[0];
         }
 
-        public String[] checkQueryStatement(SessionInfo sessionInfo, String statement, String language, Map namespaces) throws InvalidQueryException, RepositoryException {
+        public String[] checkQueryStatement(SessionInfo sessionInfo, String statement, String language, Map<String, String> namespaces) throws InvalidQueryException, RepositoryException {
             return new String[0];
         }
 
@@ -336,6 +435,7 @@
         }
 
         public void updateEventFilters(Subscription subscription, EventFilter[] filters) throws RepositoryException {
+            // empty
         }
 
         public EventBundle[] getEvents(Subscription subscription, long timeout) throws RepositoryException, InterruptedException {
@@ -347,9 +447,10 @@
         }
 
         public void dispose(Subscription subscription) throws RepositoryException {
+            // empty
         }
 
-        public Map getRegisteredNamespaces(SessionInfo sessionInfo) throws RepositoryException {
+        public Map<String, String> getRegisteredNamespaces(SessionInfo sessionInfo) throws RepositoryException {
             return null;
         }
 
@@ -362,33 +463,36 @@
         }
 
         public void registerNamespace(SessionInfo sessionInfo, String prefix, String uri) throws NamespaceException, UnsupportedRepositoryOperationException, AccessDeniedException, RepositoryException {
+            // empty
         }
 
         public void unregisterNamespace(SessionInfo sessionInfo, String uri) throws NamespaceException, UnsupportedRepositoryOperationException, AccessDeniedException, RepositoryException {
+            // empty
         }
 
-        public Iterator getQNodeTypeDefinitions(SessionInfo sessionInfo) throws RepositoryException {
+        public Iterator<QNodeTypeDefinition> getQNodeTypeDefinitions(SessionInfo sessionInfo) throws RepositoryException {
             return null;
         }
 
-        public Iterator getQNodeTypeDefinitions(SessionInfo sessionInfo, Name[] nodetypeNames) throws RepositoryException {
+        public Iterator<QNodeTypeDefinition> getQNodeTypeDefinitions(SessionInfo sessionInfo, Name[] nodetypeNames) throws RepositoryException {
             return null;
         }
 
         public void registerNodeTypes(SessionInfo sessionInfo, QNodeTypeDefinition[] nodeTypeDefinitions, boolean allowUpdate) throws InvalidNodeTypeDefinitionException, NodeTypeExistsException, UnsupportedRepositoryOperationException, RepositoryException {
-
+            // empty
         }
 
         public void unregisterNodeTypes(SessionInfo sessionInfo, Name[] nodeTypeNames) throws UnsupportedRepositoryOperationException, NoSuchNodeTypeException, RepositoryException {
-
+            // empty
         }
 
         public void createWorkspace(SessionInfo sessionInfo, String name, String srcWorkspaceName) throws AccessDeniedException, UnsupportedRepositoryOperationException, NoSuchWorkspaceException, RepositoryException {
-
+            // empty
         }
 
         public void deleteWorkspace(SessionInfo sessionInfo, String name) throws AccessDeniedException, UnsupportedRepositoryOperationException, NoSuchWorkspaceException, RepositoryException {
-
+            // empty
         }
     }
+
 }
\ No newline at end of file

Added: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/Jcr2spiRepositoryFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/Jcr2spiRepositoryFactory.java?rev=816402&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/Jcr2spiRepositoryFactory.java (added)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/Jcr2spiRepositoryFactory.java Thu Sep 17 22:52:14 2009
@@ -0,0 +1,394 @@
+/*
+ * 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.jackrabbit.jcr2spi;
+
+import java.util.Map;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+
+import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
+import org.apache.jackrabbit.jcr2spi.config.RepositoryConfig;
+import org.apache.jackrabbit.spi.RepositoryService;
+import org.apache.jackrabbit.spi.RepositoryServiceFactory;
+import org.apache.jackrabbit.spi.commons.logging.LogWriterProvider;
+import org.apache.jackrabbit.spi.commons.logging.SpiLoggerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This implementation of {@link RepositoryFactory} is capable of returning the various
+ * SPI implementations of the Apache Jackrabbit project:
+ * <ul>
+ * <li>SPI2DAVex (see jackrabbit-spi2dav module)</li>
+ * <li>SPI2DAV (see jackrabbit-spi2dav module)</li>
+ * <li>SPI2JCR (see jackrabbit-spi2jcr module)</li>
+ * </ul>
+ */
+public class Jcr2spiRepositoryFactory implements RepositoryFactory {
+    static final Logger log = LoggerFactory.getLogger(Jcr2spiRepositoryFactory.class);
+
+    /**
+     * This parameter determines the {@link RepositoryServiceFactory} to create the
+     * {@link RepositoryService}. This is either an instance of <code>RepositoryServiceFactory
+     * </code> or a fully quallyfied class name of a <code>RepositoryServiceFactory</code>
+     * having a no argument constructor.
+     */
+    public static final String PARAM_REPOSITORY_SERVICE_FACTORY = "org.apache.jackrabbit.spi.RepositoryServiceFactory";
+
+    /**
+     * This parameter contains the {@link RepositoryConfig} instance.
+     */
+    public static final String PARAM_REPOSITORY_CONFIG = "org.apache.jackrabbit.jcr2spi.RepositoryConfig";
+
+    /**
+     * Optional configuration parameter for {@link RepositoryConfig#getCacheBehaviour()}. This
+     * must be either {@link CacheBehaviour#INVALIDATE} or {@link CacheBehaviour#OBSERVATION}
+     * or one of the strings "invalidate" or "observation".
+     */
+    public static final String PARAM_CACHE_BEHAVIOR = "org.apache.jackrabbit.jcr2spi.CacheBehaviour";
+
+    /**
+     * Default value for {@link #PARAM_CACHE_BEHAVIOR}
+     */
+    public static final CacheBehaviour DEFAULT_CACHE_BEHAVIOR = CacheBehaviour.INVALIDATE;
+
+    /**
+     * Optional configuration parameter for the {@link RepositoryConfig#getItemCacheSize()}. This
+     * must be either an <code>Integer</code> or a String which parses into an integer.
+     */
+    public static final String PARAM_ITEM_CACHE_SIZE = "org.apache.jackrabbit.jcr2spi.ItemCacheSize";
+
+    /**
+     * Default value for {@link #PARAM_ITEM_CACHE_SIZE}
+     */
+    public static final int DEFAULT_ITEM_CACHE_SIZE = 5000;
+
+    /**
+     * Optional configuration parameter for the {@link RepositoryConfig#getPollTimeout()}. This
+     * must be either an <code>Integer</code> or a String which parses into an integer.
+     */
+    public static final String PARAM_POLL_TIME_OUT = "org.apache.jackrabbit.jcr2spi.PollTimeOut";
+
+    /**
+     * Default value for {@link #PARAM_POLL_TIME_OUT}
+     */
+    public static final int DEFAULT_POLL_TIME_OUT = 3000; // milli seconds
+
+    /**
+     * LogWriterProvider configuration parameter: If the parameter is present the
+     * <code>RepositoryService</code> defined by the specified
+     * <code>RepositoryConfig</code> will be wrapped by calling
+     * {@link SpiLoggerFactory#create(org.apache.jackrabbit.spi.RepositoryService, org.apache.jackrabbit.spi.commons.logging.LogWriterProvider) }
+     * if the parameter value is an instance of <code>LogWriterProvider</code> or
+     * {@link SpiLoggerFactory#create(org.apache.jackrabbit.spi.RepositoryService)}
+     * otherwise.
+     *
+     * @see SpiLoggerFactory#create(org.apache.jackrabbit.spi.RepositoryService)
+     * @see SpiLoggerFactory#create(org.apache.jackrabbit.spi.RepositoryService, org.apache.jackrabbit.spi.commons.logging.LogWriterProvider)
+     */
+    public static final String PARAM_LOG_WRITER_PROVIDER = "org.apache.jackrabbit.spi.commons.logging.LogWriterProvider";
+
+    /**
+     * <p>Creates a SPI based <code>Repository</code> instance based on the
+     * <code>parameters</code> passed.</p>
+     *
+     * <p>If the {@link #PARAM_REPOSITORY_SERVICE_FACTORY} parameter is set,
+     * the specified {@link RepositoryServiceFactory} is used to create the
+     * {@link RepositoryService} instance. All parameters are passed to
+     * {@link RepositoryServiceFactory#createRepositoryService(Map)}.</p>
+     *
+     * <p>If the {@link #PARAM_REPOSITORY_CONFIG} parameter is set, the
+     * specified {@link RepositoryConfig} instance is used to create the
+     * repository.</p>
+     *
+     * <p>If both parameters are set, the latter takes precedence and the
+     * former is ignores.</p>
+     *
+     * <p>The known SPI implementations and its <code>RepositoryServiceFactory</code>s are:
+     * <ul>
+     * <li>SPI2DAVex (see jackrabbit-spi2dav module): <code>Spi2davRepositoryServiceFactory</code></li>
+     * <li>SPI2DAV (see jackrabbit-spi2dav module): <code>Spi2davexRepositoryServiceFactory</code></li>
+     * <li>SPI2JCR (see jackrabbit-spi2jcr module) <code>Spi2jcrRepositoryServiceFactory</code></li>
+     * </ul>
+     * </p>
+     *
+     * NOTE: If the <code>parameters</code> map contains an
+     * {@link #PARAM_LOG_WRITER_PROVIDER} entry the
+     * {@link org.apache.jackrabbit.spi.RepositoryService RepositoryService} obtained
+     * from the configuration is wrapped by a SPI logger. See the
+     * {@link org.apache.jackrabbit.spi.commons.logging.SpiLoggerFactory SpiLoggerFactory}
+     * for details.
+     *
+     * @see RepositoryFactory#getRepository(java.util.Map)
+     */
+    public Repository getRepository(@SuppressWarnings("unchecked") Map parameters) throws RepositoryException {
+        RepositoryServiceFactory serviceFactory = getServiceFactory(parameters);
+        Object configParam = parameters.get(PARAM_REPOSITORY_CONFIG);
+
+        if (serviceFactory == null && configParam == null) {
+            return null;
+        }
+
+        RepositoryConfig config;
+        if (configParam instanceof RepositoryConfig) {
+            config = (RepositoryConfig) configParam;
+            if (serviceFactory != null) {
+                log.warn("Ignoring {} since {} was specified", PARAM_REPOSITORY_SERVICE_FACTORY,
+                        PARAM_REPOSITORY_CONFIG);
+            }
+        }
+        else {
+            if (serviceFactory == null) {
+                return null;
+            }
+            else {
+                config = new RepositoryConfigImpl(serviceFactory, parameters);
+            }
+        }
+
+        config = SpiLoggerConfig.wrap(config, parameters);
+        return RepositoryImpl.create(config);
+    }
+
+    // -----------------------------------------------------< private >---
+
+    private static RepositoryServiceFactory getServiceFactory(Map<?, ?> parameters)
+            throws RepositoryException {
+
+        Object serviceFactoryParam = parameters.get(PARAM_REPOSITORY_SERVICE_FACTORY);
+        if (serviceFactoryParam == null) {
+            return null;
+        }
+
+        log.debug("Acquiring RepositoryServiceFactory from {}", PARAM_REPOSITORY_SERVICE_FACTORY);
+
+        if (serviceFactoryParam instanceof RepositoryServiceFactory) {
+            log.debug("Found RepositoryServiceFactory {}", serviceFactoryParam);
+            return (RepositoryServiceFactory) serviceFactoryParam;
+        }
+        else if (serviceFactoryParam instanceof String) {
+            String serviceFactoryName = (String)serviceFactoryParam;
+            log.debug("Found RepositoryServiceFactory class name {}", serviceFactoryName);
+            try {
+                Class<?> serviceFactoryClass = Class.forName(serviceFactoryName, true,
+                            Thread.currentThread().getContextClassLoader());
+
+                Object serviceFactory = serviceFactoryClass.newInstance();
+
+                if (serviceFactory instanceof RepositoryServiceFactory) {
+                    log.debug("Found RepositoryServiceFactory {}", serviceFactory);
+                    return (RepositoryServiceFactory) serviceFactory;
+                }
+                else {
+                    String msg = "Error acquiring RepositoryServiceFactory " + serviceFactoryParam;
+                    log.error(msg);
+                    throw new RepositoryException(msg);
+                }
+            }
+            catch (Exception e) {
+                String msg = "Error acquiring RepositoryServiceFactory";
+                log.error(msg, e);
+                throw new RepositoryException(msg, e);
+            }
+        }
+        else {
+            String msg = "Error acquiring RepositoryServiceFactory from " + serviceFactoryParam;
+            log.error(msg);
+            throw new RepositoryException(msg);
+        }
+    }
+
+    private static class RepositoryConfigImpl implements RepositoryConfig {
+        private final RepositoryServiceFactory serviceFactory;
+        private final CacheBehaviour cacheBehaviour;
+        private final int itemCacheSize;
+        private final int pollTimeOut;
+        private final Map<?, ?> parameters;
+
+        public RepositoryConfigImpl(RepositoryServiceFactory serviceFactory, Map<?, ?> parameters)
+                throws RepositoryException {
+
+            super();
+            this.serviceFactory = serviceFactory;
+            this.cacheBehaviour = getCacheBehaviour(parameters);
+            this.itemCacheSize = getItemChacheSize(parameters);
+            this.pollTimeOut = getPollTimeout(parameters);
+            this.parameters = parameters;
+        }
+
+        public CacheBehaviour getCacheBehaviour() {
+            return cacheBehaviour;
+        }
+
+        public int getItemCacheSize() {
+            return itemCacheSize;
+        }
+
+        public int getPollTimeout() {
+            return pollTimeOut;
+        }
+
+        public RepositoryService getRepositoryService() throws RepositoryException {
+            return serviceFactory.createRepositoryService(parameters);
+        }
+
+        // -----------------------------------------------------< private >---
+
+        private static CacheBehaviour getCacheBehaviour(Map<?, ?> parameters) throws RepositoryException {
+            Object paramCacheBehaviour = parameters.get(PARAM_CACHE_BEHAVIOR);
+            log.debug("Setting CacheBehaviour from {}", PARAM_CACHE_BEHAVIOR);
+
+            if (paramCacheBehaviour == null) {
+                log.debug("{} not set, defaulting to {}", PARAM_CACHE_BEHAVIOR, DEFAULT_CACHE_BEHAVIOR);
+                return DEFAULT_CACHE_BEHAVIOR;
+            }
+            else if (paramCacheBehaviour instanceof CacheBehaviour) {
+                log.debug("Setting CacheBehaviour to {}", paramCacheBehaviour);
+                return (CacheBehaviour) paramCacheBehaviour;
+            }
+            else if (paramCacheBehaviour instanceof String) {
+                String cacheBehaviour = (String) paramCacheBehaviour;
+                if ("invalidate".equals(cacheBehaviour)) {
+                    log.debug("Setting CacheBehaviour to {}", CacheBehaviour.INVALIDATE);
+                    return CacheBehaviour.INVALIDATE;
+                }
+                else if ("observation".equals(cacheBehaviour)) {
+                    log.debug("Setting CacheBehaviour to {}", CacheBehaviour.OBSERVATION);
+                    return CacheBehaviour.OBSERVATION;
+                }
+                else {
+                    log.error("Invalid valid for CacheBehaviour: {}", PARAM_CACHE_BEHAVIOR, cacheBehaviour);
+                    throw new RepositoryException("Invalid value for CacheBehaviour: " + cacheBehaviour);
+                }
+            }
+            else {
+                String msg = "Invalid value for CacheBehaviour: " + paramCacheBehaviour;
+                log.error(msg);
+                throw new RepositoryException(msg);
+            }
+        }
+
+        private static int getItemChacheSize(Map<?, ?> parameters) throws RepositoryException {
+            Object paramItemCacheSize = parameters.get(PARAM_ITEM_CACHE_SIZE);
+            log.debug("Setting ItemChacheSize from {}", PARAM_ITEM_CACHE_SIZE);
+
+            if (paramItemCacheSize == null) {
+                log.debug("{} not set, defaulting to {}", PARAM_ITEM_CACHE_SIZE, DEFAULT_ITEM_CACHE_SIZE);
+                return DEFAULT_ITEM_CACHE_SIZE;
+            }
+            else if (paramItemCacheSize instanceof Integer) {
+                log.debug("Setting ItemChacheSize to {}", paramItemCacheSize);
+                return (Integer) paramItemCacheSize;
+            }
+            else if (paramItemCacheSize instanceof String) {
+                try {
+                    log.debug("Setting ItemChacheSize to {}", paramItemCacheSize);
+                    return Integer.parseInt((String) paramItemCacheSize);
+                }
+                catch (NumberFormatException e) {
+                    String msg = "Invalid value for ItemCacheSize: " + paramItemCacheSize;
+                    log.error(msg);
+                    throw new RepositoryException(msg, e);
+                }
+            }
+            else {
+                String msg = "Invalid value for ItemCacheSize: " + paramItemCacheSize;
+                log.error(msg);
+                throw new RepositoryException(msg);
+            }
+        }
+
+        private static int getPollTimeout(Map<?, ?> parameters) throws RepositoryException {
+            Object paramPollTimeOut = parameters.get(PARAM_POLL_TIME_OUT);
+            log.debug("Setting PollTimeout from {}", PARAM_POLL_TIME_OUT);
+
+            if (paramPollTimeOut == null) {
+                log.debug("{} not set, defaulting to {}", PARAM_POLL_TIME_OUT, DEFAULT_POLL_TIME_OUT);
+                return DEFAULT_POLL_TIME_OUT;
+            }
+            else if (paramPollTimeOut instanceof Integer) {
+                log.debug("Setting PollTimeout to {}", paramPollTimeOut);
+                return (Integer) paramPollTimeOut;
+            }
+            else if (paramPollTimeOut instanceof String) {
+                try {
+                    log.debug("Setting PollTimeout to {}", paramPollTimeOut);
+                    return Integer.parseInt((String) paramPollTimeOut);
+                }
+                catch (NumberFormatException e) {
+                    String msg = "Invalid value for PollTimeout: " + paramPollTimeOut;
+                    log.error(msg);
+                    throw new RepositoryException(msg, e);
+                }
+            }
+            else {
+                String msg = "Invalid value for PollTimeout: " + paramPollTimeOut;
+                log.error(msg);
+                throw new RepositoryException(msg);
+            }
+        }
+
+    }
+
+    private static class SpiLoggerConfig implements RepositoryConfig {
+        private final RepositoryConfig config;
+        private final RepositoryService service;
+
+        private SpiLoggerConfig(RepositoryConfig config, Map<?, ?> parameters) throws RepositoryException {
+            super();
+            this.config = config;
+
+            Object lwProvider = parameters.get(PARAM_LOG_WRITER_PROVIDER);
+            if (lwProvider instanceof LogWriterProvider) {
+                service = SpiLoggerFactory.create(config.getRepositoryService(), (LogWriterProvider) lwProvider);
+            }
+            else {
+                service = SpiLoggerFactory.create(config.getRepositoryService());
+            }
+        }
+
+        public static RepositoryConfig wrap(RepositoryConfig config, Map<?, ?> parameters)
+                throws RepositoryException {
+
+            if (config == null || parameters == null || !parameters.containsKey(PARAM_LOG_WRITER_PROVIDER)) {
+                return config;
+            } else {
+                return new SpiLoggerConfig(config, parameters);
+            }
+        }
+
+        public CacheBehaviour getCacheBehaviour() {
+            return config.getCacheBehaviour();
+        }
+
+        public int getItemCacheSize() {
+            return config.getItemCacheSize();
+        }
+
+        public int getPollTimeout() {
+            return config.getPollTimeout();
+        }
+
+        public RepositoryService getRepositoryService() throws RepositoryException {
+            return service;
+        }
+
+    }
+
+}

Propchange: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/Jcr2spiRepositoryFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/resources/META-INF/services/javax.jcr.RepositoryFactory
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/resources/META-INF/services/javax.jcr.RepositoryFactory?rev=816402&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/resources/META-INF/services/javax.jcr.RepositoryFactory (added)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/resources/META-INF/services/javax.jcr.RepositoryFactory Thu Sep 17 22:52:14 2009
@@ -0,0 +1,17 @@
+#  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.
+
+org.apache.jackrabbit.jcr2spi.factory.Jcr2spiRepositoryFactory
+

Added: jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryServiceFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryServiceFactory.java?rev=816402&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryServiceFactory.java (added)
+++ jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryServiceFactory.java Thu Sep 17 22:52:14 2009
@@ -0,0 +1,38 @@
+/*
+ * 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.jackrabbit.spi;
+
+import java.util.Map;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * Factory for creating {@link RepositoryService} instances. Implementations must
+ * provide a no argument constructor.
+ */
+public interface RepositoryServiceFactory {
+
+    /**
+     * Create a new {@link RepositoryService}. If the factory does not understand the
+     * passed <code>parameters</code> it <em>must</em> return <code>null</code>.
+     * @param parameters  implementation specific set of parameters
+     * @return  a fresh <code>RepositoryService</code> instance or <code>null</code>.
+     * @throws RepositoryException  If there was an error creating the
+     *     <code>RepositoryService</code> instance
+     */
+    public RepositoryService createRepositoryService(Map<?, ?> parameters) throws RepositoryException;
+}

Propchange: jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryServiceFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/Spi2davRepositoryServiceFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/Spi2davRepositoryServiceFactory.java?rev=816402&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/Spi2davRepositoryServiceFactory.java (added)
+++ jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/Spi2davRepositoryServiceFactory.java Thu Sep 17 22:52:14 2009
@@ -0,0 +1,119 @@
+/*
+ * 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.jackrabbit.spi2dav;
+
+import java.util.Map;
+
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.spi.IdFactory;
+import org.apache.jackrabbit.spi.NameFactory;
+import org.apache.jackrabbit.spi.PathFactory;
+import org.apache.jackrabbit.spi.QValueFactory;
+import org.apache.jackrabbit.spi.RepositoryService;
+import org.apache.jackrabbit.spi.RepositoryServiceFactory;
+import org.apache.jackrabbit.spi.commons.identifier.IdFactoryImpl;
+import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
+import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl;
+import org.apache.jackrabbit.spi.commons.value.QValueFactoryImpl;
+
+/**
+ * This {@link RepositoryServiceFactory} implementation is responsible
+ * for creating {@link RepositoryServiceImpl} instances.
+ */
+public class Spi2davRepositoryServiceFactory implements RepositoryServiceFactory {
+
+    /**
+     * Mandatory configuration parameter: It's value is expected to specify the
+     * URI of the JCR server implementation.
+     *
+     * @see org.apache.jackrabbit.webdav.jcr.JCRWebdavServerServlet
+     */
+    public static final String PARAM_REPOSITORY_URI = "org.apache.jackrabbit.spi2dav.uri";
+
+    /**
+     * Optional configuration parameter: It's value is expected to be an instance
+     * of {@link IdFactory}. If missing {@link IdFactoryImpl} is used.
+     */
+    public static final String PARAM_ID_FACTORY = "org.apache.jackrabbit.spi2dav.IdFactory";
+
+    /**
+     * Optional configuration parameter: It's value is expected to be an instance
+     * of {@link NameFactory}. If missing {@link NameFactoryImpl} is used.
+     */
+    public static final String PARAM_NAME_FACTORY = "org.apache.jackrabbit.spi2dav.NameFactory";
+
+    /**
+     * Optional configuration parameter: It's value is expected to be an instance
+     * of {@link PathFactory}. If missing {@link PathFactoryImpl} is used.
+     */
+    public static final String PARAM_PATH_FACTORY = "org.apache.jackrabbit.spi2dav.PathFactory";
+
+    /**
+     * Optional configuration parameter: It's value is expected to be an instance
+     * of {@link QValueFactory}. If missing {@link QValueFactoryImpl} is used.
+     */
+    public static final String PARAM_QVALUE_FACTORY = "org.apache.jackrabbit.spi2dav.QValueFactory";
+
+    public RepositoryService createRepositoryService(Map<?, ?> parameters) throws RepositoryException {
+        if (parameters == null) {
+            throw new RepositoryException("Parameter " + PARAM_REPOSITORY_URI + " missing");
+        }
+
+        String uri;
+        if (parameters.get(PARAM_REPOSITORY_URI) == null) {
+            throw new RepositoryException("Parameter " + PARAM_REPOSITORY_URI + " missing");
+        }
+        else {
+            uri = parameters.get(PARAM_REPOSITORY_URI).toString();
+        }
+
+        IdFactory idFactory;
+        Object param = parameters.get(PARAM_ID_FACTORY);
+        if (param != null && param instanceof IdFactory) {
+            idFactory = (IdFactory) param;
+        } else {
+            idFactory = IdFactoryImpl.getInstance();
+        }
+
+        NameFactory nameFactory;
+        param = parameters.get(PARAM_NAME_FACTORY);
+        if (param != null && param instanceof NameFactory) {
+            nameFactory = (NameFactory) param;
+        } else {
+            nameFactory = NameFactoryImpl.getInstance();
+        }
+
+        PathFactory pathFactory;
+        param = parameters.get(PARAM_PATH_FACTORY);
+        if (param != null && param instanceof PathFactory) {
+            pathFactory = (PathFactory) param;
+        } else {
+            pathFactory = PathFactoryImpl.getInstance();
+        }
+
+        QValueFactory vFactory;
+        param = parameters.get(PARAM_QVALUE_FACTORY);
+        if (param != null && param instanceof QValueFactory) {
+            vFactory = (QValueFactory) param;
+        } else {
+            vFactory = QValueFactoryImpl.getInstance();
+        }
+        return new RepositoryServiceImpl(uri, idFactory, nameFactory, pathFactory, vFactory);
+    }
+
+}

Propchange: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/Spi2davRepositoryServiceFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/Spi2davexRepositoryServiceFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/Spi2davexRepositoryServiceFactory.java?rev=816402&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/Spi2davexRepositoryServiceFactory.java (added)
+++ jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/Spi2davexRepositoryServiceFactory.java Thu Sep 17 22:52:14 2009
@@ -0,0 +1,90 @@
+/*
+ * 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.jackrabbit.spi2davex;
+
+import java.util.Map;
+
+import javax.jcr.NamespaceException;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.spi.Path;
+import org.apache.jackrabbit.spi.RepositoryService;
+import org.apache.jackrabbit.spi.RepositoryServiceFactory;
+import org.apache.jackrabbit.spi.commons.conversion.PathResolver;
+
+/**
+ * This {@link RepositoryServiceFactory} implementation is responsible
+ * for creating {@link RepositoryServiceImpl} instances.
+ */
+public class Spi2davexRepositoryServiceFactory implements RepositoryServiceFactory {
+
+    /**
+     * Mandatory configuration parameter: It's value is expected to specify the
+     * URI of the JCR server implementation. {@link #DEFAULT_REPOSITORY_URI} is used as
+     * fallback if no parameters or uri has been specified and the uri could not
+     * been retrieved from system props either.
+     *
+     * @see org.apache.jackrabbit.server.remoting.davex.JcrRemotingServlet
+     */
+    public static final String PARAM_REPOSITORY_URI = "org.apache.jackrabbit.spi2davex.uri";
+
+    /**
+     * Default URI for the {@link #PARAM_REPOSITORY_URI} configuration
+     * parameter.
+     */
+    public static String DEFAULT_REPOSITORY_URI = "http://localhost:8080/jackrabbit/server";
+
+    /**
+     * Optional batch read configuration parameter: If present it's value is
+     * expected to be an instance of {@link BatchReadConfig}
+     */
+    public static final String PARAM_BATCHREAD_CONFIG = "org.apache.jackrabbit.spi2dav.BatchReadConfig";
+
+    public RepositoryService createRepositoryService(Map<?, ?> parameters) throws RepositoryException {
+        String uri;
+
+        if (parameters == null) {
+            uri = System.getProperty(PARAM_REPOSITORY_URI);
+        }
+        else {
+            uri = parameters.get(PARAM_REPOSITORY_URI) == null
+                    ? null
+                    : parameters.get(PARAM_REPOSITORY_URI).toString();
+        }
+        if (uri == null) {
+            uri = DEFAULT_REPOSITORY_URI;
+        }
+
+        BatchReadConfig brc = null;
+        if (parameters != null) {
+            Object param = parameters.get(PARAM_BATCHREAD_CONFIG);
+            if (param != null && param instanceof BatchReadConfig) {
+                brc = (BatchReadConfig) param;
+            }
+        }
+        if (brc == null) {
+            brc = new BatchReadConfig() {
+                public int getDepth(Path path, PathResolver pathResolver) throws NamespaceException {
+                    return 4;
+                }
+            };
+        }
+
+        return new RepositoryServiceImpl(uri, brc);
+    }
+
+}

Propchange: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/Spi2davexRepositoryServiceFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/Spi2jcrRepositoryServiceFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/Spi2jcrRepositoryServiceFactory.java?rev=816402&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/Spi2jcrRepositoryServiceFactory.java (added)
+++ jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/Spi2jcrRepositoryServiceFactory.java Thu Sep 17 22:52:14 2009
@@ -0,0 +1,63 @@
+/*
+ * 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.jackrabbit.spi2jcr;
+
+import java.util.Map;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.spi.RepositoryService;
+import org.apache.jackrabbit.spi.RepositoryServiceFactory;
+
+public class Spi2jcrRepositoryServiceFactory implements RepositoryServiceFactory {
+
+    /**
+     * Mandatory repository parameter: expects value to be an instance of {@link javax.jcr.Repository}.
+     */
+    public static final String PARAM_REPOSITORY = "org.apache.jackrabbit.spi2jcr.Repository";
+
+    /**
+     * Optional batch read configuration parameter. If it is present the value is
+     * expected to be an instance of {@link org.apache.jackrabbit.spi2jcr.BatchReadConfig}.
+     */
+    public static final String PARAM_BATCH_READ_CONFIG = "org.apache.jackrabbit.spi2jcr.BatchReadConfig";
+
+
+    public RepositoryService createRepositoryService(Map<?, ?> parameters) throws RepositoryException {
+        if (parameters == null) {
+            throw new RepositoryException("Parameter " + PARAM_REPOSITORY + " missing");
+        }
+
+        Object repo = parameters.get(PARAM_REPOSITORY);
+        if (repo == null || !(repo instanceof Repository)) {
+            throw new RepositoryException("Parameter " + PARAM_REPOSITORY + " missing or not an instance of Repository");
+        }
+
+        BatchReadConfig brConfig;
+        Object obj = parameters.get(PARAM_BATCH_READ_CONFIG);
+        if (obj != null && obj instanceof BatchReadConfig) {
+            brConfig = (BatchReadConfig) obj;
+        }
+        else {
+            brConfig = new BatchReadConfig();
+        }
+
+        return new RepositoryServiceImpl((Repository) repo, brConfig);
+    }
+
+}

Propchange: jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/Spi2jcrRepositoryServiceFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native