]> git.argeo.org Git - lgpl/argeo-commons.git/blob - server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/remote/MultipleRepositoryHandlerMapping.java
Add JCR MVC
[lgpl/argeo-commons.git] / server / runtime / org.argeo.server.jackrabbit / src / main / java / org / argeo / jackrabbit / remote / MultipleRepositoryHandlerMapping.java
1 package org.argeo.jackrabbit.remote;
2
3 import java.util.Enumeration;
4 import java.util.Properties;
5
6 import javax.jcr.Repository;
7 import javax.servlet.ServletConfig;
8 import javax.servlet.ServletContext;
9 import javax.servlet.ServletException;
10 import javax.servlet.http.HttpServlet;
11 import javax.servlet.http.HttpServletRequest;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15 import org.apache.jackrabbit.webdav.jcr.JCRWebdavServerServlet;
16 import org.argeo.ArgeoException;
17 import org.argeo.jcr.RepositoryRegister;
18 import org.springframework.beans.BeansException;
19 import org.springframework.context.ApplicationContext;
20 import org.springframework.context.ApplicationContextAware;
21 import org.springframework.context.ConfigurableApplicationContext;
22 import org.springframework.web.context.ServletContextAware;
23 import org.springframework.web.servlet.HandlerExecutionChain;
24 import org.springframework.web.servlet.HandlerMapping;
25
26 public class MultipleRepositoryHandlerMapping implements HandlerMapping,
27 ApplicationContextAware, ServletContextAware {
28 private final static Log log = LogFactory
29 .getLog(MultipleRepositoryHandlerMapping.class);
30
31 private ConfigurableApplicationContext applicationContext;
32 private ServletContext servletContext;
33
34 private RepositoryRegister repositoryRegister;
35
36 public HandlerExecutionChain getHandler(HttpServletRequest request)
37 throws Exception {
38 if (log.isTraceEnabled()) {
39 log.trace("getContextPath=" + request.getContextPath());
40 log.trace("getServletPath=" + request.getServletPath());
41 log.trace("getPathInfo=" + request.getPathInfo());
42 }
43
44 String repositoryName = extractRepositoryName(request);
45 String pathPrefix = request.getServletPath() + '/' + repositoryName;
46 String beanName = pathPrefix;
47
48 if (!applicationContext.containsBean(beanName)) {
49 Repository repository = repositoryRegister.getRepositories().get(
50 repositoryName);
51 HttpServlet servlet = createServlet(repository, pathPrefix);
52 applicationContext.getBeanFactory().registerSingleton(beanName,
53 servlet);
54 // TODO: unregister it as well
55 }
56 HttpServlet remotingServlet = (HttpServlet) applicationContext
57 .getBean(beanName);
58 return new HandlerExecutionChain(remotingServlet);
59 }
60
61 protected HttpServlet createServlet(Repository repository, String pathPrefix)
62 throws ServletException {
63 JcrRemotingServlet jcrRemotingServlet = new JcrRemotingServlet(
64 repository);
65 Properties initParameters = new Properties();
66 initParameters.setProperty(
67 JCRWebdavServerServlet.INIT_PARAM_RESOURCE_PATH_PREFIX,
68 pathPrefix);
69 jcrRemotingServlet.init(new DelegatingServletConfig(pathPrefix.replace(
70 '/', '_'), initParameters));
71 return jcrRemotingServlet;
72 }
73
74 /** The repository name is the first part of the path info */
75 protected String extractRepositoryName(HttpServletRequest request) {
76 String pathInfo = request.getPathInfo();
77 // TODO: optimize by checking character by character
78 String[] tokens = pathInfo.split("/");
79 StringBuffer currName = new StringBuffer("");
80 tokens: for (String token : tokens) {
81 if (token.equals(""))
82 continue tokens;
83 currName.append(token);
84 if (repositoryRegister.getRepositories().containsKey(
85 currName.toString()))
86 return currName.toString();
87 currName.append('/');
88 }
89 throw new ArgeoException("No repository can be found for request "
90 + pathInfo);
91 }
92
93 public void setApplicationContext(ApplicationContext applicationContext)
94 throws BeansException {
95 this.applicationContext = (ConfigurableApplicationContext) applicationContext;
96 }
97
98 public void setServletContext(ServletContext servletContext) {
99 this.servletContext = servletContext;
100 }
101
102 public void setRepositoryRegister(RepositoryRegister repositoryRegister) {
103 this.repositoryRegister = repositoryRegister;
104 }
105
106 private class DelegatingServletConfig implements ServletConfig {
107 private String name;
108 private Properties initParameters;
109
110 public DelegatingServletConfig(String name, Properties initParameters) {
111 super();
112 this.name = name;
113 this.initParameters = initParameters;
114 }
115
116 public String getServletName() {
117 return name;
118 }
119
120 public ServletContext getServletContext() {
121 return servletContext;
122 }
123
124 public String getInitParameter(String paramName) {
125 return initParameters.getProperty(paramName);
126 }
127
128 public Enumeration getInitParameterNames() {
129 return initParameters.keys();
130 }
131 }
132
133 }