001: /**
002: * @author Jeremy Rayner
003: */package org.codehaus.groovy.tck;
004:
005: import java.io.*;
006: import java.nio.charset.Charset;
007:
008: import org.apache.tools.ant.*;
009: import org.apache.tools.ant.taskdefs.MatchingTask;
010: import org.apache.tools.ant.types.*;
011: import org.apache.tools.ant.util.*;
012:
013: /**
014: * Generates test files. This task can take the following
015: * arguments:
016: * <ul>
017: * <li>sourcedir
018: * <li>destdir
019: * </ul>
020: * Both are required.
021: * <p>
022: * When this task executes, it will recursively scan the sourcedir
023: * looking for source files to expand into testcases. This task makes its
024: * generation decision based on timestamp.
025: *
026: * Based heavily on the Javac implementation in Ant
027: *
028: * @author <a href="mailto:jeremy.rayner@bigfoot.com">Jeremy Rayner</a>
029: * @version $Revision: 2599 $
030: */
031: public class GenerateTestCases extends MatchingTask {
032:
033: private BatchGenerate batchGenerate = new BatchGenerate();
034: private Path src;
035: private File destDir;
036: private Path compileClasspath;
037: private Path compileSourcepath;
038: private String encoding;
039:
040: protected boolean failOnError = true;
041: protected boolean listFiles = false;
042: protected File[] compileList = new File[0];
043:
044: public GenerateTestCases() {
045: }
046:
047: /**
048: * Adds a path for source compilation.
049: *
050: * @return a nested src element.
051: */
052: public Path createSrc() {
053: if (src == null) {
054: src = new Path(getProject());
055: }
056: return src.createPath();
057: }
058:
059: /**
060: * Recreate src.
061: *
062: * @return a nested src element.
063: */
064: protected Path recreateSrc() {
065: src = null;
066: return createSrc();
067: }
068:
069: /**
070: * Set the source directories to find the source Java files.
071: * @param srcDir the source directories as a path
072: */
073: public void setSrcdir(Path srcDir) {
074: if (src == null) {
075: src = srcDir;
076: } else {
077: src.append(srcDir);
078: }
079: batchGenerate.setSrcdirPath(src.toString());
080: }
081:
082: /**
083: * Gets the source dirs to find the source java files.
084: * @return the source directorys as a path
085: */
086: public Path getSrcdir() {
087: return src;
088: }
089:
090: /**
091: * Set the destination directory into which the Java source
092: * files should be compiled.
093: * @param destDir the destination director
094: */
095: public void setDestdir(File destDir) {
096: this .destDir = destDir;
097: }
098:
099: /**
100: * Enable verbose compiling which will display which files
101: * are being compiled
102: * @param verbose
103: */
104: public void setVerbose(boolean verbose) {
105: batchGenerate.setVerbose(verbose);
106: }
107:
108: /**
109: * Gets the destination directory into which the java source files
110: * should be compiled.
111: * @return the destination directory
112: */
113: public File getDestdir() {
114: return destDir;
115: }
116:
117: /**
118: * Set the sourcepath to be used for this compilation.
119: * @param sourcepath the source path
120: */
121: public void setSourcepath(Path sourcepath) {
122: if (compileSourcepath == null) {
123: compileSourcepath = sourcepath;
124: } else {
125: compileSourcepath.append(sourcepath);
126: }
127: }
128:
129: /**
130: * Gets the sourcepath to be used for this compilation.
131: * @return the source path
132: */
133: public Path getSourcepath() {
134: return compileSourcepath;
135: }
136:
137: /**
138: * Adds a path to sourcepath.
139: * @return a sourcepath to be configured
140: */
141: public Path createSourcepath() {
142: if (compileSourcepath == null) {
143: compileSourcepath = new Path(getProject());
144: }
145: return compileSourcepath.createPath();
146: }
147:
148: /**
149: * Adds a reference to a source path defined elsewhere.
150: * @param r a reference to a source path
151: */
152: public void setSourcepathRef(Reference r) {
153: createSourcepath().setRefid(r);
154: }
155:
156: /**
157: * Set the classpath to be used for this compilation.
158: *
159: * @param classpath an Ant Path object containing the compilation classpath.
160: */
161: public void setClasspath(Path classpath) {
162: if (compileClasspath == null) {
163: compileClasspath = classpath;
164: } else {
165: compileClasspath.append(classpath);
166: }
167: }
168:
169: /**
170: * Gets the classpath to be used for this compilation.
171: * @return the class path
172: */
173: public Path getClasspath() {
174: return compileClasspath;
175: }
176:
177: /**
178: * Adds a path to the classpath.
179: * @return a class path to be configured
180: */
181: public Path createClasspath() {
182: if (compileClasspath == null) {
183: compileClasspath = new Path(getProject());
184: }
185: return compileClasspath.createPath();
186: }
187:
188: /**
189: * Adds a reference to a classpath defined elsewhere.
190: * @param r a reference to a classpath
191: */
192: public void setClasspathRef(Reference r) {
193: createClasspath().setRefid(r);
194: }
195:
196: public String createEncoding() {
197: if (encoding == null) {
198: encoding = System.getProperty("file.encoding");
199: }
200: return encoding;
201: }
202:
203: public void setEncoding(String encoding) {
204: this .encoding = encoding;
205: }
206:
207: public String getEncoding() {
208: return encoding;
209: }
210:
211: /**
212: * If true, list the source files being handed off to the compiler.
213: * @param list if true list the source files
214: */
215: public void setListfiles(boolean list) {
216: listFiles = list;
217: }
218:
219: /**
220: * Get the listfiles flag.
221: * @return the listfiles flag
222: */
223: public boolean getListfiles() {
224: return listFiles;
225: }
226:
227: /**
228: * Indicates whether the build will continue
229: * even if there are compilation errors; defaults to true.
230: * @param fail if true halt the build on failure
231: */
232: public void setFailonerror(boolean fail) {
233: failOnError = fail;
234: }
235:
236: /**
237: * @param proceed inverse of failoferror
238: */
239: public void setProceed(boolean proceed) {
240: failOnError = !proceed;
241: }
242:
243: /**
244: * Gets the failonerror flag.
245: * @return the failonerror flag
246: */
247: public boolean getFailonerror() {
248: return failOnError;
249: }
250:
251: /**
252: * Executes the task.
253: * @exception BuildException if an error occurs
254: */
255: public void execute() throws BuildException {
256: checkParameters();
257: resetFileLists();
258:
259: // scan source directories and dest directory to build up
260: // compile lists
261: String[] list = src.list();
262: for (int i = 0; i < list.length; i++) {
263: File srcDir = getProject().resolveFile(list[i]);
264: if (!srcDir.exists()) {
265: throw new BuildException("srcdir \"" + srcDir.getPath()
266: + "\" does not exist!", getLocation());
267: }
268:
269: DirectoryScanner ds = this .getDirectoryScanner(srcDir);
270: String[] files = ds.getIncludedFiles();
271:
272: scanDir(srcDir, destDir != null ? destDir : srcDir, files);
273: }
274:
275: compile();
276: }
277:
278: /**
279: * Clear the list of files to be compiled and copied..
280: */
281: protected void resetFileLists() {
282: compileList = new File[0];
283: }
284:
285: /**
286: * Scans the directory looking for source files to be compiled.
287: * The results are returned in the class variable compileList
288: *
289: * @param srcDir The source directory
290: * @param destDir The destination directory
291: * @param files An array of filenames
292: */
293: protected void scanDir(File srcDir, File destDir, String[] files) {
294: GlobPatternMapper m = new GlobPatternMapper();
295: m.setFrom("*");
296: m.setTo("*.html");
297: SourceFileScanner sfs = new SourceFileScanner(this );
298: File[] newFiles = sfs
299: .restrictAsFiles(files, srcDir, destDir, m);
300:
301: if (newFiles.length > 0) {
302: File[] newCompileList = new File[compileList.length
303: + newFiles.length];
304: System.arraycopy(compileList, 0, newCompileList, 0,
305: compileList.length);
306: System.arraycopy(newFiles, 0, newCompileList,
307: compileList.length, newFiles.length);
308: compileList = newCompileList;
309: }
310: }
311:
312: /**
313: * Gets the list of files to be compiled.
314: * @return the list of files as an array
315: */
316: public File[] getFileList() {
317: return compileList;
318: }
319:
320: protected void checkParameters() throws BuildException {
321: if (src == null) {
322: throw new BuildException("srcdir attribute must be set!",
323: getLocation());
324: }
325: if (src.size() == 0) {
326: throw new BuildException("srcdir attribute must be set!",
327: getLocation());
328: }
329:
330: if (destDir != null && !destDir.isDirectory()) {
331: throw new BuildException("destination directory \""
332: + destDir + "\" does not exist "
333: + "or is not a directory", getLocation());
334: }
335:
336: if (encoding != null && !Charset.isSupported(encoding)) {
337: throw new BuildException("encoding \"\" not supported");
338: }
339: }
340:
341: protected void compile() {
342: if (compileList.length > 0) {
343: log("Generating Tests " + compileList.length
344: + " source file"
345: + (compileList.length == 1 ? "" : "s")
346: + (destDir != null ? " to " + destDir : ""));
347:
348: if (listFiles) {
349: for (int i = 0; i < compileList.length; i++) {
350: String filename = compileList[i].getAbsolutePath();
351: log(filename);
352: }
353: }
354:
355: try {
356: Path classpath = getClasspath();
357: if (classpath != null) {
358: //@todo - is this useful?
359: //batchOfBiscuits.setClasspath(classpath.toString());
360: }
361: batchGenerate.setTargetDirectory(destDir);
362:
363: if (encoding != null) {
364: batchGenerate.setSourceEncoding(encoding);
365: }
366:
367: batchGenerate.addSources(compileList);
368: batchGenerate.compile();
369: } catch (Exception e) {
370:
371: StringWriter writer = new StringWriter();
372: //@todo --
373: e.printStackTrace();
374: //new ErrorReporter( e, false ).write( new PrintWriter(writer) );
375: String message = writer.toString();
376:
377: if (failOnError) {
378: throw new BuildException(message, e, getLocation());
379: } else {
380: log(message, Project.MSG_ERR);
381: }
382:
383: }
384: }
385: }
386: }
|