Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/esau/ptarmigan/impl/test/PtarmiganTest.java


1   /* $Header: /cvsroot/ptarmigan/ptarmigan/src/java/org/esau/ptarmigan/impl/test/PtarmiganTest.java,v 1.4 2002/09/24 02:51:47 reedesau Exp $ */
2   
3   package org.esau.ptarmigan.impl.test;
4   
5   import java.io.File;
6   import java.io.FileInputStream;
7   import java.io.FileOutputStream;
8   import java.io.BufferedInputStream;
9   import java.io.FileReader;
10  import java.io.IOException;
11  import java.io.InputStream;
12  import java.io.OutputStreamWriter;
13  import java.io.Reader;
14  import java.io.Writer;
15  import javax.xml.parsers.ParserConfigurationException;
16  
17  import junit.framework.Test;
18  import junit.framework.TestCase;
19  import junit.framework.TestSuite;
20  import junit.framework.Assert;
21  import org.custommonkey.xmlunit.Diff;
22  
23  import org.xml.sax.SAXException;
24  import org.xml.sax.InputSource;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  
29  import org.jdom.Attribute;
30  import org.jdom.Document;
31  import org.jdom.Element;
32  import org.jdom.JDOMException;
33  import org.jdom.Namespace;
34  import org.jdom.input.SAXBuilder;
35  import org.jdom.output.XMLOutputter;
36  
37  import org.esau.ptarmigan.Generator;
38  import org.esau.ptarmigan.GeneratorFactory;
39  import org.esau.ptarmigan.util.HelperIO;
40  import org.esau.ptarmigan.util.HelperURL;
41  
42  /**
43   * Test Suite for the default implementation of Ptarmigan
44   * <p>
45   * This suite presently relies on JDOM to (1) build documents from
46   * SAX events and (2) output XML.
47   * <p>
48   * This suite presently relies on xmlunit.Diff to detect parsing
49   * problems.
50   * <p>
51   * TODO: how to handle different property/feature combinations?
52   * Different directories for test files?
53   * Something in the filename?
54   *
55   * @author Reed Esau
56   */
57  public class PtarmiganTest extends TestCase {
58  
59      /** this will do schema validation */
60      static final String SAX_PARSER_XERCES = "org.apache.xerces.parsers.SAXParser";
61  
62      String m_test_input_dir;
63      String m_test_control_dir;
64      String m_test_output_dir;
65  
66      boolean m_recursive;   // if true, will drill down on input dir
67      boolean m_validate;    // if true, feeds generated xml to validating parser
68      boolean m_verify;      // if true, diffs control vs forecasted
69      boolean m_incl_digest; // if true, a digest will be calculated against the data range of each file
70      boolean m_incl_playlist_entries;
71  
72      public PtarmiganTest(String name) {
73          super(name);
74  
75          m_test_input_dir   = System.getProperty("test.input.dir"  );
76          m_test_control_dir = System.getProperty("test.control.dir");
77          m_test_output_dir  = System.getProperty("test.output.dir" );
78          m_recursive              = getPropertyBool("test.recursive"    , false);
79          m_validate               = getPropertyBool("test.validate"     , true );
80          m_verify                 = getPropertyBool("test.verify"       , false);
81          m_incl_digest            = getPropertyBool("test.incl_digest"  , false);
82          m_incl_playlist_entries  = getPropertyBool("test.incl_playlist_entries", true);
83  
84          log.debug("m_test_input_dir  =" + m_test_input_dir  );
85          log.debug("m_test_control_dir=" + m_test_control_dir);
86          log.debug("m_test_output_dir =" + m_test_output_dir );
87          log.debug("m_recursive       =" + m_recursive             );
88          log.debug("m_validate        =" + m_validate              );
89          log.debug("m_verify          =" + m_verify                );
90          log.debug("m_incl_digest     =" + m_incl_digest           );
91          log.debug("m_incl_playlist_entries =" + m_incl_playlist_entries );
92      }
93  
94  
95      public static Test suite() {
96          return new TestSuite(PtarmiganTest.class);
97      }
98  
99  
100     /** run generator against all files specified in property "test.input.dir" */
101     public void testAll() {
102         try {
103             File dir = new File(m_test_input_dir);
104             parseDirectory(dir);
105             log.debug("done");
106         }
107         catch (Exception e) {
108             log.warn(e.getMessage());
109             e.printStackTrace();
110             Assert.fail();
111         }
112     }
113 
114     /** run generator against all files in specified directory */
115     void parseDirectory(File dir) throws Exception {
116         File[] files = dir.listFiles();
117         if (files == null) {
118             log.warn("parseDirectory: not found: " + dir);
119             return;
120         }
121         for (int i = 0; i < files.length; i++) {
122             File f = files[i];
123             if (f.isDirectory()) {
124                 if (m_recursive && f.getName().startsWith(".")==false)
125                     parseDirectory(f);        // recurse into child directories
126             }
127             else if (f.exists())
128                 parseFile(f);
129             else
130                 log.warn("parseDirectory: the file does not exist: " + f);
131         }
132     }
133 
134     /** run generator against one file */
135     void parseFile(File infile) throws Exception {
136 
137         log.debug("parseFile: infile=" + infile);
138 
139         Document doc = buildDocument(infile);              // parse to JDOM
140 
141         // output JDOM to XML
142         File outfile = new File(m_test_output_dir, infile.getName() + ".xml");
143         writeDocument(doc, outfile);
144 
145         if (m_validate) {
146             // because '#' in File objects cause trouble for JDOM/XML parser,
147             // we're converting to a system_id (i.e., a url)
148             String system_id = HelperURL.fileToSystemId(outfile);
149             build(system_id, true);           // validate that XML
150         }
151 
152         // and verify XML against the control
153         if (m_verify) {
154             File control_file = new File(m_test_control_dir, infile.getName() + ".xml");
155             verify(control_file, outfile);
156         }
157     }
158 
159     /**
160      * Build a JDOM document from a media file source using SAX and our own
161      * parser.  <P> Note that we do the dual assignment of InputStream/system_id
162      * to the InputSource.  This is because we can be sure that the system-id
163      * will be properly resolved to a filename, so we open it ourselves.  The
164      * system-id is provided so that the Ptarmigan generator can extract details
165      * from the file for output as SAX events.
166      */
167     Document buildDocument(File infile) throws Exception {
168 
169         Generator generator = GeneratorFactory.newInstance();
170 
171         //int buf_size = 0;
172         int buf_size = 8192;
173 
174         generator.setFeature(Generator.FEATURE_INCLUDE_DIGEST, m_incl_digest);
175         generator.setFeature(Generator.FEATURE_INCLUDE_PLAYLIST_ENTRIES,
176                              m_incl_playlist_entries);
177 
178         if (buf_size > 0)
179             generator.setProperty(Generator.PROPERTY_READ_LIMIT, new Integer(buf_size));
180 
181         SAXBuilder builder = new SAXBuilder();
182         builder.setXMLFilter(generator);
183 
184         InputStream is = null;
185         try {
186             is = new FileInputStream(infile);
187 
188             if (buf_size > 0)
189                 is = new BufferedInputStream(is, buf_size);
190 
191             InputSource input_source = new InputSource(is);
192 
193             String system_id = HelperURL.fileToSystemId(infile);
194             input_source.setSystemId(system_id);
195             log.debug("system_id=" + system_id);
196 
197             Document doc = builder.build(input_source);       // the heavy lifting!
198 
199             assignNamespace( doc.getRootElement() );
200 
201             return doc;
202         }
203         finally {
204             HelperIO.safeClose(is);
205         }
206     }
207 
208     /** */
209     void assignNamespace(Element root) throws IOException {
210 
211         String pt_uri = "http://esau.org/ns/ptarmigan";     //TODO: get dynamically from GeneratorImpl
212         String pt_xsd = "schema/ptarmigan.xsd";
213 
214         // convert the relative path to a URL for schemaLocation
215         String url_xsd = new File(pt_xsd).toURL().toExternalForm();
216 
217         Namespace ns_xsi = Namespace.getNamespace("xsi",
218                                                   "http://www.w3.org/2001/XMLSchema-instance");
219         root.addNamespaceDeclaration(ns_xsi);
220 
221         Attribute attr = new Attribute("schemaLocation",
222                                        pt_uri+" "+url_xsd,
223                                        ns_xsi);
224         root.setAttribute(attr);
225     }
226 
227     /** output a JDOM document as XML */
228     void writeDocument(Document doc, File file) throws IOException, JDOMException {
229         OutputStreamWriter writer = null;
230         try {
231             writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
232             writeDocument(doc, writer);
233         }
234         finally {
235             HelperIO.safeClose(writer);
236         }
237     }
238 
239 
240     /** output a JDOM document as XML */
241     void writeDocument(Document doc, Writer writer) throws IOException, JDOMException {
242         XMLOutputter op = new XMLOutputter("\t", true);
243         op.output(doc, writer);
244     }
245 
246 
247     /**
248      * build a JDOM document, optionall using the validation machinery in the
249      * SAX XML parser to validate the document
250      */
251     Document build(String system_id, boolean validate) throws IOException, JDOMException {
252         SAXBuilder builder;
253         if (validate) {
254             builder = new SAXBuilder(SAX_PARSER_XERCES, true);
255             builder.setFeature("http://apache.org/xml/features/validation/schema", true);
256         }
257         else
258             builder = new SAXBuilder();     // no validate
259 
260         log.info("building " + system_id);
261         return builder.build(system_id);   //NOTE: don't use File as '#' chars cause truncation
262     }
263 
264 
265     /**
266      * Compare two XML files and fail the TestCase if there are any differences.
267      */
268     void verify(File file1, File file2) throws IOException, SAXException, ParserConfigurationException {
269         Reader reader1 = null;
270         Reader reader2 = null;
271         try {
272             reader1 = new FileReader(file1);
273             reader2 = new FileReader(file2);
274             verify(reader1, reader2);
275         }
276         finally {
277             HelperIO.safeClose(reader1);
278             HelperIO.safeClose(reader2);
279         }
280     }
281 
282     /**
283      * Compare two XML readers and fail the TestCase if there are any differences.
284      */
285     void verify(Reader reader1, Reader reader2)
286     throws IOException, SAXException, ParserConfigurationException {
287 
288         Diff diff = new Diff(reader1, reader2);
289 
290         if (diff.identical() == false) {
291             StringBuffer buf = new StringBuffer("Difference found: ");
292             diff.appendMessage(buf);
293             log.debug(buf.toString());
294             Assert.fail();
295         }
296     }
297 
298 //
299 // helpers
300 //
301 
302     boolean getPropertyBool(String name, boolean def_value) {
303         String value = System.getProperty(name);
304         if (value == null)
305             return def_value;
306         return value.equalsIgnoreCase("true");
307     }
308 
309     /**
310      * logging object
311      */
312     static Log log = LogFactory.getLog(PtarmiganTest.class);
313 }
314 /*
315 PTARMIGAN MODIFIED BSD LICENSE
316 
317 Copyright (c) 2002, Reed Esau (reed.esau@pobox.com) All rights reserved.
318 
319 Redistribution and use in source and binary forms, with or without
320 modification, are permitted provided that the following conditions are
321 met:
322 
323 Redistributions of source code must retain the above copyright notice,
324 this list of conditions and the following disclaimer.
325 
326 Redistributions in binary form must reproduce the above copyright notice,
327 this list of conditions and the following disclaimer in the documentation
328 and/or other materials provided with the distribution.
329 
330 Neither the name of the Ptarmigan Project
331 (http://ptarmigan.sourceforge.net) nor the names of its contributors may
332 be used to endorse or promote products derived from this software without
333 specific prior written permission.
334 
335 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
336 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
337 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
338 PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
339 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
340 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
341 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
342 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
343 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
344 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
345 POSSIBILITY OF SUCH DAMAGE.
346 */