source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 12.0 KB
Line 
1/*
2 * Copyright 2000-2005 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/*
18 * build notes
19 * The reference CD to listen to while editing this file is
20 * Underworld Everything, Everything
21 * variable naming policy from Fowler's refactoring book.
22 */
23// place below the optional ant tasks package
24
25package org.apache.tools.ant.taskdefs.optional.dotnet;
26
27// imports
28
29import java.io.File;
30import java.io.IOException;
31import java.io.FileOutputStream;
32import java.io.PrintWriter;
33import java.io.BufferedOutputStream;
34import java.io.FileNotFoundException;
35import java.util.Hashtable;
36
37import org.apache.tools.ant.BuildException;
38import org.apache.tools.ant.Project;
39import org.apache.tools.ant.Task;
40import org.apache.tools.ant.DirectoryScanner;
41import org.apache.tools.ant.util.FileUtils;
42import org.apache.tools.ant.taskdefs.Execute;
43import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
44import org.apache.tools.ant.taskdefs.LogStreamHandler;
45import org.apache.tools.ant.types.Commandline;
46
47/**
48 * This is a helper class to spawn net commands out. In its initial form it
49 * contains no .net specifics, just contains all the command line/exe
50 * construction stuff. However, it may be handy in future to have a means of
51 * setting the path to point to the dotnet bin directory; in which case the
52 * shared code should go in here.
53 *
54 *@version 0.5
55 */
56
57public class NetCommand {
58
59 /**
60 * owner project
61 */
62 protected Task owner;
63
64 /**
65 * executable
66 */
67 protected Execute executable;
68
69 /**
70 * what is the command line
71 */
72 protected Commandline commandLine;
73
74 /**
75 * title of the command
76 */
77 protected String title;
78
79 /**
80 * actual program to invoke
81 */
82 protected String program;
83
84 /**
85 * trace flag
86 */
87 protected boolean traceCommandLine = false;
88
89 /**
90 * flag to control action on execution trouble
91 */
92 protected boolean failOnError;
93
94 /**
95 * the directory to execute the command in. When null, the current
96 * directory is used.
97 */
98 private File directory;
99
100 /**
101 * flag to set to to use @file based command cache
102 */
103 private boolean useResponseFile=false;
104
105 /**
106 * name of a temp file; may be null
107 */
108 private File temporaryCommandFile;
109
110 /**
111 * internal threshold for auto-switch
112 */
113 private int automaticResponseFileThreshold = 64;
114
115 /**
116 * constructor
117 *
118 *@param title (for logging/errors)
119 *@param owner owner task
120 *@param program app we are to run
121 */
122
123 public NetCommand(Task owner, String title, String program) {
124 this.owner = owner;
125 this.title = title;
126 this.program = program;
127 commandLine = new Commandline();
128 commandLine.setExecutable(program);
129 prepareExecutor();
130 }
131
132
133 /**
134 * turn tracing on or off
135 *
136 *@param b trace flag
137 */
138 public void setTraceCommandLine(boolean b) {
139 traceCommandLine = b;
140 }
141
142
143 /**
144 * set fail on error flag
145 *
146 *@param b fail flag -set to true to cause an exception to be raised if
147 * the return value != 0
148 */
149 public void setFailOnError(boolean b) {
150 failOnError = b;
151 }
152
153
154 /**
155 * query fail on error flag
156 *
157 *@return The failFailOnError value
158 */
159 public boolean getFailFailOnError() {
160 return failOnError;
161 }
162
163
164 /**
165 * set the directory to run from, if the default is inadequate
166 * @param directory
167 */
168 public void setDirectory(File directory) {
169 this.directory = directory;
170 }
171
172 /**
173 * verbose text log
174 *
175 *@param msg string to add to log if verbose is defined for the build
176 */
177 protected void logVerbose(String msg) {
178 owner.getProject().log(msg, Project.MSG_VERBOSE);
179 }
180
181
182 /**
183 * error text log
184 *
185 *@param msg message to display as an error
186 */
187 protected void logError(String msg) {
188 owner.getProject().log(msg, Project.MSG_ERR);
189 }
190
191
192 /**
193 * add an argument to a command line; do nothing if the arg is null or
194 * empty string
195 *
196 *@param argument The feature to be added to the Argument attribute
197 */
198 public void addArgument(String argument) {
199 if (argument != null && argument.length() != 0) {
200 commandLine.createArgument().setValue(argument);
201 }
202 }
203
204 /**
205 * add an argument to a command line; do nothing if the arg is null or
206 * empty string
207 *
208 *@param argument The feature to be added to the Argument attribute
209 */
210 public void addArguments(String[] arguments) {
211 if (arguments != null && arguments.length != 0) {
212 for (int i = 0; i < arguments.length; i++) {
213 addArgument(arguments[i]);
214 }
215 }
216 }
217
218 /**
219 * concatenate two strings together and add them as a single argument,
220 * but only if argument2 is non-null and non-zero length
221 *
222 *@param argument1 The first argument
223 *@param argument2 The second argument
224 */ public void addArgument(String argument1, String argument2) {
225 if (argument2 != null && argument2.length() != 0) {
226 commandLine.createArgument().setValue(argument1 + argument2);
227 }
228 }
229
230 /**
231 * getter
232 * @return response file state
233 */
234 public boolean isUseResponseFile() {
235 return useResponseFile;
236 }
237
238 /**
239 * set this to true to always use the response file
240 * @param useResponseFile
241 */
242 public void setUseResponseFile(boolean useResponseFile) {
243 this.useResponseFile = useResponseFile;
244 }
245
246 /**
247 * getter for threshold
248 * @return 0 for disabled, or a threshold for enabling response files
249 */
250 public int getAutomaticResponseFileThreshold() {
251 return automaticResponseFileThreshold;
252 }
253
254 /**
255 * set threshold for automatically using response files -use 0 for off
256 * @param automaticResponseFileThreshold
257 */
258 public void setAutomaticResponseFileThreshold(int automaticResponseFileThreshold) {
259 this.automaticResponseFileThreshold = automaticResponseFileThreshold;
260 }
261
262 /**
263 * set up the command sequence..
264 */
265 protected void prepareExecutor() {
266 // default directory to the project's base directory
267 if (owner == null) {
268 throw new RuntimeException("no owner");
269 }
270 if (owner.getProject() == null) {
271 throw new RuntimeException("Owner has no project");
272 }
273 File dir = owner.getProject().getBaseDir();
274 if (directory != null) {
275 dir = directory;
276 }
277
278 ExecuteStreamHandler handler = new LogStreamHandler(owner,
279 Project.MSG_INFO, Project.MSG_WARN);
280 executable = new Execute(handler, null);
281 executable.setAntRun(owner.getProject());
282 executable.setWorkingDirectory(dir);
283 }
284
285
286 /**
287 * Run the command using the given Execute instance.
288 *
289 *@exception BuildException if something goes wrong and the
290 * failOnError flag is true
291 */
292 public void runCommand()
293 throws BuildException {
294 int err = -1;
295 // assume the worst
296 try {
297 if (traceCommandLine) {
298 owner.log(commandLine.describeCommand());
299 } else {
300 //in verbose mode we always log stuff
301 logVerbose(commandLine.describeCommand());
302 }
303 setExecutableCommandLine();
304 err = executable.execute();
305 if (Execute.isFailure(err)) {
306 if (failOnError) {
307 throw new BuildException(title + " returned: " + err, owner.getLocation());
308 } else {
309 owner.log(title + " Result: " + err, Project.MSG_ERR);
310 }
311 }
312 } catch (IOException e) {
313 throw new BuildException(title + " failed: " + e, e, owner.getLocation());
314 } finally {
315 if (temporaryCommandFile != null) {
316 temporaryCommandFile.delete();
317 }
318 }
319 }
320
321 /**
322 * set the executable command line
323 */
324 private void setExecutableCommandLine() {
325
326 String[] commands = commandLine.getCommandline();
327 //always trigger file mode if commands are big enough
328 if (automaticResponseFileThreshold>0 &&
329 commands.length > automaticResponseFileThreshold) {
330 useResponseFile = true;
331 }
332 if (!useResponseFile || commands.length <= 1) {
333 //the simple action is to send the command line in as is
334 executable.setCommandline(commands);
335 } else {
336 //but for big operations, we save all the params to a temp file
337 //and set @tmpfile as the command -then we remember to delete the tempfile
338 //afterwards
339 FileOutputStream fos = null;
340 FileUtils fileUtils = FileUtils.newFileUtils();
341
342 temporaryCommandFile = fileUtils.createTempFile("cmd", ".txt", null);
343 owner.log("Using response file"+temporaryCommandFile,Project.MSG_VERBOSE);
344
345 try {
346 fos = new FileOutputStream(temporaryCommandFile);
347 PrintWriter out = new PrintWriter(new BufferedOutputStream(fos));
348 //start at 1 because element 0 is the executable name
349 for (int i = 1; i < commands.length; ++i) {
350 out.println(commands[i]);
351 }
352 out.flush();
353 out.close();
354 } catch (IOException ex) {
355 throw new BuildException("saving command stream to " + temporaryCommandFile, ex);
356 }
357
358 String newCommandLine[] = new String[2];
359 newCommandLine[0] = commands[0];
360 newCommandLine[1] = "@" + temporaryCommandFile.getAbsolutePath();
361 executable.setCommandline(newCommandLine);
362 }
363 }
364
365
366 /**
367 * scan through one fileset for files to include
368 * @param scanner
369 * @param filesToBuild
370 * @param outputTimestamp timestamp to compare against
371 * @return #of files out of date
372 * @todo: should FAT granularity be included here?
373 */
374 public int scanOneFileset(DirectoryScanner scanner, Hashtable filesToBuild,
375 long outputTimestamp) {
376 int filesOutOfDate = 0;
377 String[] dependencies = scanner.getIncludedFiles();
378 File base = scanner.getBasedir();
379 //add to the list
380 for (int i = 0; i < dependencies.length; i++) {
381 File targetFile = new File(base, dependencies[i]);
382 if (filesToBuild.get(targetFile) == null) {
383 filesToBuild.put(targetFile, targetFile);
384 if (targetFile.lastModified() > outputTimestamp) {
385 filesOutOfDate++;
386 owner.log(targetFile.toString() + " is out of date",
387 Project.MSG_VERBOSE);
388 } else {
389 owner.log(targetFile.toString(),
390 Project.MSG_VERBOSE);
391 }
392 }
393 }
394 return filesOutOfDate;
395 }
396}
397
Note: See TracBrowser for help on using the repository browser.