Improve CMS initialisation
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 24 Feb 2015 21:45:08 +0000 (21:45 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 24 Feb 2015 21:45:08 +0000 (21:45 +0000)
Publish additional repositories as WebDav / JCR remoting

git-svn-id: https://svn.argeo.org/commons/trunk@7944 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

demo/argeo_node_rap.properties
org.argeo.cms/src/org/argeo/cms/internal/auth/AbstractLoginModule.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/JackrabbitNode.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/Kernel.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelUtils.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeHttp.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/repository-h2.xml
org.argeo.cms/src/org/argeo/cms/internal/kernel/repository-memory.xml
org.argeo.cms/src/org/argeo/cms/internal/kernel/repository-postgresql.xml

index 768976ec1e255468189d497183a0c431c34507b2..5aceaa68aafc111dd6f2c95dbb42ed9988a3c2b9 100644 (file)
@@ -1,24 +1,22 @@
-argeo.osgi.start.3.node=\
-org.eclipse.equinox.http.servlet,\
-org.eclipse.equinox.http.jetty,\
-org.eclipse.rap.rwt.osgi
+argeo.osgi.start.2.node=\
+org.argeo.cms
 
-argeo.osgi.start.4.node=\
-org.argeo.cms,\
+argeo.osgi.start.3.http=\
+org.eclipse.equinox.http.servlet,\
+org.eclipse.equinox.http.jetty
 
-argeo.osgi.start.5.node=\
+argeo.osgi.start.4.apps=\
+org.eclipse.rap.rwt.osgi,\
 org.eclipse.gemini.blueprint.extender
 
-argeo.osgi.start.5.workbench=\
+argeo.osgi.start.4.workbench=\
 org.eclipse.equinox.http.registry,\
 
-org.osgi.service.http.port=7070
+org.osgi.service.http.port=7080
 org.eclipse.equinox.http.jetty.log.stderr.threshold=info
-#org.eclipse.equinox.http.jetty.context.path=/ui
 
 argeo.i18n.availableLocales=en,fr,de,ru,ar
 eclipse.registry.MultiLanguage=true
 
 log4j.configuration=file:../../log4j.properties
-#osgi.console.enable.builtin=true
 org.eclipse.rap.workbenchAutostart=false
\ No newline at end of file
index 36d5e0fef263616b781d28d60c1ad55df224e221..77f0d165aaede68f7b3c852654882cdd244f5572 100644 (file)
@@ -67,8 +67,8 @@ public abstract class AbstractLoginModule implements LoginModule {
                                        .getAuthentication();
                        if (currentAuth != null) {
                                if (subject.getPrincipals(Authentication.class).size() == 0) {
-                                       throw new LoginException(
-                                                       "Security context set but not Authentication principal");
+                                       // throw new LoginException(
+                                       // "Security context set but not Authentication principal");
                                } else {
                                        Authentication principal = subject
                                                        .getPrincipals(Authentication.class).iterator()
index 3bda38813b79b3ce69c6e590b459f389ec05547e..627f26d0b05d4e21c4bfab202f9b58a14241db48 100644 (file)
@@ -104,8 +104,7 @@ class JackrabbitNode extends JackrabbitWrapper implements KernelConstants,
                Hashtable<String, Object> defaults = new Hashtable<String, Object>();
 
                // home
-               File osgiInstanceDir = KernelUtils
-                               .getOsgiInstanceDir(getBundleContext());
+               File osgiInstanceDir = KernelUtils.getOsgiInstanceDir();
                File homeDir = new File(osgiInstanceDir, "node");
                // home cannot be overridden
                defaults.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
index ad6ca084a345b20fa4f621b0bca45e719edf4cce..f0c2d90d1f99758a1adc4e9238afa93e3324c3f3 100644 (file)
@@ -2,15 +2,23 @@ package org.argeo.cms.internal.kernel;
 
 import java.lang.management.ManagementFactory;
 
+import javax.jcr.Repository;
 import javax.jcr.RepositoryFactory;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.util.TransientFileFactory;
 import org.argeo.ArgeoException;
+import org.argeo.cms.CmsException;
 import org.argeo.jackrabbit.OsgiJackrabbitRepositoryFactory;
+import org.argeo.jcr.ArgeoJcrConstants;
 import org.argeo.security.core.InternalAuthentication;
+import org.eclipse.equinox.http.servlet.ExtendedHttpService;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
 import org.springframework.security.core.context.SecurityContextHolder;
 
 /**
@@ -24,12 +32,11 @@ import org.springframework.security.core.context.SecurityContextHolder;
  * <li>OS access</li>
  * </ul>
  */
-final class Kernel {
+final class Kernel implements ServiceListener {
        private final static Log log = LogFactory.getLog(Kernel.class);
-       // private static final String PROP_WORKBENCH_AUTOSTART =
-       // "org.eclipse.rap.workbenchAutostart";
 
        private final BundleContext bundleContext;
+       private final ThreadGroup threadGroup = new ThreadGroup("Argeo CMS Kernel");
 
        private JackrabbitNode node;
        private RepositoryFactory repositoryFactory;
@@ -41,12 +48,19 @@ final class Kernel {
        }
 
        void init() {
-               ClassLoader currentContextCl = Thread.currentThread()
-                               .getContextClassLoader();
-               // We use the CMS bundle classloader during initialization
-               Thread.currentThread().setContextClassLoader(
-                               Kernel.class.getClassLoader());
+               new Thread(threadGroup, "init") {
+                       @Override
+                       public void run() {
+                               // CMS bundle classloader used during initialisation
+                               Thread.currentThread().setContextClassLoader(
+                                               Kernel.class.getClassLoader());
+                               doInit();
+                       }
+               }.start();
+       }
 
+       /** Run asynchronously */
+       protected void doInit() {
                long begin = System.currentTimeMillis();
                InternalAuthentication initAuth = new InternalAuthentication(
                                KernelConstants.DEFAULT_SECURITY_KEY);
@@ -56,19 +70,21 @@ final class Kernel {
                        node = new JackrabbitNode(bundleContext);
                        repositoryFactory = new OsgiJackrabbitRepositoryFactory();
                        nodeSecurity = new NodeSecurity(bundleContext, node);
-                       nodeHttp = new NodeHttp(bundleContext, node, nodeSecurity);
+
+                       // Equinox dependency
+                       ExtendedHttpService httpService = waitForHttpService();
+                       nodeHttp = new NodeHttp(httpService, node, nodeSecurity);
 
                        // Publish services to OSGi
                        nodeSecurity.publish();
                        node.publish();
                        bundleContext.registerService(RepositoryFactory.class,
                                        repositoryFactory, null);
-                       nodeHttp.publish();
+
+                       bundleContext.addServiceListener(Kernel.this);
                } catch (Exception e) {
                        log.error("Cannot initialize Argeo CMS", e);
                        throw new ArgeoException("Cannot initialize", e);
-               } finally {
-                       Thread.currentThread().setContextClassLoader(currentContextCl);
                }
 
                long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
@@ -83,9 +99,14 @@ final class Kernel {
        void destroy() {
                long begin = System.currentTimeMillis();
 
-               nodeHttp = null;
-               nodeSecurity.destroy();
-               node.destroy();
+               if (nodeHttp != null)
+                       nodeHttp.destroy();
+               if (nodeSecurity != null)
+                       nodeSecurity.destroy();
+               if (node != null)
+                       node.destroy();
+
+               bundleContext.removeServiceListener(this);
 
                // Clean hanging threads from Jackrabbit
                TransientFileFactory.shutdown();
@@ -95,7 +116,31 @@ final class Kernel {
                                + (duration % 1000) + "s ##");
        }
 
-       private void directorsCut(long initDuration) {
+       @Override
+       public void serviceChanged(ServiceEvent event) {
+               ServiceReference<?> sr = event.getServiceReference();
+               Object jcrRepoAlias = sr
+                               .getProperty(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS);
+               if (jcrRepoAlias != null) {// JCR repository
+                       String alias = jcrRepoAlias.toString();
+                       Repository repository = (Repository) bundleContext.getService(sr);
+                       if (ServiceEvent.REGISTERED == event.getType()) {
+                               try {
+                                       nodeHttp.registerWebdavServlet(alias, repository, true);
+                                       nodeHttp.registerWebdavServlet(alias, repository, false);
+                                       nodeHttp.registerRemotingServlet(alias, repository, true);
+                                       nodeHttp.registerRemotingServlet(alias, repository, false);
+                               } catch (Exception e) {
+                                       throw new CmsException("Could not publish JCR repository "
+                                                       + alias, e);
+                               }
+                       } else if (ServiceEvent.UNREGISTERING == event.getType()) {
+                       }
+               }
+
+       }
+
+       final private static void directorsCut(long initDuration) {
                // final long ms = 128l + (long) (Math.random() * 128d);
                long ms = initDuration / 10;
                log.info("Spend " + ms + "ms"
@@ -110,9 +155,25 @@ final class Kernel {
                long durationNano = System.nanoTime() - beginNano;
                final double M = 1000d * 1000d;
                double sleepAccuracy = ((double) durationNano) / (ms * M);
-               if (log.isDebugEnabled())
-                       log.debug("Sleep accuracy: "
+               if (log.isTraceEnabled())
+                       log.trace("Sleep accuracy: "
                                        + String.format("%.2f", sleepAccuracy * 100) + " %");
        }
 
+       private ExtendedHttpService waitForHttpService() {
+               final ServiceTracker<ExtendedHttpService, ExtendedHttpService> st = new ServiceTracker<ExtendedHttpService, ExtendedHttpService>(
+                               bundleContext, ExtendedHttpService.class, null);
+               st.open();
+               ExtendedHttpService httpService;
+               try {
+                       httpService = st.waitForService(1000);
+               } catch (InterruptedException e) {
+                       httpService = null;
+               }
+
+               if (httpService == null)
+                       throw new CmsException("Could not find "
+                                       + ExtendedHttpService.class + " service.");
+               return httpService;
+       }
 }
index c93caa23dc3f358d93fd7383b7d8431d5c596532..299b912da6670236f3a494a9932fd158bb20e430 100644 (file)
@@ -24,10 +24,10 @@ public interface KernelConstants {
        // DAV
        final static String WEBDAV_CONFIG = "/org/argeo/cms/internal/kernel/webdav-config.xml";
        final static String PATH_DATA = "/data";
-       final static String PATH_WEBDAV_PUBLIC = PATH_DATA + "/public";
-       final static String PATH_WEBDAV_PRIVATE = PATH_DATA + "/files";
-       final static String PATH_REMOTING_PUBLIC = PATH_DATA + "/pub";
-       final static String PATH_REMOTING_PRIVATE = PATH_DATA + "/jcr";
+       final static String WEBDAV_PUBLIC = PATH_DATA + "/public";
+       final static String WEBDAV_PRIVATE = PATH_DATA + "/files";
+       final static String REMOTING_PUBLIC = PATH_DATA + "/pub";
+       final static String REMOTING_PRIVATE = PATH_DATA + "/jcr";
 
        // RWT / RAP
        final static String PATH_WORKBENCH = "/ui";
index 80c166e0a9db33fddfe94594ac842adbc1df4c59..eacb67c7db0fd3f9f590331ff8fe4b963bcfe3f5 100644 (file)
@@ -15,7 +15,6 @@ import org.apache.commons.logging.Log;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.KernelHeader;
 import org.argeo.cms.internal.auth.GrantedAuthorityPrincipal;
-import org.osgi.framework.BundleContext;
 import org.springframework.security.authentication.AnonymousAuthenticationToken;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.core.Authentication;
@@ -46,9 +45,10 @@ class KernelUtils implements KernelConstants {
                return asDictionary(props);
        }
 
-       static File getOsgiInstanceDir(BundleContext bundleContext) {
-               return new File(bundleContext.getProperty(OSGI_INSTANCE_AREA)
-                               .substring("file:".length())).getAbsoluteFile();
+       static File getOsgiInstanceDir() {
+               return new File(Activator.getBundleContext()
+                               .getProperty(OSGI_INSTANCE_AREA).substring("file:".length()))
+                               .getAbsoluteFile();
        }
 
        // Security
index f3bfc9488dcc3c7ad4ea71f0045ae35dcc5fd82c..cbad271540f4896e54325756a56d54c33571c170 100644 (file)
@@ -1,10 +1,13 @@
 package org.argeo.cms.internal.kernel;
 
+import static org.argeo.jackrabbit.servlet.WebdavServlet.INIT_PARAM_RESOURCE_CONFIG;
+
 import java.io.IOException;
 import java.util.Enumeration;
 import java.util.Properties;
 import java.util.StringTokenizer;
 
+import javax.jcr.Repository;
 import javax.servlet.FilterChain;
 import javax.servlet.Servlet;
 import javax.servlet.ServletException;
@@ -20,10 +23,9 @@ import org.argeo.jackrabbit.servlet.OpenInViewSessionProvider;
 import org.argeo.jackrabbit.servlet.RemotingServlet;
 import org.argeo.jackrabbit.servlet.WebdavServlet;
 import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.security.NodeAuthenticationToken;
 import org.eclipse.equinox.http.servlet.ExtendedHttpService;
-import org.osgi.framework.BundleContext;
 import org.osgi.service.http.NamespaceException;
-import org.osgi.util.tracker.ServiceTracker;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
@@ -42,8 +44,7 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
        private final static String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
 
        private final AuthenticationManager authenticationManager;
-       private final BundleContext bundleContext;
-       private ExtendedHttpService httpService;
+       private final ExtendedHttpService httpService;
 
        // FIXME Make it more unique
        private String httpAuthRealm = "Argeo";
@@ -53,31 +54,15 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
        // private final DoSFilter dosFilter;
        // private final QoSFilter qosFilter;
 
-       // remoting
+       // WebDav / JCR remoting
        private OpenInViewSessionProvider sessionProvider;
-       private WebdavServlet publicWebdavServlet;
-       private WebdavServlet privateWebdavServlet;
-       private RemotingServlet publicRemotingServlet;
-       private RemotingServlet privateRemotingServlet;
 
-       NodeHttp(BundleContext bundleContext, JackrabbitNode node,
+       NodeHttp(ExtendedHttpService httpService, JackrabbitNode node,
                        NodeSecurity authenticationManager) {
-               this.bundleContext = bundleContext;
+               // this.bundleContext = bundleContext;
                this.authenticationManager = authenticationManager;
 
-               // Equinox dependency
-               ServiceTracker<ExtendedHttpService, ExtendedHttpService> st = new ServiceTracker<ExtendedHttpService, ExtendedHttpService>(
-                               bundleContext, ExtendedHttpService.class, null);
-               st.open();
-               try {
-                       httpService = st.waitForService(1000);
-               } catch (InterruptedException e) {
-                       httpService = null;
-               }
-
-               if (httpService == null)
-                       throw new CmsException("Could not find "
-                                       + ExtendedHttpService.class + " service.");
+               this.httpService = httpService;
 
                // Filters
                rootFilter = new RootFilter();
@@ -86,66 +71,55 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
 
                // DAV
                sessionProvider = new OpenInViewSessionProvider();
-               publicWebdavServlet = new WebdavServlet(node, sessionProvider);
-               privateWebdavServlet = new WebdavServlet(node, sessionProvider);
-               publicRemotingServlet = new RemotingServlet(node, sessionProvider);
-               privateRemotingServlet = new RemotingServlet(node, sessionProvider);
-       }
 
-       void publish() {
                try {
-                       registerWebdavServlet(PATH_WEBDAV_PUBLIC, ALIAS_NODE, true,
-                                       publicWebdavServlet);
-                       registerWebdavServlet(PATH_WEBDAV_PRIVATE, ALIAS_NODE, false,
-                                       privateWebdavServlet);
-                       registerRemotingServlet(PATH_REMOTING_PUBLIC, ALIAS_NODE, true,
-                                       publicRemotingServlet);
-                       registerRemotingServlet(PATH_REMOTING_PRIVATE, ALIAS_NODE, false,
-                                       privateRemotingServlet);
-
-                       // httpService.registerFilter("/", dosFilter, null, null);
+                       registerWebdavServlet(ALIAS_NODE, node, true);
+                       registerWebdavServlet(ALIAS_NODE, node, false);
+                       registerRemotingServlet(ALIAS_NODE, node, true);
+                       registerRemotingServlet(ALIAS_NODE, node, false);
+
                        httpService.registerFilter("/", rootFilter, null, null);
-                       // httpService.registerFilter("/", qosFilter, null, null);
                } catch (Exception e) {
-                       throw new CmsException("Cannot publish HTTP services to OSGi", e);
+                       throw new CmsException("Could not initialise http", e);
                }
        }
 
-       private void registerWebdavServlet(String pathPrefix, String alias,
-                       Boolean anonymous, WebdavServlet webdavServlet)
-                       throws NamespaceException, ServletException {
+       public void destroy() {
+               sessionProvider.destroy();
+       }
+
+       void registerWebdavServlet(String alias, Repository repository,
+                       boolean anonymous) throws NamespaceException, ServletException {
+               WebdavServlet webdavServlet = new WebdavServlet(repository,
+                               sessionProvider);
+               String pathPrefix = anonymous ? WEBDAV_PUBLIC : WEBDAV_PRIVATE;
                String path = pathPrefix + "/" + alias;
-               Properties initParameters = new Properties();
-               initParameters.setProperty(WebdavServlet.INIT_PARAM_RESOURCE_CONFIG,
-                               KernelConstants.WEBDAV_CONFIG);
-               initParameters.setProperty(
-                               WebdavServlet.INIT_PARAM_RESOURCE_PATH_PREFIX, path);
+               Properties ip = new Properties();
+               ip.setProperty(INIT_PARAM_RESOURCE_CONFIG, WEBDAV_CONFIG);
+               ip.setProperty(WebdavServlet.INIT_PARAM_RESOURCE_PATH_PREFIX, path);
                httpService.registerFilter(path, anonymous ? new AnonymousFilter()
                                : new DavFilter(), null, null);
                // Cast to servlet because of a weird behaviour in Eclipse
-               httpService.registerServlet(path, (Servlet) webdavServlet,
-                               initParameters, null);
+               httpService.registerServlet(path, (Servlet) webdavServlet, ip, null);
        }
 
-       private void registerRemotingServlet(String pathPrefix, String alias,
-                       Boolean anonymous, RemotingServlet remotingServlet)
-                       throws NamespaceException, ServletException {
+       void registerRemotingServlet(String alias, Repository repository,
+                       boolean anonymous) throws NamespaceException, ServletException {
+               String pathPrefix = anonymous ? REMOTING_PUBLIC : REMOTING_PRIVATE;
+               RemotingServlet remotingServlet = new RemotingServlet(repository,
+                               sessionProvider);
                String path = pathPrefix + "/" + alias;
-               Properties initParameters = new Properties();
-               initParameters.setProperty(
-                               RemotingServlet.INIT_PARAM_RESOURCE_PATH_PREFIX, path);
+               Properties ip = new Properties();
+               ip.setProperty(RemotingServlet.INIT_PARAM_RESOURCE_PATH_PREFIX, path);
 
                // Looks like a bug in Jackrabbit remoting init
-               initParameters.setProperty(RemotingServlet.INIT_PARAM_HOME,
-                               KernelUtils.getOsgiInstanceDir(bundleContext)
-                                               + "/tmp/jackrabbit");
-               initParameters.setProperty(RemotingServlet.INIT_PARAM_TMP_DIRECTORY,
-                               "remoting");
+               ip.setProperty(RemotingServlet.INIT_PARAM_HOME,
+                               KernelUtils.getOsgiInstanceDir() + "/tmp/jackrabbit");
+               ip.setProperty(RemotingServlet.INIT_PARAM_TMP_DIRECTORY, "remoting");
                // Cast to servlet because of a weird behaviour in Eclipse
                httpService.registerFilter(path, anonymous ? new AnonymousFilter()
                                : new DavFilter(), null, null);
-               httpService.registerServlet(path, (Servlet) remotingServlet,
-                               initParameters, null);
+               httpService.registerServlet(path, (Servlet) remotingServlet, ip, null);
        }
 
        private Boolean isSessionAuthenticated(HttpSession httpSession) {
@@ -162,7 +136,7 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
                httpSession.setAttribute(ATTR_AUTH, Boolean.TRUE);
        }
 
-       private UsernamePasswordAuthenticationToken basicAuth(String authHeader) {
+       private NodeAuthenticationToken basicAuth(String authHeader) {
                if (authHeader != null) {
                        StringTokenizer st = new StringTokenizer(authHeader);
                        if (st.hasMoreTokens()) {
@@ -178,8 +152,8 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
                                                        String password = credentials.substring(p + 1)
                                                                        .trim();
 
-                                                       return new UsernamePasswordAuthenticationToken(
-                                                                       login, password.toCharArray());
+                                                       return new NodeAuthenticationToken(login,
+                                                                       password.toCharArray());
                                                } else {
                                                        throw new CmsException(
                                                                        "Invalid authentication token");
@@ -251,7 +225,7 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
        }
 
        /** Intercepts all requests. Authenticates. */
-       class AnonymousFilter extends HttpFilter {
+       private class AnonymousFilter extends HttpFilter {
                @Override
                public void doFilter(HttpSession httpSession,
                                HttpServletRequest request, HttpServletResponse response,
@@ -269,7 +243,7 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
        }
 
        /** Intercepts all requests. Authenticates. */
-       class DavFilter extends HttpFilter {
+       private class DavFilter extends HttpFilter {
 
                @Override
                public void doFilter(HttpSession httpSession,
index 583bf4c1cc188acfe4f35d43f34849c53e405e53..68168a85239626cafc45620670d962116d891fd2 100644 (file)
@@ -1,6 +1,5 @@
-<?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
-                            "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
 <Repository>
        <!-- Shared datasource -->
        <DataSources>
index b41cfad6d945c4f6705bf2eac9d053a10ac95dcf..aeb22692c751315ff9e4e933ecfc72c84c3274b0 100644 (file)
@@ -1,6 +1,5 @@
 <?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
-                            "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
+<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
 <Repository>
        <!-- File system and datastore -->
        <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
index 811f0c6bc1a2b316d66392e9ada579ad6cc8011e..01c9474ca97c54c0a007632561fb11ae2195f1fc 100644 (file)
@@ -1,6 +1,5 @@
 <?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
-                            "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
+<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
 <Repository>
        <!-- Shared datasource -->
        <DataSources>