Improve JCR
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 19 Apr 2010 10:13:24 +0000 (10:13 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 19 Apr 2010 10:13:24 +0000 (10:13 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@3478 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/BeanNodeMapper.java
server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/JcrUtils.java
server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/server/jackrabbit/JackrabbitContainer.java
server/runtime/org.argeo.server.jackrabbit/src/main/resources/org/argeo/server/jackrabbit/repository-inMemory.xml

index 6f282bac7177143da530bc4f55df4d5b7f0f4c4c..a526bcf5ec0d06ed838392baa08aabfbccd38bb1 100644 (file)
@@ -22,14 +22,12 @@ import javax.jcr.Session;
 import javax.jcr.Value;
 import javax.jcr.ValueFactory;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.argeo.ArgeoException;
 import org.springframework.beans.BeanWrapper;
 import org.springframework.beans.BeanWrapperImpl;
 
 public class BeanNodeMapper implements NodeMapper {
-       private final static Log log = LogFactory.getLog(BeanNodeMapper.class);
+       // private final static Log log = LogFactory.getLog(BeanNodeMapper.class);
 
        private final static String NODE_VALUE = "value";
 
@@ -99,7 +97,6 @@ public class BeanNodeMapper implements NodeMapper {
         */
        public Node save(Session session, String path, Object obj) {
                try {
-                       BeanWrapper beanWrapper = createBeanWrapper(obj);
                        final Node node;
                        String parentPath = JcrUtils.parentPath(path);
                        // find or create parent node
@@ -120,7 +117,6 @@ public class BeanNodeMapper implements NodeMapper {
 
                        // Check specific cases
                        if (nodeMapperProvider != null) {
-
                                NodeMapper nodeMapper = nodeMapperProvider.findNodeMapper(node);
                                if (nodeMapper != this) {
                                        nodeMapper.update(node, obj);
@@ -158,124 +154,128 @@ public class BeanNodeMapper implements NodeMapper {
         */
        protected Object nodeToBean(Node node) throws RepositoryException {
 
-               String clssName = node.getProperty(classProperty).getValue()
-                               .getString();
-
-               BeanWrapper beanWrapper = createBeanWrapper(loadClass(clssName));
-
-               // process properties
-               PropertyIterator propIt = node.getProperties();
-               props: while (propIt.hasNext()) {
-                       Property prop = propIt.nextProperty();
-                       if (!beanWrapper.isWritableProperty(prop.getName()))
-                               continue props;
-
-                       PropertyDescriptor pd = beanWrapper.getPropertyDescriptor(prop
-                                       .getName());
-                       Class propClass = pd.getPropertyType();
-
-                       // Process case of List and its derived classes
-                       // primitive list
-                       if (propClass != null && List.class.isAssignableFrom(propClass)) {
-                               List<Object> lst = new ArrayList<Object>();
-                               Class<?> valuesClass = classFromProperty(prop);
-                               if (valuesClass != null)
-                                       for (Value value : prop.getValues()) {
-                                               lst.add(asObject(value, valuesClass));
-                                       }
-                               continue props;
+               try {
+                       String clssName = node.getProperty(classProperty).getValue()
+                                       .getString();
+
+                       BeanWrapper beanWrapper = createBeanWrapper(loadClass(clssName));
+
+                       // process properties
+                       PropertyIterator propIt = node.getProperties();
+                       props: while (propIt.hasNext()) {
+                               Property prop = propIt.nextProperty();
+                               if (!beanWrapper.isWritableProperty(prop.getName()))
+                                       continue props;
+
+                               PropertyDescriptor pd = beanWrapper.getPropertyDescriptor(prop
+                                               .getName());
+                               Class propClass = pd.getPropertyType();
+
+                               // Process case of List and its derived classes
+                               // primitive list
+                               if (propClass != null && List.class.isAssignableFrom(propClass)) {
+                                       List<Object> lst = new ArrayList<Object>();
+                                       Class<?> valuesClass = classFromProperty(prop);
+                                       if (valuesClass != null)
+                                               for (Value value : prop.getValues()) {
+                                                       lst.add(asObject(value, valuesClass));
+                                               }
+                                       continue props;
+                               }
+
+                               // Case of other type of property accepted by jcr
+                               // Long, Double, String, Binary, Date, Boolean, Name
+                               Object value = asObject(prop.getValue(), pd.getPropertyType());
+                               if (value != null)
+                                       beanWrapper.setPropertyValue(prop.getName(), value);
                        }
 
-                       // Case of other type of property accepted by jcr
-                       // Long, Double, String, Binary, Date, Boolean, Name
-                       Object value = asObject(prop.getValue(), pd.getPropertyType());
-                       if (value != null)
-                               beanWrapper.setPropertyValue(prop.getName(), value);
-               }
+                       // process children nodes
+                       NodeIterator nodeIt = node.getNodes();
+                       nodes: while (nodeIt.hasNext()) {
+                               Node childNode = nodeIt.nextNode();
+                               String name = childNode.getName();
+                               if (!beanWrapper.isWritableProperty(name))
+                                       continue nodes;
+
+                               PropertyDescriptor pd = beanWrapper.getPropertyDescriptor(name);
+                               Class propClass = pd.getPropertyType();
+
+                               // objects list
+                               if (propClass != null && List.class.isAssignableFrom(propClass)) {
+                                       String lstClass = childNode.getProperty(classProperty)
+                                                       .getString();
+                                       List<Object> lst;
+                                       try {
+                                               lst = (List<Object>) loadClass(lstClass).newInstance();
+                                       } catch (Exception e) {
+                                               lst = new ArrayList<Object>();
+                                       }
 
-               // process children nodes
-               NodeIterator nodeIt = node.getNodes();
-               nodes: while (nodeIt.hasNext()) {
-                       Node childNode = nodeIt.nextNode();
-                       String name = childNode.getName();
-                       if (!beanWrapper.isWritableProperty(name))
-                               continue nodes;
-
-                       PropertyDescriptor pd = beanWrapper.getPropertyDescriptor(name);
-                       Class propClass = pd.getPropertyType();
-
-                       // objects list
-                       if (propClass != null && List.class.isAssignableFrom(propClass)) {
-                               String lstClass = childNode.getProperty(classProperty)
-                                               .getString();
-                               List<Object> lst;
-                               try {
-                                       lst = (List<Object>) loadClass(lstClass).newInstance();
-                               } catch (Exception e) {
-                                       lst = new ArrayList<Object>();
-                               }
+                                       NodeIterator valuesIt = childNode.getNodes();
+                                       while (valuesIt.hasNext()) {
+                                               Node lstValueNode = valuesIt.nextNode();
+                                               Object lstValue = nodeToBean(lstValueNode);
+                                               lst.add(lstValue);
+                                       }
 
-                               NodeIterator valuesIt = childNode.getNodes();
-                               while (valuesIt.hasNext()) {
-                                       Node lstValueNode = valuesIt.nextNode();
-                                       Object lstValue = nodeToBean(lstValueNode);
-                                       lst.add(lstValue);
+                                       beanWrapper.setPropertyValue(name, lst);
+                                       continue nodes;
                                }
 
-                               beanWrapper.setPropertyValue(name, lst);
-                               continue nodes;
-                       }
-
-                       // objects map
-                       if (propClass != null && Map.class.isAssignableFrom(propClass)) {
-                               String mapClass = childNode.getProperty(classProperty)
-                                               .getString();
-                               Map<Object, Object> map;
-                               try {
-                                       map = (Map<Object, Object>) loadClass(mapClass)
-                                                       .newInstance();
-                               } catch (Exception e) {
-                                       map = new HashMap<Object, Object>();
-                               }
+                               // objects map
+                               if (propClass != null && Map.class.isAssignableFrom(propClass)) {
+                                       String mapClass = childNode.getProperty(classProperty)
+                                                       .getString();
+                                       Map<Object, Object> map;
+                                       try {
+                                               map = (Map<Object, Object>) loadClass(mapClass)
+                                                               .newInstance();
+                                       } catch (Exception e) {
+                                               map = new HashMap<Object, Object>();
+                                       }
 
-                               // properties
-                               PropertyIterator keysPropIt = childNode.getProperties();
-                               keyProps: while (keysPropIt.hasNext()) {
-                                       Property keyProp = keysPropIt.nextProperty();
-                                       // FIXME: use property editor
-                                       String key = keyProp.getName();
-                                       if (classProperty.equals(key))
-                                               continue keyProps;
-
-                                       Class keyPropClass = classFromProperty(keyProp);
-                                       if (keyPropClass != null) {
-                                               Object mapValue = asObject(keyProp.getValue(),
-                                                               keyPropClass);
-                                               map.put(key, mapValue);
+                                       // properties
+                                       PropertyIterator keysPropIt = childNode.getProperties();
+                                       keyProps: while (keysPropIt.hasNext()) {
+                                               Property keyProp = keysPropIt.nextProperty();
+                                               // FIXME: use property editor
+                                               String key = keyProp.getName();
+                                               if (classProperty.equals(key))
+                                                       continue keyProps;
+
+                                               Class keyPropClass = classFromProperty(keyProp);
+                                               if (keyPropClass != null) {
+                                                       Object mapValue = asObject(keyProp.getValue(),
+                                                                       keyPropClass);
+                                                       map.put(key, mapValue);
+                                               }
                                        }
-                               }
 
-                               // node
-                               NodeIterator keysIt = childNode.getNodes();
-                               while (keysIt.hasNext()) {
-                                       Node mapValueNode = keysIt.nextNode();
-                                       // FIXME: use property editor
-                                       Object key = mapValueNode.getName();
+                                       // node
+                                       NodeIterator keysIt = childNode.getNodes();
+                                       while (keysIt.hasNext()) {
+                                               Node mapValueNode = keysIt.nextNode();
+                                               // FIXME: use property editor
+                                               Object key = mapValueNode.getName();
 
-                                       Object mapValue = nodeToBean(mapValueNode);
+                                               Object mapValue = nodeToBean(mapValueNode);
 
-                                       map.put(key, mapValue);
+                                               map.put(key, mapValue);
+                                       }
+                                       beanWrapper.setPropertyValue(name, map);
+                                       continue nodes;
                                }
-                               beanWrapper.setPropertyValue(name, map);
-                               continue nodes;
-                       }
 
-                       // default
-                       Object value = nodeToBean(childNode);
-                       beanWrapper.setPropertyValue(name, value);
+                               // default
+                               Object value = nodeToBean(childNode);
+                               beanWrapper.setPropertyValue(name, value);
 
+                       }
+                       return beanWrapper.getWrappedInstance();
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot map node " + node, e);
                }
-               return beanWrapper.getWrappedInstance();
        }
 
        /**
index 8792a36de3aeb3e79d02f2376c68aaf9baee4660..bf199ffdaed882a7720d6322ffd70a56e8b3ca83 100644 (file)
@@ -38,10 +38,10 @@ public class JcrUtils {
                        throw new ArgeoException("Query returned more than one node.");
                return node;
        }
-       
-       public static String removeForbiddenCharacters(String str){
-               return str.replace('[', '_').replace(']', '_')
-               .replace('/', '_').replace('*', '_');
+
+       public static String removeForbiddenCharacters(String str) {
+               return str.replace('[', '_').replace(']', '_').replace('/', '_')
+                               .replace('*', '_');
 
        }
 
@@ -146,8 +146,8 @@ public class JcrUtils {
 
                // Then output the properties
                PropertyIterator properties = node.getProperties();
-               //log.debug("Property are : ");
-               
+               // log.debug("Property are : ");
+
                while (properties.hasNext()) {
                        Property property = properties.nextProperty();
                        if (property.getDefinition().isMultiple()) {
index 21209b51120065e564853ac3a4d167393606d188..f6ae9357e201457a6eb8f439088b807f078f2b1b 100644 (file)
@@ -12,6 +12,8 @@ import javax.jcr.Session;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.core.RepositoryImpl;
 import org.apache.jackrabbit.core.TransientRepository;
 import org.apache.jackrabbit.core.config.RepositoryConfig;
@@ -21,6 +23,8 @@ import org.springframework.core.io.Resource;
 
 public class JackrabbitContainer implements InitializingBean, DisposableBean,
                Repository {
+       private Log log = LogFactory.getLog(JackrabbitContainer.class);
+
        private Resource configuration;
        private File homeDirectory;
 
@@ -29,6 +33,11 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
        private Repository repository;
 
        public void afterPropertiesSet() throws Exception {
+               if (inMemory && homeDirectory.exists()) {
+                       FileUtils.deleteDirectory(homeDirectory);
+                       log.warn("Deleted Jackrabbit home directory " + homeDirectory);
+               }
+
                RepositoryConfig config;
                InputStream in = configuration.getInputStream();
                try {
@@ -44,6 +53,9 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
                        repository = new TransientRepository(config);
                else
                        repository = RepositoryImpl.create(config);
+
+               log.info("Initialized Jackrabbit repository " + repository + " in "
+                               + homeDirectory + " with config " + configuration);
        }
 
        public void destroy() throws Exception {
@@ -55,8 +67,14 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
                }
 
                if (inMemory)
-                       if (homeDirectory.exists())
+                       if (homeDirectory.exists()) {
                                FileUtils.deleteDirectory(homeDirectory);
+                               if (log.isDebugEnabled())
+                                       log.debug("Deleted Jackrabbit home directory "
+                                                       + homeDirectory);
+                       }
+               log.info("Destroyed Jackrabbit repository " + repository + " in "
+                               + homeDirectory + " with config " + configuration);
        }
 
        // JCR REPOSITORY (delegated)
@@ -97,4 +115,8 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
                this.configuration = configuration;
        }
 
+       public void setInMemory(Boolean inMemory) {
+               this.inMemory = inMemory;
+       }
+
 }
index f05192337f134fd11a1d6bf8e4eb78a767abe2fd..d980f8bd1f575cb3f6a0dd9ba495be19657eb959 100644 (file)
 <?xml version="1.0"?>
-<!--
-   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
+       <!--
+               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.
--->
+               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.
+       -->
 <!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
                             "http://jackrabbit.apache.org/dtd/repository-1.6.dtd">
-<!-- Example Repository Configuration File
-     Used by
-     - org.apache.jackrabbit.core.config.RepositoryConfigTest.java
-     -
--->
+       <!--
+               Example Repository Configuration File Used by -
+               org.apache.jackrabbit.core.config.RepositoryConfigTest.java -
+       -->
 <Repository>
-    <!--
-        virtual file system where the repository stores global state
-        (e.g. registered namespaces, custom node types, etc.)
-    -->
-    <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
-        <param name="path" value="${rep.home}/repository"/>
-    </FileSystem>
+       <!--
+               virtual file system where the repository stores global state (e.g.
+               registered namespaces, custom node types, etc.)
+       -->
+       <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+               <param name="path" value="${rep.home}/repository" />
+       </FileSystem>
 
-    <!--
+       <!--
         security configuration
     -->
-    <Security appName="Jackrabbit">
-        <!--
-            security manager:
-            class: FQN of class implementing the JackrabbitSecurityManager interface
-        -->
-        <SecurityManager class="org.apache.jackrabbit.core.security.simple.SimpleSecurityManager" workspaceName="security">
-            <!--
-            workspace access:
-            class: FQN of class implementing the WorkspaceAccessManager interface
-            -->
-            <!-- <WorkspaceAccessManager class="..."/> -->
-            <!-- <param name="config" value="${rep.home}/security.xml"/> -->
-        </SecurityManager>
+       <Security appName="Jackrabbit">
+               <!--
+                       security manager: class: FQN of class implementing the
+                       JackrabbitSecurityManager interface
+               -->
+               <SecurityManager
+                       class="org.apache.jackrabbit.core.security.simple.SimpleSecurityManager"
+                       workspaceName="security">
+                       <!--
+                               workspace access: class: FQN of class implementing the
+                               WorkspaceAccessManager interface
+                       -->
+                       <!-- <WorkspaceAccessManager class="..."/> -->
+                       <!-- <param name="config" value="${rep.home}/security.xml"/> -->
+               </SecurityManager>
 
-        <!--
-            access manager:
-            class: FQN of class implementing the AccessManager interface
-        -->
-        <AccessManager class="org.apache.jackrabbit.core.security.simple.SimpleAccessManager">
-            <!-- <param name="config" value="${rep.home}/access.xml"/> -->
-        </AccessManager>
+               <!--
+                       access manager: class: FQN of class implementing the AccessManager
+                       interface
+               -->
+               <AccessManager
+                       class="org.apache.jackrabbit.core.security.simple.SimpleAccessManager">
+                       <!-- <param name="config" value="${rep.home}/access.xml"/> -->
+               </AccessManager>
 
-        <LoginModule class="org.apache.jackrabbit.core.security.simple.SimpleLoginModule">
-           <!-- 
-              anonymous user name ('anonymous' is the default value)
-            -->
-           <param name="anonymousId" value="anonymous"/>
-           <!--
-              administrator user id (default value if param is missing is 'admin')
-            -->
-           <param name="adminId" value="admin"/>
-        </LoginModule>
-    </Security>
+               <LoginModule
+                       class="org.apache.jackrabbit.core.security.simple.SimpleLoginModule">
+                       <!--
+                               anonymous user name ('anonymous' is the default value)
+                       -->
+                       <param name="anonymousId" value="anonymous" />
+                       <!--
+                               administrator user id (default value if param is missing is 'admin')
+                       -->
+                       <param name="adminId" value="admin" />
+               </LoginModule>
+       </Security>
 
-    <!--
-        location of workspaces root directory and name of default workspace
-    -->
-    <Workspaces rootPath="${rep.home}/workspaces" defaultWorkspace="default"/>
-    <!--
-        workspace configuration template:
-        used to create the initial workspace if there's no workspace yet
-    -->
-    <Workspace name="${wsp.name}">
-        <!--
-            virtual file system of the workspace:
-            class: FQN of class implementing the FileSystem interface
-        -->
-        <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
-            <param name="path" value="${wsp.home}"/>
-        </FileSystem>
-        <!--
-            persistence manager of the workspace:
-            class: FQN of class implementing the PersistenceManager interface
-        -->
-        <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.DerbyPersistenceManager">
-          <param name="url" value="jdbc:derby:memory:db;create=true"/>
-          <param name="schemaObjectPrefix" value="${wsp.name}_"/>
-        </PersistenceManager>
-        <!--
-            Search index and the file system it uses.
-            class: FQN of class implementing the QueryHandler interface
-        -->
-        <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-            <param name="path" value="${wsp.home}/index"/>
-            <param name="extractorPoolSize" value="2"/>
-            <param name="supportHighlighting" value="true"/>
-        </SearchIndex>
-    </Workspace>
+       <!--
+               location of workspaces root directory and name of default workspace
+       -->
+       <Workspaces rootPath="${rep.home}/workspaces"
+               defaultWorkspace="default" />
+       <!--
+               workspace configuration template: used to create the initial workspace
+               if there's no workspace yet
+       -->
+       <Workspace name="${wsp.name}">
+               <!--
+                       virtual file system of the workspace: class: FQN of class
+                       implementing the FileSystem interface
+               -->
+               <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+                       <param name="path" value="${wsp.home}" />
+               </FileSystem>
+               <!--
+                       persistence manager of the workspace: class: FQN of class
+                       implementing the PersistenceManager interface
+               -->
+               <PersistenceManager
+                       class="org.apache.jackrabbit.core.persistence.bundle.DerbyPersistenceManager">
+                       <!--
+                               <param name="url" value="jdbc:derby:memory:db;create=true" />
+                       -->
+                       <param name="url" value="jdbc:derby:${wsp.home}/db;create=true" />
+                       <param name="driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
+                       <param name="schemaObjectPrefix" value="${wsp.name}_" />
+               </PersistenceManager>
+               <!--
+                       Search index and the file system it uses. class: FQN of class
+                       implementing the QueryHandler interface
+               -->
+               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+                       <param name="path" value="${wsp.home}/index" />
+                       <param name="extractorPoolSize" value="2" />
+                       <param name="supportHighlighting" value="true" />
+               </SearchIndex>
+       </Workspace>
 
-    <!--
+       <!--
         Configures the versioning
     -->
-    <Versioning rootPath="${rep.home}/version">
-        <!--
-            Configures the filesystem to use for versioning for the respective
-            persistence manager
-        -->
-        <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
-            <param name="path" value="${rep.home}/version" />
-        </FileSystem>
+       <Versioning rootPath="${rep.home}/version">
+               <!--
+                       Configures the filesystem to use for versioning for the respective
+                       persistence manager
+               -->
+               <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+                       <param name="path" value="${rep.home}/version" />
+               </FileSystem>
 
-        <!--
-            Configures the persistence manager to be used for persisting version state.
-            Please note that the current versioning implementation is based on
-            a 'normal' persistence manager, but this could change in future
-            implementations.
-        -->
-        <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.DerbyPersistenceManager">
-          <param name="url" value="jdbc:derby:memory:version;create=true"/>
-          <param name="schemaObjectPrefix" value="version_"/>
-        </PersistenceManager>
-    </Versioning>
+               <!--
+                       Configures the persistence manager to be used for persisting version
+                       state. Please note that the current versioning implementation is
+                       based on a 'normal' persistence manager, but this could change in
+                       future implementations.
+               -->
+               <PersistenceManager
+                       class="org.apache.jackrabbit.core.persistence.bundle.DerbyPersistenceManager">
+                       <!--
+                               <param name="url" value="jdbc:derby:memory:version;create=true" />
+                       -->
+                       <param name="url" value="jdbc:derby:${rep.home}/version/db;create=true" />
+                       <param name="driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
+                       <param name="schemaObjectPrefix" value="version_" />
+               </PersistenceManager>
+       </Versioning>
 
-    <!--
-        Search index for content that is shared repository wide
-        (/jcr:system tree, contains mainly versions)
-    -->
-    <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-        <param name="path" value="${rep.home}/repository/index"/>
-        <param name="extractorPoolSize" value="2"/>
-        <param name="supportHighlighting" value="true"/>
-    </SearchIndex>
+       <!--
+               Search index for content that is shared repository wide (/jcr:system
+               tree, contains mainly versions)
+       -->
+       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+               <param name="path" value="${rep.home}/repository/index" />
+               <param name="extractorPoolSize" value="2" />
+               <param name="supportHighlighting" value="true" />
+       </SearchIndex>
 </Repository>