1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 package org.codehaus.groovy.ant;
48
49 import groovy.lang.GroovyShell;
50 import groovy.lang.Script;
51 import groovy.util.AntBuilder;
52
53 import java.io.BufferedOutputStream;
54 import java.io.BufferedReader;
55 import java.io.File;
56 import java.io.FileOutputStream;
57 import java.io.FileReader;
58 import java.io.IOException;
59 import java.io.PrintStream;
60 import java.io.Reader;
61 import java.lang.reflect.Field;
62 import java.util.Hashtable;
63 import java.util.Vector;
64
65 import org.apache.tools.ant.BuildException;
66 import org.apache.tools.ant.DirectoryScanner;
67 import org.apache.tools.ant.Project;
68 import org.apache.tools.ant.Task;
69 import org.apache.tools.ant.types.FileSet;
70 import org.apache.tools.ant.types.Path;
71 import org.apache.tools.ant.types.Reference;
72 import org.codehaus.groovy.control.CompilationFailedException;
73 import org.codehaus.groovy.runtime.InvokerHelper;
74
75 /***
76 * Executes a series of Groovy statements.
77 *
78 * <p>Statements can
79 * either be read in from a text file using the <i>src</i> attribute or from
80 * between the enclosing groovy tags.</p>
81 *
82 *
83 * Based heavily on SQLExec.java which is part of apache-ant
84 * http://cvs.apache.org/viewcvs.cgi/ant/src/main/org/apache/tools/ant/taskdefs/SQLExec.java?rev=MAIN
85 *
86 * Copyright 2000-2005 The Apache Software Foundation
87 *
88 * Licensed under the Apache License, Version 2.0 (the "License");
89 * you may not use this file except in compliance with the License.
90 * You may obtain a copy of the License at
91 *
92 * http://www.apache.org/licenses/LICENSE-2.0
93 *
94 * Unless required by applicable law or agreed to in writing, software
95 * distributed under the License is distributed on an "AS IS" BASIS,
96 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
97 * See the License for the specific language governing permissions and
98 * limitations under the License.
99 *
100 *
101 */
102 public class Groovy extends Task {
103 /***
104 * files to load
105 */
106 private Vector filesets = new Vector();
107
108 /***
109 * input file
110 */
111 private File srcFile = null;
112
113 /***
114 * input command
115 */
116 private String command = "";
117
118 /***
119 * Print results.
120 */
121 private boolean print = false;
122
123 /***
124 * Results Output file.
125 */
126 private File output = null;
127
128 /***
129 * Append to an existing file or overwrite it?
130 */
131 private boolean append = false;
132
133 /***
134 * Used for caching loaders / driver. This is to avoid
135 * getting an OutOfMemoryError when calling this task
136 * multiple times in a row.
137 */
138 private static Hashtable loaderMap = new Hashtable(3);
139
140 private Path classpath;
141
142 /***
143 * User name.
144 */
145 private String userId = null;
146
147 /***
148 * Groovy Version needed for this collection of statements.
149 **/
150 private String version = null;
151
152
153 /***
154 * Set the name of the file to be run.
155 * Required unless statements are enclosed in the build file
156 */
157 public void setSrc(File srcFile) {
158 this.srcFile = srcFile;
159 }
160
161 /***
162 * Set an inline command to execute.
163 * NB: Properties are not expanded in this text.
164 */
165 public void addText(String txt) {
166 log("addText('"+txt+"')", Project.MSG_VERBOSE);
167 this.command += txt;
168 }
169
170 /***
171 * Adds a set of files (nested fileset attribute).
172 */
173 public void addFileset(FileSet set) {
174 filesets.addElement(set);
175 }
176
177 /***
178 * Print results from the statements;
179 * optional, default false
180 */
181 public void setPrint(boolean print) {
182 this.print = print;
183 }
184
185 /***
186 * Set the output file;
187 * optional, defaults to the Ant log.
188 */
189 public void setOutput(File output) {
190 this.output = output;
191 }
192
193 /***
194 * whether output should be appended to or overwrite
195 * an existing file. Defaults to false.
196 *
197 * @since Ant 1.5
198 */
199 public void setAppend(boolean append) {
200 this.append = append;
201 }
202
203
204 /***
205 * Sets the classpath for loading.
206 * @param classpath The classpath to set
207 */
208 public void setClasspath(Path classpath) {
209 this.classpath = classpath;
210 }
211
212 /***
213 * Add a path to the classpath for loading.
214 */
215 public Path createClasspath() {
216 if (this.classpath == null) {
217 this.classpath = new Path(getProject());
218 }
219 return this.classpath.createPath();
220 }
221
222 /***
223 * Set the classpath for loading
224 * using the classpath reference.
225 */
226 public void setClasspathRef(Reference r) {
227 createClasspath().setRefid(r);
228 }
229
230 /***
231 * Sets the version string, execute task only if
232 * groovy version match; optional.
233 * @param version The version to set
234 */
235 public void setVersion(String version) {
236 this.version = version;
237 }
238
239
240 protected static Hashtable getLoaderMap() {
241 return loaderMap;
242 }
243
244
245
246
247 /***
248 * Gets the classpath.
249 * @return Returns a Path
250 */
251 public Path getClasspath() {
252 return classpath;
253 }
254
255 /***
256 * Gets the userId.
257 * @return Returns a String
258 */
259 public String getUserId() {
260 return userId;
261 }
262
263 /***
264 * Set the user name for the connection; required.
265 * @param userId The userId to set
266 */
267 public void setUserid(String userId) {
268 this.userId = userId;
269 }
270
271 /***
272 * Gets the version.
273 * @return Returns a String
274 */
275 public String getVersion() {
276 return version;
277 }
278
279 /***
280 * Load the file and then execute it
281 */
282 public void execute() throws BuildException {
283 log("execute()", Project.MSG_VERBOSE);
284
285 command = command.trim();
286
287 try {
288 if (srcFile == null && command.length() == 0
289 && filesets.isEmpty()) {
290 throw new BuildException("Source file does not exist!", getLocation());
291 }
292
293 if (srcFile != null && !srcFile.exists()) {
294 throw new BuildException("Source file does not exist!", getLocation());
295 }
296
297
298 for (int i = 0; i < filesets.size(); i++) {
299 FileSet fs = (FileSet) filesets.elementAt(i);
300 DirectoryScanner ds = fs.getDirectoryScanner(getProject());
301 File srcDir = fs.getDir(getProject());
302
303 String[] srcFiles = ds.getIncludedFiles();
304 }
305
306 try {
307 PrintStream out = System.out;
308 try {
309 if (output != null) {
310 log("Opening PrintStream to output file " + output,
311 Project.MSG_VERBOSE);
312 out = new PrintStream(
313 new BufferedOutputStream(
314 new FileOutputStream(output
315 .getAbsolutePath(),
316 append)));
317 }
318
319
320
321 if (command == null || command.trim().length() == 0) {
322 command = getText(new BufferedReader(new FileReader(srcFile)));
323 }
324
325
326 if (command != null) {
327 execGroovy(command,out);
328 } else {
329 throw new BuildException("Source file does not exist!", getLocation());
330 }
331
332 } finally {
333 if (out != null && out != System.out) {
334 out.close();
335 }
336 }
337 } catch (IOException e) {
338 throw new BuildException(e, getLocation());
339 }
340
341 log("statements executed successfully");
342 } finally{}
343 }
344
345
346 private static String getText(BufferedReader reader) throws IOException {
347 StringBuffer answer = new StringBuffer();
348
349 char[] charBuffer = new char[4096];
350 int nbCharRead = 0;
351 while ((nbCharRead = reader.read(charBuffer)) != -1) {
352
353 answer.append(charBuffer, 0, nbCharRead);
354 }
355 reader.close();
356 return answer.toString();
357 }
358
359
360 /***
361 * read in lines and execute them
362 */
363 protected void runStatements(Reader reader, PrintStream out)
364 throws IOException {
365 log("runStatements()", Project.MSG_VERBOSE);
366
367 StringBuffer txt = new StringBuffer();
368 String line = "";
369
370 BufferedReader in = new BufferedReader(reader);
371
372 while ((line = in.readLine()) != null) {
373 line = getProject().replaceProperties(line);
374
375 if (line.indexOf("--") >= 0) {
376 txt.append("\n");
377 }
378 }
379
380 if (!txt.equals("")) {
381 execGroovy(txt.toString(), out);
382 }
383 }
384
385
386 /***
387 * Exec the statement.
388 */
389 protected void execGroovy(String txt, PrintStream out) {
390 log("execGroovy()", Project.MSG_VERBOSE);
391
392
393 if ("".equals(txt.trim())) {
394 return;
395 }
396
397 log("Groovy: " + txt, Project.MSG_VERBOSE);
398
399
400 GroovyShell groovy = new GroovyShell(GroovyShell.class.getClassLoader());
401
402 try {
403 Script script = groovy.parse(txt);
404 Project project = getProject();
405 script.setProperty("ant", new AntBuilder(project));
406 script.setProperty("project", project);
407 script.setProperty("properties", new AntProjectPropertiesDelegate(project));
408 script.setProperty("target", getOwningTarget());
409 script.setProperty("task", this);
410
411
412 if ("org.apache.commons.grant.GrantProject".equals(project.getClass().getName())) {
413 try {
414 Object propsHandler = project.getClass().getMethod("getPropsHandler", new Class[0]).invoke(project, new Object[0]);
415 Field contextField = propsHandler.getClass().getDeclaredField("context");
416 contextField.setAccessible(true);
417 Object context = contextField.get(propsHandler);
418 Object mavenPom = InvokerHelper.invokeMethod(context, "getProject", new Object[0]);
419 script.setProperty("pom", mavenPom);
420 } catch (Exception e) {
421 throw new BuildException("Impossible to retrieve Maven's Ant project: " + e.getMessage(), getLocation());
422 }
423 }
424
425 script.run();
426 } catch (CompilationFailedException e) {
427 throw new BuildException("Script Failed: "+ e.getMessage(), getLocation());
428 }
429
430 if (print) {
431 StringBuffer line = new StringBuffer();
432 line.append( " foo bar");
433 out.println(line);
434 }
435
436
437 }
438
439 /***
440 * print any results in the statement.
441 */
442 protected void printResults(PrintStream out) {
443 log("printResults()", Project.MSG_VERBOSE);
444 StringBuffer line = new StringBuffer();
445 out.println(line);
446 line = new StringBuffer();
447 out.println();
448 }
449 }