2011/08/05 - Jakarta Cactus has been retired.

For more information, please explore the Attic.

View Javadoc

1   /* 
2    * ========================================================================
3    * 
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements.  See the NOTICE file distributed with
6    * this work for additional information regarding copyright ownership.
7    * The ASF licenses this file to You under the Apache License, Version 2.0
8    * (the "License"); you may not use this file except in compliance with
9    * the License.  You may obtain a copy of the License at
10   * 
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * 
19   * ========================================================================
20   */
21  package org.apache.cactus.internal.server;
22  
23  import javax.servlet.ServletException;
24  import javax.servlet.http.HttpServletRequest;
25  
26  import org.apache.cactus.internal.HttpServiceDefinition;
27  import org.apache.cactus.internal.ServiceEnumeration;
28  import org.apache.cactus.spi.server.ImplicitObjects;
29  import org.apache.cactus.spi.server.TestController;
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  
33  /**
34   * Controller that extracts the requested service from the HTTP request and
35   * executes the request. Examples of requests are: executing a given test, 
36   * returning the test result, verifying that the controller is correctly 
37   * configured, etc.
38   *
39   * @version $Id: AbstractWebTestController.java 238991 2004-05-22 11:34:50Z vmassol $
40   */
41  public abstract class AbstractWebTestController implements TestController
42  {
43      /**
44       * The logger.
45       */
46      private static final Log LOGGER = 
47          LogFactory.getLog(AbstractWebTestController.class);
48  
49      /**
50       * @param theObjects the implicit objects coming from the redirector
51       * @return the test caller that will be used to execute the test
52       */
53      protected abstract AbstractWebTestCaller getTestCaller(
54          WebImplicitObjects theObjects);
55  
56      /**
57       * Handles the incoming request by extracting the requested service and
58       * calling the correct method on a <code>WebTestCaller</code>.
59       *
60       * @param theObjects the implicit objects (they are different for the
61       *                   different redirectors)
62       * @exception ServletException if an error occurs when servicing the
63       *            request
64       */
65      public void handleRequest(ImplicitObjects theObjects)
66          throws ServletException
67      {
68          WebImplicitObjects webImplicitObjects = (WebImplicitObjects) theObjects;
69  
70          // If the Cactus user has forgotten to put a needed jar on the server
71          // classpath (i.e. in WEB-INF/lib), then the servlet engine Webapp
72          // class loader will throw a NoClassDefFoundError exception. As this
73          // method is the entry point of the webapp, we'll catch all
74          // NoClassDefFoundError exceptions and report a nice error message
75          // for the user so that he knows he has forgotten to put a jar in the
76          // classpath. If we don't do this, the error will be trapped by the
77          // container and may not result in an ... err ... understandable error
78          // message (like in Tomcat) ...
79          try
80          {
81              String serviceName = 
82                  getServiceName(webImplicitObjects.getHttpServletRequest());
83  
84              AbstractWebTestCaller caller = getTestCaller(webImplicitObjects);
85  
86              // TODO: will need a factory here real soon...
87              
88              ServiceEnumeration service =
89                  ServiceEnumeration.valueOf(serviceName);
90              
91              // Is it the call test method service ?
92              if (service == ServiceEnumeration.CALL_TEST_SERVICE)
93              {
94                  caller.doTest();
95              }
96              // Is it the get test results service ?
97              else if (service == ServiceEnumeration.GET_RESULTS_SERVICE)
98              {
99                  caller.doGetResults();
100             }
101             // Is it the test connection service ?
102             // This service is only used to verify that connection between
103             // client and server is working fine
104             else if (service == ServiceEnumeration.RUN_TEST_SERVICE)
105             {
106                 caller.doRunTest();
107             }
108             // Is it the service to create an HTTP session?
109             else if (service == ServiceEnumeration.CREATE_SESSION_SERVICE)
110             {
111                 caller.doCreateSession();                
112             }
113             else if (service == ServiceEnumeration.GET_VERSION_SERVICE)
114             {
115                 caller.doGetVersion();
116             }
117             else
118             {
119                 String message = "Unknown service [" + serviceName
120                     + "] in HTTP request.";
121 
122                 LOGGER.error(message);
123                 throw new ServletException(message);
124             }
125         }
126         catch (NoClassDefFoundError e)
127         {
128             // try to display messages as descriptive as possible !
129             if (e.getMessage().startsWith("junit/framework"))
130             {
131                 String message = "You must put the JUnit jar in "
132                     + "your server classpath (in WEB-INF/lib for example)";
133 
134                 LOGGER.error(message, e);
135                 throw new ServletException(message, e);
136             }
137             else
138             {
139                 String message = "You are missing a jar in your "
140                     + "classpath (class [" + e.getMessage()
141                     + "] could not " + "be found";
142 
143                 LOGGER.error(message, e);
144                 throw new ServletException(message, e);
145             }
146         }
147     }
148 
149     /**
150      * @param theRequest the HTTP request
151      * @return the service name of the service to call (there are 2 services
152      *         "do test" and "get results"), extracted from the HTTP request
153      * @exception ServletException if the service to execute is missing from
154      *            the HTTP request
155      */
156     private String getServiceName(HttpServletRequest theRequest)
157         throws ServletException
158     {
159         // Call the correct Service method
160         String queryString = theRequest.getQueryString();
161         String serviceName = ServletUtil.getQueryStringParameter(queryString, 
162             HttpServiceDefinition.SERVICE_NAME_PARAM);
163 
164         if (serviceName == null)
165         {
166             String message = "Missing service name parameter ["
167                 + HttpServiceDefinition.SERVICE_NAME_PARAM
168                 + "] in HTTP request. Received query string is ["
169                 + queryString + "].";
170 
171             LOGGER.debug(message);
172             throw new ServletException(message);
173         }
174 
175         LOGGER.debug("Service to call = " + serviceName);
176 
177         return serviceName;
178     }
179 }