This project has retired. For details please refer to its Attic page.
Dispatcher xref

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.io.Serializable;
22  import java.lang.reflect.InvocationTargetException;
23  import java.lang.reflect.Method;
24  import java.util.HashMap;
25  import java.util.Map;
26  
27  import javax.servlet.http.HttpServletRequest;
28  import javax.servlet.http.HttpServletResponse;
29  
30  import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException;
31  import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
32  import org.apache.chemistry.opencmis.commons.server.CallContext;
33  import org.apache.chemistry.opencmis.commons.server.CmisService;
34  import org.apache.commons.logging.Log;
35  import org.apache.commons.logging.LogFactory;
36  
37  /**
38   * Dispatcher for the AtomPub and Browser binding servlet.
39   */
40  public class Dispatcher implements Serializable {
41  
42      private static final long serialVersionUID = 1L;
43  
44      public static final String METHOD_GET = "GET";
45      public static final String METHOD_POST = "POST";
46      public static final String METHOD_PUT = "PUT";
47      public static final String METHOD_DELETE = "DELETE";
48  
49      private static final Log LOG = LogFactory.getLog(Dispatcher.class.getName());
50  
51      private final boolean caseSensitive;
52      private Map<String, Method> methodMap = new HashMap<String, Method>();
53  
54      public Dispatcher() {
55          this(true);
56      }
57  
58      public Dispatcher(boolean caseSensitive) {
59          this.caseSensitive = caseSensitive;
60      }
61  
62      /**
63       * Connects a resource and HTTP method with a class and a class method.
64       */
65      public synchronized void addResource(String resource, String httpMethod, Class<?> clazz, String classmethod)
66              throws NoSuchMethodException {
67  
68          Method m = clazz.getMethod(classmethod, CallContext.class, CmisService.class, String.class,
69                  HttpServletRequest.class, HttpServletResponse.class);
70  
71          methodMap.put(getKey(resource, httpMethod), m);
72      }
73  
74      /**
75       * Find the appropriate method an call it.
76       * 
77       * @return <code>true</code> if the method was found, <code>false</code>
78       *         otherwise.
79       */
80      public boolean dispatch(String resource, String httpMethod, CallContext context, CmisService service,
81              String repositoryId, HttpServletRequest request, HttpServletResponse response) {
82          Method m = methodMap.get(getKey(resource, httpMethod));
83          if (m == null) {
84              return false;
85          }
86  
87          if (LOG.isDebugEnabled()) {
88              LOG.debug(repositoryId + " / " + resource + ", " + httpMethod + " -> " + m.getName());
89          }
90  
91          try {
92              m.invoke(null, context, service, repositoryId, request, response);
93          } catch (IllegalAccessException e) {
94              throw new CmisRuntimeException("Internal error!", e);
95          } catch (InvocationTargetException e) {
96              if (e.getCause() instanceof CmisBaseException) {
97                  throw (CmisBaseException) e.getCause();
98              } else {
99                  throw new CmisRuntimeException(e.getMessage(), e);
100             }
101         }
102 
103         return true;
104     }
105 
106     /**
107      * Generates a map key from a resource and an HTTP method.
108      */
109     private String getKey(String resource, String httpMethod) {
110         String s = resource + "/" + httpMethod;
111         return (caseSensitive ? s : s.toUpperCase());
112     }
113 }