]> git.argeo.org Git - lgpl/argeo-commons.git/blob - server/runtime/org.argeo.server.jcr.mvc/src/main/java/org/argeo/jcr/mvc/MultipleRepositoryHandlerMapping.java
bc333ba4400d15d87e951c85ca8aa6400d295bb7
[lgpl/argeo-commons.git] / server / runtime / org.argeo.server.jcr.mvc / src / main / java / org / argeo / jcr / mvc / MultipleRepositoryHandlerMapping.java
1 package org.argeo.jcr.mvc;
2
3 import java.util.ArrayList;
4 import java.util.Enumeration;
5 import java.util.List;
6 import java.util.Properties;
7
8 import javax.jcr.Repository;
9 import javax.servlet.ServletConfig;
10 import javax.servlet.ServletContext;
11 import javax.servlet.ServletException;
12 import javax.servlet.http.HttpServlet;
13 import javax.servlet.http.HttpServletRequest;
14
15 import org.apache.commons.logging.Log;
16 import org.apache.commons.logging.LogFactory;
17 import org.argeo.ArgeoException;
18 import org.argeo.jcr.RepositoryRegister;
19 import org.springframework.beans.BeansException;
20 import org.springframework.context.ApplicationContext;
21 import org.springframework.context.ApplicationContextAware;
22 import org.springframework.context.ConfigurableApplicationContext;
23 import org.springframework.web.context.ServletContextAware;
24 import org.springframework.web.servlet.HandlerExecutionChain;
25 import org.springframework.web.servlet.HandlerMapping;
26
27 public abstract class MultipleRepositoryHandlerMapping implements
28 HandlerMapping, ApplicationContextAware, ServletContextAware {
29 private final static Log log = LogFactory
30 .getLog(MultipleRepositoryHandlerMapping.class);
31
32 private final static String MKCOL = "MKCOL";
33
34 private ConfigurableApplicationContext applicationContext;
35 private ServletContext servletContext;
36
37 private RepositoryRegister repositoryRegister;
38
39 /** Actually creates the servlet to be registered. */
40 protected abstract HttpServlet createServlet(Repository repository,
41 String pathPrefix) throws ServletException;
42
43 public HandlerExecutionChain getHandler(HttpServletRequest request)
44 throws Exception {
45 if (log.isTraceEnabled()) {
46 log.trace("getContextPath=" + request.getContextPath());
47 log.trace("getServletPath=" + request.getServletPath());
48 log.trace("getPathInfo=" + request.getPathInfo());
49 }
50
51 String pathInfo = request.getPathInfo();
52
53 // tokenize path
54 // TODO factorize
55 List<String> tokens = new ArrayList<String>();
56 StringBuffer curr = new StringBuffer();
57 char[] arr = pathInfo.toCharArray();
58 chars: for (int i = 0; i < arr.length; i++) {
59 char c = arr[i];
60 if (c == '/') {
61 if (i == 0 || (i == arr.length - 1))
62 continue chars;
63 if (curr.length() > 0) {
64 tokens.add(curr.toString());
65 curr = new StringBuffer();
66 }
67 } else
68 curr.append(c);
69 }
70 if (curr.length() > 0) {
71 tokens.add(curr.toString());
72 curr = new StringBuffer();
73 }
74
75 // check if repository can be found
76 if (tokens.size() == 0
77 || (tokens.size() == 1 && tokens.get(0).equals("")))
78 return null;
79 // MKCOL on repository or root node doesn't make sense
80 if ((tokens.size() == 1 || tokens.size() == 2)
81 && request.getMethod().equals(MKCOL))
82 return null;
83 String repositoryName = extractRepositoryName(tokens);
84 String pathPrefix = request.getServletPath() + '/' + repositoryName;
85 String beanName = pathPrefix;
86
87 if (!applicationContext.containsBean(beanName)) {
88 Repository repository = repositoryRegister.getRepositories().get(
89 repositoryName);
90 HttpServlet servlet = createServlet(repository, pathPrefix);
91 applicationContext.getBeanFactory().registerSingleton(beanName,
92 servlet);
93 // TODO: unregister it as well
94 }
95 HttpServlet remotingServlet = (HttpServlet) applicationContext
96 .getBean(beanName);
97 HandlerExecutionChain hec = new HandlerExecutionChain(remotingServlet);
98 return hec;
99 }
100
101 /** The repository name is the first part of the path info */
102 protected String extractRepositoryName(List<String> pathTokens) {
103 StringBuffer currName = new StringBuffer("");
104 for (String token : pathTokens) {
105 currName.append(token);
106 if (repositoryRegister.getRepositories().containsKey(
107 currName.toString()))
108 return currName.toString();
109 currName.append('/');
110 }
111 throw new ArgeoException("No repository can be found for request "
112 + pathTokens);
113 }
114
115 public void setApplicationContext(ApplicationContext applicationContext)
116 throws BeansException {
117 this.applicationContext = (ConfigurableApplicationContext) applicationContext;
118 }
119
120 public void setServletContext(ServletContext servletContext) {
121 this.servletContext = servletContext;
122 }
123
124 public void setRepositoryRegister(RepositoryRegister repositoryRegister) {
125 this.repositoryRegister = repositoryRegister;
126 }
127
128 protected class DelegatingServletConfig implements ServletConfig {
129 private String name;
130 private Properties initParameters;
131
132 public DelegatingServletConfig(String name, Properties initParameters) {
133 super();
134 this.name = name;
135 this.initParameters = initParameters;
136 }
137
138 public String getServletName() {
139 return name;
140 }
141
142 public ServletContext getServletContext() {
143 return servletContext;
144 }
145
146 public String getInitParameter(String paramName) {
147 return initParameters.getProperty(paramName);
148 }
149
150 @SuppressWarnings("rawtypes")
151 public Enumeration getInitParameterNames() {
152 return initParameters.keys();
153 }
154 }
155 }