1. /*
  2. * Copyright 2001-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.FileOutputStream;
  20. import java.io.OutputStream;
  21. import org.apache.tools.ant.BuildException;
  22. import org.apache.tools.ant.Task;
  23. import org.apache.tools.ant.types.EnumeratedAttribute;
  24. /**
  25. * <p> A wrapper for the implementations of <code>JUnitResultFormatter</code>.
  26. * In particular, used as a nested <code><formatter></code> element in
  27. * a <code><junit></code> task.
  28. * <p> For example,
  29. * <code><pre>
  30. * <junit printsummary="no" haltonfailure="yes" fork="false">
  31. * <formatter type="plain" usefile="false" />
  32. * <test name="org.apache.ecs.InternationalCharTest" />
  33. * </junit></pre></code>
  34. * adds a <code>plain</code> type implementation
  35. * (<code>PlainJUnitResultFormatter</code>) to display the results of the test.
  36. *
  37. * <p> Either the <code>type</code> or the <code>classname</code> attribute
  38. * must be set.
  39. *
  40. * @see JUnitTask
  41. * @see XMLJUnitResultFormatter
  42. * @see BriefJUnitResultFormatter
  43. * @see PlainJUnitResultFormatter
  44. * @see JUnitResultFormatter
  45. */
  46. public class FormatterElement {
  47. private String classname;
  48. private String extension;
  49. private OutputStream out = System.out;
  50. private File outFile;
  51. private boolean useFile = true;
  52. private String ifProperty;
  53. private String unlessProperty;
  54. public static final String XML_FORMATTER_CLASS_NAME =
  55. "org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter";
  56. public static final String BRIEF_FORMATTER_CLASS_NAME =
  57. "org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter";
  58. public static final String PLAIN_FORMATTER_CLASS_NAME =
  59. "org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter";
  60. /**
  61. * <p> Quick way to use a standard formatter.
  62. *
  63. * <p> At the moment, there are three supported standard formatters.
  64. * <ul>
  65. * <li> The <code>xml</code> type uses a <code>XMLJUnitResultFormatter</code>.
  66. * <li> The <code>brief</code> type uses a <code>BriefJUnitResultFormatter</code>.
  67. * <li> The <code>plain</code> type (the default) uses a <code>PlainJUnitResultFormatter</code>.
  68. * </ul>
  69. *
  70. * <p> Sets <code>classname</code> attribute - so you can't use that
  71. * attribute if you use this one.
  72. */
  73. public void setType(TypeAttribute type) {
  74. if ("xml".equals(type.getValue())) {
  75. setClassname(XML_FORMATTER_CLASS_NAME);
  76. } else {
  77. if ("brief".equals(type.getValue())) {
  78. setClassname(BRIEF_FORMATTER_CLASS_NAME);
  79. } else { // must be plain, ensured by TypeAttribute
  80. setClassname(PLAIN_FORMATTER_CLASS_NAME);
  81. }
  82. }
  83. }
  84. /**
  85. * <p> Set name of class to be used as the formatter.
  86. *
  87. * <p> This class must implement <code>JUnitResultFormatter</code>
  88. */
  89. public void setClassname(String classname) {
  90. this.classname = classname;
  91. if (XML_FORMATTER_CLASS_NAME.equals(classname)) {
  92. setExtension(".xml");
  93. } else if (PLAIN_FORMATTER_CLASS_NAME.equals(classname)) {
  94. setExtension(".txt");
  95. } else if (BRIEF_FORMATTER_CLASS_NAME.equals(classname)) {
  96. setExtension(".txt");
  97. }
  98. }
  99. /**
  100. * Get name of class to be used as the formatter.
  101. */
  102. public String getClassname() {
  103. return classname;
  104. }
  105. public void setExtension(String ext) {
  106. this.extension = ext;
  107. }
  108. public String getExtension() {
  109. return extension;
  110. }
  111. /**
  112. * <p> Set the file which the formatte should log to.
  113. *
  114. * <p> Note that logging to file must be enabled .
  115. */
  116. void setOutfile(File out) {
  117. this.outFile = out;
  118. }
  119. /**
  120. * <p> Set output stream for formatter to use.
  121. *
  122. * <p> Defaults to standard out.
  123. */
  124. public void setOutput(OutputStream out) {
  125. this.out = out;
  126. }
  127. /**
  128. * Set whether the formatter should log to file.
  129. */
  130. public void setUseFile(boolean useFile) {
  131. this.useFile = useFile;
  132. }
  133. /**
  134. * Get whether the formatter should log to file.
  135. */
  136. boolean getUseFile() {
  137. return useFile;
  138. }
  139. /**
  140. * Set whether this formatter should be used. It will be
  141. * used if the property has been set, otherwise it won't.
  142. * @param ifProperty name of property
  143. */
  144. public void setIf(String ifProperty) {
  145. this.ifProperty = ifProperty;
  146. }
  147. /**
  148. * Set whether this formatter should NOT be used. It
  149. * will not be used if the property has been set, orthwise it
  150. * will be used.
  151. * @param unlessProperty name of property
  152. */
  153. public void setUnless(String unlessProperty) {
  154. this.unlessProperty = unlessProperty;
  155. }
  156. /**
  157. * Ensures that the selector passes the conditions placed
  158. * on it with <code>if</code> and <code>unless</code> properties.
  159. */
  160. public boolean shouldUse(Task t) {
  161. if (ifProperty != null && t.getProject().getProperty(ifProperty) == null) {
  162. return false;
  163. } else if (unlessProperty != null
  164. && t.getProject().getProperty(unlessProperty) != null) {
  165. return false;
  166. }
  167. return true;
  168. }
  169. /**
  170. * @since Ant 1.2
  171. */
  172. JUnitResultFormatter createFormatter() throws BuildException {
  173. return createFormatter(null);
  174. }
  175. /**
  176. * @since Ant 1.6
  177. */
  178. JUnitResultFormatter createFormatter(ClassLoader loader)
  179. throws BuildException {
  180. if (classname == null) {
  181. throw new BuildException("you must specify type or classname");
  182. }
  183. Class f = null;
  184. try {
  185. if (loader == null) {
  186. f = Class.forName(classname);
  187. } else {
  188. f = Class.forName(classname, true, loader);
  189. }
  190. } catch (ClassNotFoundException e) {
  191. throw new BuildException(e);
  192. }
  193. Object o = null;
  194. try {
  195. o = f.newInstance();
  196. } catch (InstantiationException e) {
  197. throw new BuildException(e);
  198. } catch (IllegalAccessException e) {
  199. throw new BuildException(e);
  200. }
  201. if (!(o instanceof JUnitResultFormatter)) {
  202. throw new BuildException(classname
  203. + " is not a JUnitResultFormatter");
  204. }
  205. JUnitResultFormatter r = (JUnitResultFormatter) o;
  206. if (useFile && outFile != null) {
  207. try {
  208. out = new FileOutputStream(outFile);
  209. } catch (java.io.IOException e) {
  210. throw new BuildException(e);
  211. }
  212. }
  213. r.setOutput(out);
  214. return r;
  215. }
  216. /**
  217. * <p> Enumerated attribute with the values "plain", "xml" and "brief".
  218. *
  219. * <p> Use to enumerate options for <code>type</code> attribute.
  220. */
  221. public static class TypeAttribute extends EnumeratedAttribute {
  222. public String[] getValues() {
  223. return new String[] {"plain", "xml", "brief"};
  224. }
  225. }
  226. }