KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cactus > server > runner > ServletTestRunner


1 /*
2  * ========================================================================
3  *
4  * Copyright 2001-2004 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * 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, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * ========================================================================
19  */

20 package org.apache.cactus.server.runner;
21
22 import java.io.InputStream JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.Reader JavaDoc;
25 import java.io.PrintWriter JavaDoc;
26 import java.io.StringReader JavaDoc;
27 import java.io.Writer JavaDoc;
28 import java.lang.reflect.Constructor JavaDoc;
29 import java.lang.reflect.Method JavaDoc;
30
31 import javax.servlet.ServletException JavaDoc;
32 import javax.servlet.UnavailableException JavaDoc;
33 import javax.servlet.http.HttpServlet JavaDoc;
34 import javax.servlet.http.HttpServletRequest JavaDoc;
35 import javax.servlet.http.HttpServletResponse JavaDoc;
36
37 import junit.framework.Test;
38 import junit.framework.TestResult;
39
40 import org.apache.cactus.internal.configuration.BaseConfiguration;
41 import org.apache.cactus.internal.configuration.ConfigurationInitializer;
42 import org.apache.cactus.internal.server.runner.WebappTestRunner;
43 import org.apache.cactus.internal.server.runner.XMLFormatter;
44
45 /**
46  * Helper servlet to start a JUnit Test Runner in a webapp.
47  *
48  * <p>
49  * This class currently does a couple of reflection tricks to avoid a direct
50  * dependancy on the TraX API (<code>javax.xml.transform.*</code>),
51  * encapsulated in the
52  * {@link org.apache.cactus.internal.server.runner.XMLTransformer} class.
53  * </p>
54  *
55  * @version $Id: ServletTestRunner.java,v 1.4 2004/06/27 15:23:30 vmassol Exp $
56  */

57 public class ServletTestRunner extends HttpServlet JavaDoc
58 {
59     /**
60      * HTTP parameter containing name of test suite to execute
61      */

62     private static final String JavaDoc HTTP_SUITE_PARAM = "suite";
63
64     /**
65      * HTTP parameter that determines whether the XML test results should be
66      * transformed using the XSLT stylesheet specified as initialization
67      * parameter.
68      */

69     private static final String JavaDoc HTTP_TRANSFORM_PARAM = "transform";
70
71     /**
72      * HTTP parameter containing name of the XSL stylesheet to put in the
73      * returned XML test result. It will only work if the browser supports
74      * this feature (IE does, I don't know about others).
75      */

76     private static final String JavaDoc HTTP_XSL_PARAM = "xsl";
77
78     /**
79      * Name of the servlet initialization parameter that contains the path to
80      * the XSLT stylesheet for transforming the XML report into HTML.
81      */

82     private static final String JavaDoc XSL_STYLESHEET_PARAM = "xsl-stylesheet";
83
84     /**
85      * Encoding to use for the returned XML.
86      */

87     private static final String JavaDoc ENCODING_PARAM = "encoding";
88     
89     /**
90      * The XML transformer. Avoid direct dependancy by using reflection.
91      */

92     private Object JavaDoc transformer = null;
93
94     /**
95      * Indicates whether the servlet has sufficient permissions to set a
96      * system property, to be able to set the cactus.contentURL property. This
97      * is set to false if the first attempt to set the property throws a
98      * SecurityException.
99      */

100     private boolean canSetSystemProperty = true;
101
102     /**
103      * Called by the container when the servlet is initialized.
104      *
105      * @throws ServletException If an initialization parameter contains an
106      * illegal value
107      */

108     public void init() throws ServletException JavaDoc
109     {
110         // Reset the Cactus initialization so that multiple web application can
111
// work with different Cactus configurations. Otherwise, as the Cactus
112
// initialization is JVM-wide, the config is not read again.
113
ConfigurationInitializer.initialize(true);
114
115         // Check whether XSLT transformations should be done server-side and
116
// build the templates if an XSLT processor is available
117
String JavaDoc xslStylesheetParam = getInitParameter(XSL_STYLESHEET_PARAM);
118         if (xslStylesheetParam != null)
119         {
120             InputStream JavaDoc xslStylesheet =
121                 getServletContext().getResourceAsStream(xslStylesheetParam);
122             if (xslStylesheet != null)
123             {
124                 try
125                 {
126                     Class JavaDoc transformerClass = Class.forName("org.apache.cactus."
127                         + "internal.server.runner.XMLTransformer");
128                     Constructor JavaDoc transformerCtor =
129                         transformerClass.getConstructor(
130                         new Class JavaDoc[] {InputStream JavaDoc.class});
131                     transformer = transformerCtor.newInstance(
132                         new Object JavaDoc[] {xslStylesheet});
133                 }
134                 catch (Throwable JavaDoc t)
135                 {
136                     log("Could not instantiate XMLTransformer - will not "
137                         + "perform server-side XSLT transformations", t);
138                 }
139             }
140             else
141             {
142                 throw new UnavailableException JavaDoc(
143                     "The initialization parameter 'xsl-stylesheet' does not "
144                     + "refer to an existing resource");
145             }
146         }
147     }
148
149     /**
150      * Starts the test suite passed as a HTTP parameter
151      *
152      * @param theRequest the incoming HTTP client request
153      * @param theResponse the outgoing HTTP client request to send back.
154      *
155      * @exception ServletException if an error occurs when servicing the
156      * request
157      * @exception IOException if an error occurs when servicing the request
158      */

159     public void doGet(HttpServletRequest JavaDoc theRequest,
160         HttpServletResponse JavaDoc theResponse) throws ServletException JavaDoc,
161         IOException JavaDoc
162     {
163         // Verify if a suite parameter exists
164
String JavaDoc suiteClassName = theRequest.getParameter(HTTP_SUITE_PARAM);
165
166         // Set up default Cactus System properties so that there is no need
167
// to have a cactus.properties file in WEB-INF/classes
168
setSystemProperties(theRequest);
169
170         if (suiteClassName == null)
171         {
172             throw new ServletException JavaDoc("Missing HTTP parameter ["
173                 + HTTP_SUITE_PARAM + "] in request");
174         }
175
176         // Get the XSL stylesheet parameter if any
177
String JavaDoc xslParam = theRequest.getParameter(HTTP_XSL_PARAM);
178
179         // Get the transform parameter if any
180
String JavaDoc transformParam = theRequest.getParameter(HTTP_TRANSFORM_PARAM);
181
182         // Get the enconding parameter, if any
183
String JavaDoc encoding = theRequest.getParameter(ENCODING_PARAM);
184         
185         // Run the tests
186
String JavaDoc xml = run(suiteClassName, xslParam, encoding);
187
188         // Check if we should do the transformation server side
189
if ((transformParam != null) && (transformer != null))
190         {
191             // Transform server side
192
try
193             {
194                 Method JavaDoc getContentTypeMethod =
195                     transformer.getClass().getMethod(
196                         "getContentType", new Class JavaDoc[0]);
197                 theResponse.setContentType((String JavaDoc)
198                     getContentTypeMethod.invoke(transformer, new Object JavaDoc[0]));
199                 PrintWriter JavaDoc out = theResponse.getWriter();
200                 Method JavaDoc transformMethod =
201                     transformer.getClass().getMethod(
202                         "transform", new Class JavaDoc[] {Reader JavaDoc.class, Writer JavaDoc.class});
203                 transformMethod.invoke(transformer,
204                     new Object JavaDoc[] {new StringReader JavaDoc(xml), out});
205             }
206             catch (Exception JavaDoc e)
207             {
208                 throw new ServletException JavaDoc(
209                     "Problem applying the XSLT transformation", e);
210             }
211         }
212         else
213         {
214             // Transform client side (or not at all)
215
theResponse.setContentType("text/xml");
216             PrintWriter JavaDoc pw = theResponse.getWriter();
217             pw.println(xml);
218         }
219     }
220
221     /**
222      * Set up default Cactus System properties so that there is no need
223      * to have a <code>cactus.properties</code> file in WEB-INF/classes.
224      * However, if a <code>cactus.properties</code> file is found, the
225      * properties are read from it.
226      *
227      * Note: If the JVM security policy prevents setting System properties
228      * you will still need to provide a cactus.properties file.
229      *
230      * @param theRequest the HTTP request coming from the browser (used
231      * to extract information about the server name, port, etc)
232      */

233     private void setSystemProperties(HttpServletRequest JavaDoc theRequest)
234     {
235         // TODO: We cannot call BaseConfiguration.getContextURL() as it
236
// throws an exception if the context URL property is not defined.
237
// It would be good to change that behavior for a better reuse
238
String JavaDoc contextURL = System.getProperty(
239             BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY);
240
241         // If the context URL propety has not been set, we set a default
242
// value based on the ServletTestRunner mapping in the web app.
243
if (contextURL == null)
244         {
245             if (this.canSetSystemProperty)
246             {
247                 try
248                 {
249                     System.setProperty(
250                         BaseConfiguration.CACTUS_CONTEXT_URL_PROPERTY,
251                         "http://" + theRequest.getServerName() + ":"
252                         + theRequest.getServerPort()
253                         + theRequest.getContextPath());
254                 }
255                 catch (SecurityException JavaDoc se)
256                 {
257                     log("Could not set the Cactus context URL as system "
258                         + "property, you will have to include a Cactus "
259                         + "properties file in the class path of the web "
260                         + "application", se);
261                     this.canSetSystemProperty = false;
262                 }
263             }
264         }
265     }
266     
267     /**
268      * Run the suite tests and return the result.
269      *
270      * @param theSuiteClassName the suite containing the tests to run
271      * @param theXslFileName the name of the XSL stylesheet or null if we don't
272      * want to apply a stylesheet to the returned XML data
273      * @param theEncoding the encoding to use for the returned XML or null if
274      * default encoding is to be used
275      * @return the result object
276      * @exception ServletException if the suite failed to be loaded
277      */

278     protected String JavaDoc run(String JavaDoc theSuiteClassName, String JavaDoc theXslFileName,
279         String JavaDoc theEncoding) throws ServletException JavaDoc
280     {
281         TestResult result = new TestResult();
282
283         XMLFormatter formatter = new XMLFormatter();
284         formatter.setXslFileName(theXslFileName);
285         formatter.setSuiteClassName(theSuiteClassName);
286
287         if (theEncoding != null)
288         {
289             formatter.setEncoding(theEncoding);
290         }
291         
292         result.addListener(formatter);
293
294         long startTime = System.currentTimeMillis();
295
296         WebappTestRunner testRunner = new WebappTestRunner();
297
298         Test suite = testRunner.getTest(theSuiteClassName);
299
300         if (suite == null)
301         {
302             throw new ServletException JavaDoc("Failed to load test suite ["
303                 + theSuiteClassName + "], Reason is ["
304                 + testRunner.getErrorMessage() + "]");
305         }
306
307         // Run the tests
308
suite.run(result);
309
310         long endTime = System.currentTimeMillis();
311
312         formatter.setTotalDuration(endTime - startTime);
313
314         return formatter.toXML(result);
315     }
316 }
317
Popular Tags