]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - server/runtime/org.argeo.server.jcr.mvc/src/main/java/org/argeo/jcr/mvc/MultipleRepositoryHandlerMapping.java
Add dep folder
[lgpl/argeo-commons.git] / server / runtime / org.argeo.server.jcr.mvc / src / main / java / org / argeo / jcr / mvc / MultipleRepositoryHandlerMapping.java
index 16ecdd89ecff8de8b5fda232a33ad74124015060..fb3f1ae65fe8c7aa455dd432a07b7eaccedaf630 100644 (file)
@@ -1,9 +1,26 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.jcr.mvc;
 
 import java.util.Enumeration;
 import java.util.Properties;
+import java.util.StringTokenizer;
 
 import javax.jcr.Repository;
+import javax.jcr.RepositoryFactory;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
@@ -12,8 +29,8 @@ import javax.servlet.http.HttpServletRequest;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.RepositoryRegister;
+import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.jcr.ArgeoJcrUtils;
 import org.springframework.beans.BeansException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
@@ -22,15 +39,19 @@ import org.springframework.web.context.ServletContextAware;
 import org.springframework.web.servlet.HandlerExecutionChain;
 import org.springframework.web.servlet.HandlerMapping;
 
+/** Handles multiple JCR servers with a single servlet. */
 public abstract class MultipleRepositoryHandlerMapping implements
                HandlerMapping, ApplicationContextAware, ServletContextAware {
        private final static Log log = LogFactory
                        .getLog(MultipleRepositoryHandlerMapping.class);
 
+       private final static String MKCOL = "MKCOL";
+
        private ConfigurableApplicationContext applicationContext;
        private ServletContext servletContext;
 
-       private RepositoryRegister repositoryRegister;
+       // private RepositoryRegister repositoryRegister;
+       private RepositoryFactory repositoryFactory;
 
        /** Actually creates the servlet to be registered. */
        protected abstract HttpServlet createServlet(Repository repository,
@@ -44,13 +65,35 @@ public abstract class MultipleRepositoryHandlerMapping implements
                        log.trace("getPathInfo=" + request.getPathInfo());
                }
 
-               String repositoryName = extractRepositoryName(request);
-               String pathPrefix = request.getServletPath() + '/' + repositoryName;
+               String pathInfo = request.getPathInfo();
+               String repositoryAlias = extractRepositoryAlias(pathInfo);
+               if (repositoryAlias.equals(""))
+                       return null;
+
+               // MKCOL on repository or root node doesn't make sense
+               // and causes issues
+               if (request.getMethod().equals(MKCOL)) {
+                       StringTokenizer st = new StringTokenizer(pathInfo, "/");
+                       if (!st.hasMoreTokens())
+                               return null;
+                       st.nextToken();// repository
+                       if (!st.hasMoreTokens())
+                               return null;
+                       st.nextToken();// workspace
+                       if (!st.hasMoreTokens())
+                               return null;
+               }
+
+               request.setAttribute(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS,
+                               repositoryAlias);
+               String pathPrefix = request.getServletPath() + '/' + repositoryAlias;
                String beanName = pathPrefix;
 
                if (!applicationContext.containsBean(beanName)) {
-                       Repository repository = repositoryRegister.getRepositories().get(
-                                       repositoryName);
+                       Repository repository = ArgeoJcrUtils.getRepositoryByAlias(
+                                       repositoryFactory, repositoryAlias);
+                       // Repository repository = repositoryRegister.getRepositories().get(
+                       // repositoryAlias);
                        HttpServlet servlet = createServlet(repository, pathPrefix);
                        applicationContext.getBeanFactory().registerSingleton(beanName,
                                        servlet);
@@ -62,25 +105,43 @@ public abstract class MultipleRepositoryHandlerMapping implements
                return hec;
        }
 
-       /** The repository name is the first part of the path info */
-       protected String extractRepositoryName(HttpServletRequest request) {
-               String pathInfo = request.getPathInfo();
-               // TODO: optimize by checking character by character
-               String[] tokens = pathInfo.split("/");
-               StringBuffer currName = new StringBuffer("");
-               tokens: for (String token : tokens) {
-                       if (token.equals(""))
-                               continue tokens;
-                       currName.append(token);
-                       if (repositoryRegister.getRepositories().containsKey(
-                                       currName.toString()))
-                               return currName.toString();
-                       currName.append('/');
+       /** Returns the first two token of the path */
+       // protected String[] extractPrefix(String pathInfo) {
+       // String[] res = new String[2];
+       // StringTokenizer st = new StringTokenizer(pathInfo, "/");
+       // if (st.hasMoreTokens())
+       // res[0] = st.nextToken();
+       // if (st.hasMoreTokens())
+       // res[1] = st.nextToken();
+       // return res;
+       // }
+
+       /** Returns the first token of the path */
+       protected String extractRepositoryAlias(String pathInfo) {
+               StringBuffer buf = new StringBuffer();
+               for (int i = 1; i < pathInfo.length(); i++) {
+                       char c = pathInfo.charAt(i);
+                       if (c == '/')
+                               break;
+                       buf.append(c);
                }
-               throw new ArgeoException("No repository can be found for request "
-                               + pathInfo);
+               return buf.toString();
        }
 
+       /** The repository name is the first part of the path info */
+       // protected String extractRepositoryName(List<String> pathTokens) {
+       // StringBuffer currName = new StringBuffer("");
+       // for (String token : pathTokens) {
+       // currName.append(token);
+       // if (repositoryRegister.getRepositories().containsKey(
+       // currName.toString()))
+       // return currName.toString();
+       // currName.append('/');
+       // }
+       // throw new ArgeoException("No repository can be found for request "
+       // + pathTokens);
+       // }
+
        public void setApplicationContext(ApplicationContext applicationContext)
                        throws BeansException {
                this.applicationContext = (ConfigurableApplicationContext) applicationContext;
@@ -90,8 +151,13 @@ public abstract class MultipleRepositoryHandlerMapping implements
                this.servletContext = servletContext;
        }
 
-       public void setRepositoryRegister(RepositoryRegister repositoryRegister) {
-               this.repositoryRegister = repositoryRegister;
+       // public void setRepositoryRegister(RepositoryRegister repositoryRegister)
+       // {
+       // this.repositoryRegister = repositoryRegister;
+       // }
+
+       public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
+               this.repositoryFactory = repositoryFactory;
        }
 
        protected class DelegatingServletConfig implements ServletConfig {