This project has retired. For details please refer to its Attic page.
AbstractCmisHttpServlet xref
View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.chemistry.opencmis.server.shared;
20  
21  import java.util.Map;
22  
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;
28  import javax.servlet.http.HttpServletResponse;
29  
30  import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
31  import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
32  import org.apache.chemistry.opencmis.commons.impl.ClassLoaderUtil;
33  import org.apache.chemistry.opencmis.commons.impl.Constants;
34  import org.apache.chemistry.opencmis.commons.server.CallContext;
35  import org.apache.chemistry.opencmis.commons.server.CmisServiceFactory;
36  import org.apache.chemistry.opencmis.server.impl.CallContextImpl;
37  import org.apache.chemistry.opencmis.server.impl.CmisRepositoryContextListener;
38  import org.apache.chemistry.opencmis.server.impl.browser.BrowserCallContextImpl;
39  
40  public abstract class AbstractCmisHttpServlet extends HttpServlet {
41  
42      public static final String PARAM_CALL_CONTEXT_HANDLER = "callContextHandler";
43      public static final String PARAM_CMIS_VERSION = "cmisVersion";
44  
45      private static final long serialVersionUID = 1L;
46  
47      private CmisServiceFactory factory;
48      private String binding;
49      private CmisVersion cmisVersion;
50      private CallContextHandler callContextHandler;
51      private CsrfManager csrfManager;
52  
53      @Override
54      public void init(ServletConfig config) throws ServletException {
55          super.init(config);
56  
57          // initialize the call context handler
58          callContextHandler = loadCallContextHandler(config);
59  
60          // get service factory
61          factory = CmisRepositoryContextListener.getServiceFactory(config.getServletContext());
62  
63          if (factory == null) {
64              throw new ServletException("Service factory not available! Configuration problem?");
65          }
66  
67          // set up CSRF manager
68          csrfManager = new CsrfManager(config);
69      }
70  
71      /**
72       * Loads a {@code CallContextHandler} if it is configured in for this
73       * servlet.
74       */
75      public static CallContextHandler loadCallContextHandler(ServletConfig config) throws ServletException {
76          String callContextHandlerClass = config.getInitParameter(PARAM_CALL_CONTEXT_HANDLER);
77          if (callContextHandlerClass != null) {
78              try {
79                  return (CallContextHandler) ClassLoaderUtil.loadClass(callContextHandlerClass).newInstance();
80              } catch (Exception e) {
81                  throw new ServletException("Could not load call context handler: " + e, e);
82              }
83          }
84  
85          return null;
86      }
87  
88      /**
89       * Sets the binding.
90       */
91      protected void setBinding(String binding) {
92          this.binding = binding;
93      }
94  
95      /**
96       * Returns the CMIS version configured for this servlet.
97       */
98      protected CmisVersion getCmisVersion() {
99          return cmisVersion;
100     }
101 
102     protected void setCmisVersion(CmisVersion cmisVersion) {
103         this.cmisVersion = cmisVersion;
104     }
105 
106     /**
107      * Returns the {@link CmisServiceFactory}.
108      */
109     protected CmisServiceFactory getServiceFactory() {
110         return factory;
111     }
112 
113     /**
114      * Return the {@link CallContextHandler}
115      */
116     protected CallContextHandler getCallContextHandler() {
117         return callContextHandler;
118     }
119 
120     /**
121      * Checks the CSRF if configured. Throws an
122      * {@link CmisPermissionDeniedException} if something is wrong.
123      */
124     protected void checkCsrfToken(HttpServletRequest req, HttpServletResponse resp, boolean isRepositoryInfoRequest,
125             boolean isContentRequest) {
126         csrfManager.check(req, resp, isRepositoryInfoRequest, isContentRequest);
127     }
128 
129     /**
130      * Creates a {@link CallContext} object from a servlet request.
131      */
132     protected CallContext createContext(ServletContext servletContext, HttpServletRequest request,
133             HttpServletResponse response, TempStoreOutputStreamFactory streamFactory) {
134         String[] pathFragments = HttpUtils.splitPath(request);
135 
136         String repositoryId = null;
137         if (pathFragments.length > 0) {
138             repositoryId = pathFragments[0];
139         }
140 
141         if (repositoryId == null && CallContext.BINDING_ATOMPUB.equals(binding)) {
142             // it's a getRepositories or getRepositoryInfo call
143             // getRepositoryInfo has the repository ID in the query parameters
144             repositoryId = HttpUtils.getStringParameter(request, Constants.PARAM_REPOSITORY_ID);
145         }
146 
147         CallContextImpl context = null;
148 
149         if (CallContext.BINDING_BROWSER.equals(binding)) {
150             context = new BrowserCallContextImpl(binding, cmisVersion, repositoryId, servletContext, request, response,
151                     factory, streamFactory);
152         } else {
153             context = new CallContextImpl(binding, cmisVersion, repositoryId, servletContext, request, response,
154                     factory, streamFactory);
155         }
156 
157         // decode range
158         context.setRange(request.getHeader("Range"));
159 
160         // get locale
161         context.setAcceptLanguage(request.getHeader("Accept-Language"));
162 
163         // call call context handler
164         if (callContextHandler != null) {
165             Map<String, String> callContextMap = callContextHandler.getCallContextMap(request);
166             if (callContextMap != null) {
167                 for (Map.Entry<String, String> e : callContextMap.entrySet()) {
168                     context.put(e.getKey(), e.getValue());
169                 }
170             }
171         }
172 
173         return context;
174     }
175 
176     protected static String createLogMessage(Throwable t, HttpServletRequest request) {
177         StringBuilder sb = new StringBuilder(256);
178 
179         sb.append(t.getMessage());
180 
181         sb.append(" (");
182         sb.append(request.getMethod());
183         sb.append(' ');
184         sb.append(request.getRequestURL().toString());
185         if (request.getQueryString() != null) {
186             sb.append('?');
187             sb.append(request.getQueryString());
188         }
189         sb.append(')');
190 
191         return sb.toString();
192     }
193 }