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