2 * Copyright (C) 2007-2012 Argeo GmbH
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org
.argeo
.jcr
.mvc
;
18 import java
.util
.Enumeration
;
19 import java
.util
.Properties
;
20 import java
.util
.StringTokenizer
;
22 import javax
.jcr
.Repository
;
23 import javax
.jcr
.RepositoryFactory
;
24 import javax
.servlet
.ServletConfig
;
25 import javax
.servlet
.ServletContext
;
26 import javax
.servlet
.ServletException
;
27 import javax
.servlet
.http
.HttpServlet
;
28 import javax
.servlet
.http
.HttpServletRequest
;
30 import org
.apache
.commons
.logging
.Log
;
31 import org
.apache
.commons
.logging
.LogFactory
;
32 import org
.argeo
.jcr
.ArgeoJcrConstants
;
33 import org
.argeo
.jcr
.ArgeoJcrUtils
;
34 import org
.springframework
.beans
.BeansException
;
35 import org
.springframework
.context
.ApplicationContext
;
36 import org
.springframework
.context
.ApplicationContextAware
;
37 import org
.springframework
.context
.ConfigurableApplicationContext
;
38 import org
.springframework
.web
.context
.ServletContextAware
;
39 import org
.springframework
.web
.servlet
.HandlerExecutionChain
;
40 import org
.springframework
.web
.servlet
.HandlerMapping
;
42 /** Handles multiple JCR servers with a single servlet. */
43 public abstract class MultipleRepositoryHandlerMapping
implements
44 HandlerMapping
, ApplicationContextAware
, ServletContextAware
{
45 private final static Log log
= LogFactory
46 .getLog(MultipleRepositoryHandlerMapping
.class);
48 private final static String MKCOL
= "MKCOL";
50 private ConfigurableApplicationContext applicationContext
;
51 private ServletContext servletContext
;
53 // private RepositoryRegister repositoryRegister;
54 private RepositoryFactory repositoryFactory
;
56 /** Actually creates the servlet to be registered. */
57 protected abstract HttpServlet
createServlet(Repository repository
,
58 String pathPrefix
) throws ServletException
;
60 public HandlerExecutionChain
getHandler(HttpServletRequest request
)
62 if (log
.isTraceEnabled()) {
63 log
.trace("getContextPath=" + request
.getContextPath());
64 log
.trace("getServletPath=" + request
.getServletPath());
65 log
.trace("getPathInfo=" + request
.getPathInfo());
68 String pathInfo
= request
.getPathInfo();
69 String repositoryAlias
= extractRepositoryAlias(pathInfo
);
70 if (repositoryAlias
.equals(""))
73 // MKCOL on repository or root node doesn't make sense
75 if (request
.getMethod().equals(MKCOL
)) {
76 StringTokenizer st
= new StringTokenizer(pathInfo
, "/");
77 if (!st
.hasMoreTokens())
79 st
.nextToken();// repository
80 if (!st
.hasMoreTokens())
82 st
.nextToken();// workspace
83 if (!st
.hasMoreTokens())
87 request
.setAttribute(ArgeoJcrConstants
.JCR_REPOSITORY_ALIAS
,
89 String pathPrefix
= request
.getServletPath() + '/' + repositoryAlias
;
90 String beanName
= pathPrefix
;
92 if (!applicationContext
.containsBean(beanName
)) {
93 Repository repository
= ArgeoJcrUtils
.getRepositoryByAlias(
94 repositoryFactory
, repositoryAlias
);
95 // Repository repository = repositoryRegister.getRepositories().get(
97 HttpServlet servlet
= createServlet(repository
, pathPrefix
);
98 applicationContext
.getBeanFactory().registerSingleton(beanName
,
100 // TODO: unregister it as well
102 HttpServlet remotingServlet
= (HttpServlet
) applicationContext
104 HandlerExecutionChain hec
= new HandlerExecutionChain(remotingServlet
);
108 /** Returns the first two token of the path */
109 // protected String[] extractPrefix(String pathInfo) {
110 // String[] res = new String[2];
111 // StringTokenizer st = new StringTokenizer(pathInfo, "/");
112 // if (st.hasMoreTokens())
113 // res[0] = st.nextToken();
114 // if (st.hasMoreTokens())
115 // res[1] = st.nextToken();
119 /** Returns the first token of the path */
120 protected String
extractRepositoryAlias(String pathInfo
) {
121 StringBuffer buf
= new StringBuffer();
122 for (int i
= 1; i
< pathInfo
.length(); i
++) {
123 char c
= pathInfo
.charAt(i
);
128 return buf
.toString();
131 /** The repository name is the first part of the path info */
132 // protected String extractRepositoryName(List<String> pathTokens) {
133 // StringBuffer currName = new StringBuffer("");
134 // for (String token : pathTokens) {
135 // currName.append(token);
136 // if (repositoryRegister.getRepositories().containsKey(
137 // currName.toString()))
138 // return currName.toString();
139 // currName.append('/');
141 // throw new ArgeoException("No repository can be found for request "
145 public void setApplicationContext(ApplicationContext applicationContext
)
146 throws BeansException
{
147 this.applicationContext
= (ConfigurableApplicationContext
) applicationContext
;
150 public void setServletContext(ServletContext servletContext
) {
151 this.servletContext
= servletContext
;
154 // public void setRepositoryRegister(RepositoryRegister repositoryRegister)
156 // this.repositoryRegister = repositoryRegister;
159 public void setRepositoryFactory(RepositoryFactory repositoryFactory
) {
160 this.repositoryFactory
= repositoryFactory
;
163 protected class DelegatingServletConfig
implements ServletConfig
{
165 private Properties initParameters
;
167 public DelegatingServletConfig(String name
, Properties initParameters
) {
170 this.initParameters
= initParameters
;
173 public String
getServletName() {
177 public ServletContext
getServletContext() {
178 return servletContext
;
181 public String
getInitParameter(String paramName
) {
182 return initParameters
.getProperty(paramName
);
185 @SuppressWarnings("rawtypes")
186 public Enumeration
getInitParameterNames() {
187 return initParameters
.keys();