KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > latka > Latka


1 /*
2  * Copyright 1999-2002,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.commons.latka;
18
19 import java.io.File JavaDoc;
20 import java.io.FileInputStream JavaDoc;
21 import java.io.FileWriter JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.StringReader JavaDoc;
24 import java.io.StringWriter JavaDoc;
25 import java.net.URL JavaDoc;
26 import java.text.SimpleDateFormat JavaDoc;
27 import java.util.Date JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.Properties JavaDoc;
30
31 import javax.xml.transform.Source JavaDoc;
32 import javax.xml.transform.Transformer JavaDoc;
33 import javax.xml.transform.TransformerException JavaDoc;
34 import javax.xml.transform.TransformerFactory JavaDoc;
35 import javax.xml.transform.stream.StreamResult JavaDoc;
36 import javax.xml.transform.stream.StreamSource JavaDoc;
37
38 import org.apache.commons.jelly.Jelly;
39 import org.apache.commons.jelly.JellyContext;
40 import org.apache.commons.jelly.XMLOutput;
41
42 import org.apache.commons.latka.event.LatkaEventInfo;
43 import org.apache.commons.latka.event.LatkaEventListener;
44 import org.apache.commons.latka.jelly.JellyUtils;
45
46 import org.apache.log4j.Category;
47
48 /**
49  * This is the primary class for executing Latka functional
50  * tests. The main(String aargs[]) class provides a convenient
51  * command-line interface for executing single tests. See the
52  * Latka documentation for details on command-line usage.
53  * There is also a webapp-based Latka interface.
54  *
55  * @see Suite
56  * @see LatkaProperties
57  *
58  * @author Morgan Delagrange
59  * @author <a HREF="mailto:dion@apache.org">dIon Gillard</a>
60  *
61  * @version $Revision$
62  */

63 public class Latka {
64
65     /** whether xml parsing is validating or not */
66     protected boolean _isValidating = true;
67     /** XSL stylesheet url to use when generating XML */
68     protected URL JavaDoc _reportStylesheetUrl = null;
69
70     /** log4j category for logged output */
71     protected static final Category _log =
72                              Category.getInstance(Latka.class.getName());
73
74     /** Latka configuration variables */
75     protected Properties JavaDoc _props = LatkaProperties.getProperties();
76
77     /** Message displayed to user when incorrect args provided */
78     private static final String JavaDoc LATKA_USAGE =
79             "\n######################\n"
80         + "Latka usage:\n"
81         + " java org.apache.commons.latka.Latka \"XML_suite_URL\" "
82         + "[\"propfile:file_name\"] [\"prop:prop_name=prop_value\"]\n\n"
83         + "The quotes around properties are REQUIRED.\n"
84         + "######################\n";
85     
86     /**
87      * Execute a single Latka test suite. The Latka event listner
88      * will receive all the events generated during the test.
89      * The Latka packages contain an implmentation of LatkaEventInfo
90      * which can generate an XML report according to a standard
91      * DTD (see documentation).
92      *
93      * @param suite test suite to execute
94      * @param listener target for test events
95      * @exception LatkaException
96      * when any internal error occurs
97      * @see XMLReporter XML-based implementation of LatkaEventListener
98      */

99     public void runTests(Suite suite, LatkaEventListener listener)
100                 throws LatkaException {
101     
102         try {
103
104             Jelly jelly = new Jelly();
105             URL JavaDoc url = suite.getURL();
106             jelly.setUrl(url);
107             jelly.setValidateXML(_isValidating);
108             jelly.setDefaultNamespaceURI("jelly:org.apache.commons.latka.jelly.LatkaTagLibrary");
109
110             JellyContext context = buildJellyContext();
111             JellyUtils.getInstance().setLatkaEventListener(context,listener);
112
113             String JavaDoc exturl = url.toExternalForm();
114             int lastSlash = exturl.lastIndexOf("/");
115             String JavaDoc extBase = exturl.substring(0,lastSlash+1);
116             URL JavaDoc baseurl = new URL JavaDoc(extBase);
117             context.setCurrentURL(baseurl);
118
119             // add listener
120
jelly.compileScript().run(context,XMLOutput.createDummyXMLOutput());
121
122         } catch (Exception JavaDoc e) {
123             throw new LatkaException(e);
124         }
125     }
126
127     protected JellyContext buildJellyContext() {
128         JellyContext context = new JellyContext();
129         Iterator JavaDoc keys = _props.keySet().iterator();
130         while (keys.hasNext()) {
131             String JavaDoc key = (String JavaDoc) keys.next();
132             String JavaDoc value = _props.getProperty(key);
133             context.setVariable(key,value);
134         }
135
136         return context;
137     }
138
139     /**
140      * Set whether or not Latka will validate the XML in
141      * each test.
142      *
143      * @param isValidating whether or not to validate XML
144      */

145     public void setValidating(boolean isValidating) {
146         _isValidating = isValidating;
147     }
148
149     /**
150      * Set the URL to be used when transforming XML generated by the XMLReporter
151      * @param url a valid URL referencing a stylesheet
152      */

153     public void setReportStylesheet(URL JavaDoc url) {
154         _reportStylesheetUrl = url;
155     }
156
157     /**
158      * Use this method to log XML generated by the
159      * XMLReporter class.
160      *
161      * @param xml XML to be logged
162      * @throws IOException if the XML could not be written to the filesystem
163      */

164     protected void logXML(String JavaDoc xml) throws IOException JavaDoc {
165
166         String JavaDoc logProp = _props.getProperty("latka.writeLog");
167         if ((logProp != null) && (logProp.equals("false"))) {
168             return;
169         }
170
171         File JavaDoc dir = new File JavaDoc("logs");
172         // try to create logs directory. if it fails, then check to
173
// make sure it is there (may have existed before) and is writeable
174
if (!dir.mkdirs()) {
175             if (!dir.exists ()) {
176                 throw new IOException JavaDoc("Unable to create logs directory");
177             } else if (!dir.canWrite ()) {
178                 throw new IOException JavaDoc("Unable to write to logs directory");
179             }
180         }
181         SimpleDateFormat JavaDoc formatter = new SimpleDateFormat JavaDoc ("yyyyMMdd'-'HHmm");
182         String JavaDoc dateString = formatter.format(new Date JavaDoc());
183         File JavaDoc file = new File JavaDoc(dir, dateString + ".xml");
184         FileWriter JavaDoc fileWriter = new FileWriter JavaDoc(file);
185         fileWriter.write(xml);
186         fileWriter.close();
187     }
188
189     /**
190      * Transform the XML generated by the XMLReporter using
191      * the default stylesheet.
192      *
193      * @param xml XML generated by XMLReporter
194      * @return transformed report
195      * @throws LatkaException if the XML could not be transformed
196      */

197     public String JavaDoc transformXML(String JavaDoc xml) throws LatkaException {
198     
199         try {
200             StringWriter JavaDoc output = new StringWriter JavaDoc();
201
202             Source JavaDoc xslSource = null;
203
204             if (_reportStylesheetUrl == null) {
205             ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
206             if (loader == null) {
207                 // there may not be a context class loader
208
loader = getClass().getClassLoader();
209             }
210
211             xslSource = new StreamSource JavaDoc(
212                             loader.getResourceAsStream(
213                             "org.apache.commons.latka.report.xsl")
214                         );
215             } else {
216                 xslSource = new StreamSource JavaDoc(_reportStylesheetUrl.toString());
217             }
218
219
220             Transformer JavaDoc transformer =
221             TransformerFactory.newInstance().newTransformer(xslSource);
222             StreamSource JavaDoc xmlSource = new StreamSource JavaDoc(new StringReader JavaDoc(xml));
223             StreamResult JavaDoc result = new StreamResult JavaDoc(output);
224             transformer.transform(xmlSource, result);
225             return output.toString();
226         } catch (TransformerException JavaDoc e) {
227             throw new LatkaException(e);
228         }
229     }
230
231     /**
232      * Processes the command line arguments, executes a single test.
233      * and processes the resulting report. Command line usage is
234      * described in the LATKA_USAGE constant.
235      *
236      * @param args arguments passed into the main(String[]) method
237      *
238      * @throws LatkaException if any problems are encountered during
239      * the execution of the tests
240      */

241     protected void runCommandLine(String JavaDoc args[]) throws LatkaException {
242
243         if (args.length < 1) {
244             System.out.println(LATKA_USAGE);
245         }
246
247         String JavaDoc urlString = args[0];
248
249         if (args.length > 1) {
250
251             for (int i = 1; i < args.length; ++i) {
252                 String JavaDoc arg = args[i];
253                 if (arg.startsWith("prop:")) {
254                     String JavaDoc propName = arg.substring(5, arg.indexOf("="));
255                     String JavaDoc propValue = arg.substring(arg.indexOf("=") + 1);
256                     _props.setProperty(propName, propValue);
257                 } else if (arg.startsWith("propfile:")) {
258                     try {
259                         _props.load(new FileInputStream JavaDoc(arg.substring(9)));
260                     } catch (IOException JavaDoc e) {
261                         System.out.println("Could not load user prop file, uri="
262                                             + arg.substring(9));
263                     }
264                 } else {
265                     throw new IllegalArgumentException JavaDoc(LATKA_USAGE);
266                 }
267             } // for
268
} // if
269

270         String JavaDoc xml = null;
271         XMLReporter listener = new XMLReporter();
272
273         // overkill, all we need is success/failure
274
LatkaEventInfo info = new DefaultLatkaEventInfo(listener);
275
276         try {
277
278             URL JavaDoc url = new URL JavaDoc(urlString);
279             Suite suite = new Suite(url);
280
281
282             runTests(suite, info);
283
284             xml = listener.getDocumentAsString();
285             logXML(xml);
286         } catch (IOException JavaDoc e) {
287             throw new LatkaException(e);
288         }
289
290         System.out.println(transformXML(xml));
291
292         if (info.didSuiteSucceed() == false) {
293             // throw an exception, so the process will
294
// return as a failure
295
throw new LatkaException("SUITE FAILED");
296         }
297     }
298
299     /**
300      * Execute a single test suite via the command line
301      * interface. See the Latka documentation for detailed
302      * usage instructions. The Java process will return
303      * a 0 if all tests succeed and a 1 if any fail
304      * or there is an unrecoverable error in the test
305      * execution.
306      *
307      * @param args arguments containing the test suite location
308      * and any properties or property file references
309      */

310     public static void main (String JavaDoc args[]) {
311
312         Latka latka = new Latka();
313         try {
314             latka.runCommandLine(args);
315         } catch (LatkaException e) {
316             e.printStackTrace();
317             System.exit(1);
318         }
319     
320     }
321 }
322
Popular Tags