2 * Copyright (C) 2007-2012 Mathieu Baudier
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
.List
;
20 import java
.util
.Properties
;
22 import javax
.jcr
.Repository
;
23 import javax
.servlet
.ServletConfig
;
24 import javax
.servlet
.ServletContext
;
25 import javax
.servlet
.ServletException
;
26 import javax
.servlet
.http
.HttpServlet
;
27 import javax
.servlet
.http
.HttpServletRequest
;
29 import org
.apache
.commons
.logging
.Log
;
30 import org
.apache
.commons
.logging
.LogFactory
;
31 import org
.argeo
.ArgeoException
;
32 import org
.argeo
.jcr
.ArgeoJcrConstants
;
33 import org
.argeo
.jcr
.JcrUtils
;
34 import org
.argeo
.jcr
.RepositoryRegister
;
35 import org
.springframework
.beans
.BeansException
;
36 import org
.springframework
.context
.ApplicationContext
;
37 import org
.springframework
.context
.ApplicationContextAware
;
38 import org
.springframework
.context
.ConfigurableApplicationContext
;
39 import org
.springframework
.web
.context
.ServletContextAware
;
40 import org
.springframework
.web
.servlet
.HandlerExecutionChain
;
41 import org
.springframework
.web
.servlet
.HandlerMapping
;
43 /** Handles multiple JCR servers with a single servlet. */
44 public abstract class MultipleRepositoryHandlerMapping
implements
45 HandlerMapping
, ApplicationContextAware
, ServletContextAware
{
46 private final static Log log
= LogFactory
47 .getLog(MultipleRepositoryHandlerMapping
.class);
49 private final static String MKCOL
= "MKCOL";
51 private ConfigurableApplicationContext applicationContext
;
52 private ServletContext servletContext
;
54 private RepositoryRegister repositoryRegister
;
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();
71 List
<String
> tokens
= JcrUtils
.tokenize(pathInfo
);
73 // check if repository can be found
74 if (tokens
.size() == 0
75 || (tokens
.size() == 1 && tokens
.get(0).equals("")))
77 // MKCOL on repository or root node doesn't make sense
78 if ((tokens
.size() == 1 || tokens
.size() == 2)
79 && request
.getMethod().equals(MKCOL
))
81 String repositoryAlias
= extractRepositoryName(tokens
);
82 request
.setAttribute(ArgeoJcrConstants
.JCR_REPOSITORY_ALIAS
,
84 String pathPrefix
= request
.getServletPath() + '/' + repositoryAlias
;
85 String beanName
= pathPrefix
;
87 if (!applicationContext
.containsBean(beanName
)) {
88 Repository repository
= repositoryRegister
.getRepositories().get(
90 HttpServlet servlet
= createServlet(repository
, pathPrefix
);
91 applicationContext
.getBeanFactory().registerSingleton(beanName
,
93 // TODO: unregister it as well
95 HttpServlet remotingServlet
= (HttpServlet
) applicationContext
97 HandlerExecutionChain hec
= new HandlerExecutionChain(remotingServlet
);
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('/');
111 throw new ArgeoException("No repository can be found for request "
115 public void setApplicationContext(ApplicationContext applicationContext
)
116 throws BeansException
{
117 this.applicationContext
= (ConfigurableApplicationContext
) applicationContext
;
120 public void setServletContext(ServletContext servletContext
) {
121 this.servletContext
= servletContext
;
124 public void setRepositoryRegister(RepositoryRegister repositoryRegister
) {
125 this.repositoryRegister
= repositoryRegister
;
128 protected class DelegatingServletConfig
implements ServletConfig
{
130 private Properties initParameters
;
132 public DelegatingServletConfig(String name
, Properties initParameters
) {
135 this.initParameters
= initParameters
;
138 public String
getServletName() {
142 public ServletContext
getServletContext() {
143 return servletContext
;
146 public String
getInitParameter(String paramName
) {
147 return initParameters
.getProperty(paramName
);
150 @SuppressWarnings("rawtypes")
151 public Enumeration
getInitParameterNames() {
152 return initParameters
.keys();