001: /*
002: * ========================================================================
003: *
004: * Copyright 2001-2004 The Apache Software Foundation.
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: *
018: * ========================================================================
019: */
020: package org.apache.cactus.internal.server;
021:
022: import javax.servlet.ServletException;
023: import javax.servlet.http.HttpServletRequest;
024:
025: import org.apache.cactus.internal.HttpServiceDefinition;
026: import org.apache.cactus.internal.ServiceEnumeration;
027: import org.apache.cactus.spi.server.ImplicitObjects;
028: import org.apache.cactus.spi.server.TestController;
029: import org.apache.commons.logging.Log;
030: import org.apache.commons.logging.LogFactory;
031:
032: /**
033: * Controller that extracts the requested service from the HTTP request and
034: * executes the request. Examples of requests are: executing a given test,
035: * returning the test result, verifying that the controller is correctly
036: * configured, etc.
037: *
038: * @version $Id: AbstractWebTestController.java 238991 2004-05-22 11:34:50Z vmassol $
039: */
040: public abstract class AbstractWebTestController implements
041: TestController {
042: /**
043: * The logger
044: */
045: private static final Log LOGGER = LogFactory
046: .getLog(AbstractWebTestController.class);
047:
048: /**
049: * @param theObjects the implicit objects coming from the redirector
050: * @return the test caller that will be used to execute the test
051: */
052: protected abstract AbstractWebTestCaller getTestCaller(
053: WebImplicitObjects theObjects);
054:
055: /**
056: * Handles the incoming request by extracting the requested service and
057: * calling the correct method on a <code>WebTestCaller</code>.
058: *
059: * @param theObjects the implicit objects (they are different for the
060: * different redirectors)
061: * @exception ServletException if an error occurs when servicing the
062: * request
063: */
064: public void handleRequest(ImplicitObjects theObjects)
065: throws ServletException {
066: WebImplicitObjects webImplicitObjects = (WebImplicitObjects) theObjects;
067:
068: // If the Cactus user has forgotten to put a needed jar on the server
069: // classpath (i.e. in WEB-INF/lib), then the servlet engine Webapp
070: // class loader will throw a NoClassDefFoundError exception. As this
071: // method is the entry point of the webapp, we'll catch all
072: // NoClassDefFoundError exceptions and report a nice error message
073: // for the user so that he knows he has forgotten to put a jar in the
074: // classpath. If we don't do this, the error will be trapped by the
075: // container and may not result in an ... err ... understandable error
076: // message (like in Tomcat) ...
077: try {
078: String serviceName = getServiceName(webImplicitObjects
079: .getHttpServletRequest());
080:
081: AbstractWebTestCaller caller = getTestCaller(webImplicitObjects);
082:
083: // TODO: will need a factory here real soon...
084:
085: ServiceEnumeration service = ServiceEnumeration
086: .valueOf(serviceName);
087:
088: // Is it the call test method service ?
089: if (service == ServiceEnumeration.CALL_TEST_SERVICE) {
090: caller.doTest();
091: }
092: // Is it the get test results service ?
093: else if (service == ServiceEnumeration.GET_RESULTS_SERVICE) {
094: caller.doGetResults();
095: }
096: // Is it the test connection service ?
097: // This service is only used to verify that connection between
098: // client and server is working fine
099: else if (service == ServiceEnumeration.RUN_TEST_SERVICE) {
100: caller.doRunTest();
101: }
102: // Is it the service to create an HTTP session?
103: else if (service == ServiceEnumeration.CREATE_SESSION_SERVICE) {
104: caller.doCreateSession();
105: } else if (service == ServiceEnumeration.GET_VERSION_SERVICE) {
106: caller.doGetVersion();
107: } else {
108: String message = "Unknown service [" + serviceName
109: + "] in HTTP request.";
110:
111: LOGGER.error(message);
112: throw new ServletException(message);
113: }
114: } catch (NoClassDefFoundError e) {
115: // try to display messages as descriptive as possible !
116: if (e.getMessage().startsWith("junit/framework")) {
117: String message = "You must put the JUnit jar in "
118: + "your server classpath (in WEB-INF/lib for example)";
119:
120: LOGGER.error(message, e);
121: throw new ServletException(message, e);
122: } else {
123: String message = "You are missing a jar in your "
124: + "classpath (class [" + e.getMessage()
125: + "] could not " + "be found";
126:
127: LOGGER.error(message, e);
128: throw new ServletException(message, e);
129: }
130: }
131: }
132:
133: /**
134: * @param theRequest the HTTP request
135: * @return the service name of the service to call (there are 2 services
136: * "do test" and "get results"), extracted from the HTTP request
137: * @exception ServletException if the service to execute is missing from
138: * the HTTP request
139: */
140: private String getServiceName(HttpServletRequest theRequest)
141: throws ServletException {
142: // Call the correct Service method
143: String queryString = theRequest.getQueryString();
144: String serviceName = ServletUtil.getQueryStringParameter(
145: queryString, HttpServiceDefinition.SERVICE_NAME_PARAM);
146:
147: if (serviceName == null) {
148: String message = "Missing service name parameter ["
149: + HttpServiceDefinition.SERVICE_NAME_PARAM
150: + "] in HTTP request. Received query string is ["
151: + queryString + "].";
152:
153: LOGGER.debug(message);
154: throw new ServletException(message);
155: }
156:
157: LOGGER.debug("Service to call = " + serviceName);
158:
159: return serviceName;
160: }
161: }
|