1. /*
  2. * Copyright 2001-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.tools.ant.taskdefs.optional.junit;
  18. import java.io.File;
  19. import java.io.FileInputStream;
  20. import java.io.FileNotFoundException;
  21. import java.io.IOException;
  22. import java.io.InputStream;
  23. import java.net.URL;
  24. import javax.xml.parsers.DocumentBuilder;
  25. import javax.xml.parsers.DocumentBuilderFactory;
  26. import org.apache.tools.ant.BuildException;
  27. import org.apache.tools.ant.Project;
  28. import org.apache.tools.ant.Task;
  29. import org.apache.tools.ant.util.JAXPUtils;
  30. import org.apache.tools.ant.types.EnumeratedAttribute;
  31. import org.w3c.dom.Document;
  32. /**
  33. * Transform a JUnit xml report.
  34. * The default transformation generates an html report in either framed or non-framed
  35. * style. The non-framed style is convenient to have a concise report via mail, the
  36. * framed report is much more convenient if you want to browse into different
  37. * packages or testcases since it is a Javadoc like report.
  38. *
  39. */
  40. public class AggregateTransformer {
  41. public static final String FRAMES = "frames";
  42. public static final String NOFRAMES = "noframes";
  43. public static class Format extends EnumeratedAttribute {
  44. public String[] getValues() {
  45. return new String[]{FRAMES, NOFRAMES};
  46. }
  47. }
  48. /** Task */
  49. protected Task task;
  50. /** the xml document to process */
  51. protected Document document;
  52. /** the style directory. XSLs should be read from here if necessary */
  53. protected File styleDir;
  54. /** the destination directory, this is the root from where html should be generated */
  55. protected File toDir;
  56. /** the format to use for the report. Must be <tt>FRAMES</tt> or <tt>NOFRAMES</tt> */
  57. protected String format = FRAMES;
  58. /** XML Parser factory */
  59. private static DocumentBuilderFactory privateDBFactory;
  60. /** XML Parser factory accessible to subclasses */
  61. protected static DocumentBuilderFactory dbfactory;
  62. static {
  63. privateDBFactory = DocumentBuilderFactory.newInstance();
  64. dbfactory = privateDBFactory;
  65. }
  66. public AggregateTransformer(Task task) {
  67. this.task = task;
  68. }
  69. /**
  70. * Get the Document Builder Factory
  71. *
  72. * @return the DocumentBuilderFactory instance in use
  73. */
  74. protected static DocumentBuilderFactory getDocumentBuilderFactory() {
  75. return privateDBFactory;
  76. }
  77. public void setFormat(Format format) {
  78. this.format = format.getValue();
  79. }
  80. public void setXmlDocument(Document doc) {
  81. this.document = doc;
  82. }
  83. /**
  84. * Set the xml file to be processed. This is a helper if you want
  85. * to set the file directly. Much more for testing purposes.
  86. * @param xmlfile xml file to be processed
  87. */
  88. protected void setXmlfile(File xmlfile) throws BuildException {
  89. try {
  90. DocumentBuilder builder = privateDBFactory.newDocumentBuilder();
  91. InputStream in = new FileInputStream(xmlfile);
  92. try {
  93. Document doc = builder.parse(in);
  94. setXmlDocument(doc);
  95. } finally {
  96. in.close();
  97. }
  98. } catch (Exception e) {
  99. throw new BuildException("Error while parsing document: " + xmlfile, e);
  100. }
  101. }
  102. /**
  103. * set the style directory. It is optional and will override the
  104. * default xsl used.
  105. * @param styledir the directory containing the xsl files if the user
  106. * would like to override with its own style.
  107. */
  108. public void setStyledir(File styledir) {
  109. this.styleDir = styledir;
  110. }
  111. /** set the destination directory */
  112. public void setTodir(File todir) {
  113. this.toDir = todir;
  114. }
  115. /** set the extension of the output files */
  116. public void setExtension(String ext) {
  117. task.log("extension is not used anymore", Project.MSG_WARN);
  118. }
  119. public void transform() throws BuildException {
  120. checkOptions();
  121. final long t0 = System.currentTimeMillis();
  122. XalanExecutor executor = XalanExecutor.newInstance(this);
  123. try {
  124. executor.execute();
  125. } catch (Exception e) {
  126. throw new BuildException("Errors while applying transformations: "
  127. + e.getMessage(), e);
  128. }
  129. final long dt = System.currentTimeMillis() - t0;
  130. task.log("Transform time: " + dt + "ms");
  131. }
  132. /** check for invalid options */
  133. protected void checkOptions() throws BuildException {
  134. // set the destination directory relative from the project if needed.
  135. if (toDir == null) {
  136. toDir = task.getProject().resolveFile(".");
  137. } else if (!toDir.isAbsolute()) {
  138. toDir = task.getProject().resolveFile(toDir.getPath());
  139. }
  140. }
  141. /**
  142. * Get the systemid of the appropriate stylesheet based on its
  143. * name and styledir. If no styledir is defined it will load
  144. * it as a java resource in the xsl child package, otherwise it
  145. * will get it from the given directory.
  146. * @throws IOException thrown if the requested stylesheet does
  147. * not exist.
  148. */
  149. protected String getStylesheetSystemId() throws IOException {
  150. String xslname = "junit-frames.xsl";
  151. if (NOFRAMES.equals(format)) {
  152. xslname = "junit-noframes.xsl";
  153. }
  154. if (styleDir == null) {
  155. URL url = getClass().getResource("xsl/" + xslname);
  156. if (url == null) {
  157. throw new FileNotFoundException("Could not find jar resource " + xslname);
  158. }
  159. return url.toExternalForm();
  160. }
  161. File file = new File(styleDir, xslname);
  162. if (!file.exists()) {
  163. throw new FileNotFoundException("Could not find file '" + file + "'");
  164. }
  165. return JAXPUtils.getSystemId(file);
  166. }
  167. }