Source Code Cross Referenced for SubAnt.java in  » Build » ANT » org » apache » tools » ant » taskdefs » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Build » ANT » org.apache.tools.ant.taskdefs 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         *
017:         */
018:        package org.apache.tools.ant.taskdefs;
019:
020:        import java.io.File;
021:        import java.io.IOException;
022:
023:        import java.util.Vector;
024:        import java.util.Enumeration;
025:
026:        import org.apache.tools.ant.Task;
027:        import org.apache.tools.ant.Project;
028:        import org.apache.tools.ant.BuildException;
029:
030:        import org.apache.tools.ant.types.Path;
031:        import org.apache.tools.ant.types.DirSet;
032:        import org.apache.tools.ant.types.FileSet;
033:        import org.apache.tools.ant.types.FileList;
034:        import org.apache.tools.ant.types.PropertySet;
035:        import org.apache.tools.ant.types.Reference;
036:        import org.apache.tools.ant.types.ResourceCollection;
037:
038:        import org.apache.tools.ant.taskdefs.Ant.TargetElement;
039:
040:        /**
041:         * Calls a given target for all defined sub-builds. This is an extension
042:         * of ant for bulk project execution.
043:         * <p>
044:         * <h2> Use with directories </h2>
045:         * <p>
046:         * subant can be used with directory sets to execute a build from different directories.
047:         * 2 different options are offered
048:         * </p>
049:         * <ul>
050:         * <li>
051:         * run the same build file /somepath/otherpath/mybuild.xml
052:         * with different base directories use the genericantfile attribute
053:         * </li>
054:         * <li>if you want to run directory1/build.xml, directory2/build.xml, ....
055:         * use the antfile attribute. The base directory does not get set by the subant task in this case,
056:         * because you can specify it in each build file.
057:         * </li>
058:         * </ul>
059:         * @since Ant1.6
060:         * @ant.task name="subant" category="control"
061:         */
062:        public class SubAnt extends Task {
063:
064:            private Path buildpath;
065:
066:            private Ant ant = null;
067:            private String subTarget = null;
068:            private String antfile = "build.xml";
069:            private File genericantfile = null;
070:            private boolean verbose = false;
071:            private boolean inheritAll = false;
072:            private boolean inheritRefs = false;
073:            private boolean failOnError = true;
074:            private String output = null;
075:
076:            private Vector properties = new Vector();
077:            private Vector references = new Vector();
078:            private Vector propertySets = new Vector();
079:
080:            /** the targets to call on the new project */
081:            private Vector/*<TargetElement>*/targets = new Vector();
082:
083:            /**
084:             * Pass output sent to System.out to the new project.
085:             *
086:             * @param output a line of output
087:             * @since Ant 1.6.2
088:             */
089:            public void handleOutput(String output) {
090:                if (ant != null) {
091:                    ant.handleOutput(output);
092:                } else {
093:                    super .handleOutput(output);
094:                }
095:            }
096:
097:            /**
098:             * Process input into the ant task
099:             *
100:             * @param buffer the buffer into which data is to be read.
101:             * @param offset the offset into the buffer at which data is stored.
102:             * @param length the amount of data to read
103:             *
104:             * @return the number of bytes read
105:             *
106:             * @exception IOException if the data cannot be read
107:             *
108:             * @see Task#handleInput(byte[], int, int)
109:             *
110:             * @since Ant 1.6.2
111:             */
112:            public int handleInput(byte[] buffer, int offset, int length)
113:                    throws IOException {
114:                if (ant != null) {
115:                    return ant.handleInput(buffer, offset, length);
116:                } else {
117:                    return super .handleInput(buffer, offset, length);
118:                }
119:            }
120:
121:            /**
122:             * Pass output sent to System.out to the new project.
123:             *
124:             * @param output The output to log. Should not be <code>null</code>.
125:             *
126:             * @since Ant 1.6.2
127:             */
128:            public void handleFlush(String output) {
129:                if (ant != null) {
130:                    ant.handleFlush(output);
131:                } else {
132:                    super .handleFlush(output);
133:                }
134:            }
135:
136:            /**
137:             * Pass output sent to System.err to the new project.
138:             *
139:             * @param output The error output to log. Should not be <code>null</code>.
140:             *
141:             * @since Ant 1.6.2
142:             */
143:            public void handleErrorOutput(String output) {
144:                if (ant != null) {
145:                    ant.handleErrorOutput(output);
146:                } else {
147:                    super .handleErrorOutput(output);
148:                }
149:            }
150:
151:            /**
152:             * Pass output sent to System.err to the new project.
153:             *
154:             * @param output The error output to log. Should not be <code>null</code>.
155:             *
156:             * @since Ant 1.6.2
157:             */
158:            public void handleErrorFlush(String output) {
159:                if (ant != null) {
160:                    ant.handleErrorFlush(output);
161:                } else {
162:                    super .handleErrorFlush(output);
163:                }
164:            }
165:
166:            /**
167:             * Runs the various sub-builds.
168:             */
169:            public void execute() {
170:                if (buildpath == null) {
171:                    throw new BuildException("No buildpath specified");
172:                }
173:
174:                final String[] filenames = buildpath.list();
175:                final int count = filenames.length;
176:                if (count < 1) {
177:                    log("No sub-builds to iterate on", Project.MSG_WARN);
178:                    return;
179:                }
180:                /*
181:                 //REVISIT: there must be cleaner way of doing this, if it is merited at all
182:                 if (subTarget == null) {
183:                 subTarget = getOwningTarget().getName();
184:                 }
185:                 */
186:                BuildException buildException = null;
187:                for (int i = 0; i < count; ++i) {
188:                    File file = null;
189:                    String subdirPath = null;
190:                    Throwable thrownException = null;
191:                    try {
192:                        File directory = null;
193:                        file = new File(filenames[i]);
194:                        if (file.isDirectory()) {
195:                            if (verbose) {
196:                                subdirPath = file.getPath();
197:                                log("Entering directory: " + subdirPath + "\n",
198:                                        Project.MSG_INFO);
199:                            }
200:                            if (genericantfile != null) {
201:                                directory = file;
202:                                file = genericantfile;
203:                            } else {
204:                                file = new File(file, antfile);
205:                            }
206:                        }
207:                        execute(file, directory);
208:                        if (verbose && subdirPath != null) {
209:                            log("Leaving directory: " + subdirPath + "\n",
210:                                    Project.MSG_INFO);
211:                        }
212:                    } catch (RuntimeException ex) {
213:                        if (!(getProject().isKeepGoingMode())) {
214:                            if (verbose && subdirPath != null) {
215:                                log("Leaving directory: " + subdirPath + "\n",
216:                                        Project.MSG_INFO);
217:                            }
218:                            throw ex; // throw further
219:                        }
220:                        thrownException = ex;
221:                    } catch (Throwable ex) {
222:                        if (!(getProject().isKeepGoingMode())) {
223:                            if (verbose && subdirPath != null) {
224:                                log("Leaving directory: " + subdirPath + "\n",
225:                                        Project.MSG_INFO);
226:                            }
227:                            throw new BuildException(ex);
228:                        }
229:                        thrownException = ex;
230:                    }
231:                    if (thrownException != null) {
232:                        if (thrownException instanceof  BuildException) {
233:                            log("File '" + file + "' failed with message '"
234:                                    + thrownException.getMessage() + "'.",
235:                                    Project.MSG_ERR);
236:                            // only the first build exception is reported
237:                            if (buildException == null) {
238:                                buildException = (BuildException) thrownException;
239:                            }
240:                        } else {
241:                            log("Target '" + file + "' failed with message '"
242:                                    + thrownException.getMessage() + "'.",
243:                                    Project.MSG_ERR);
244:                            thrownException.printStackTrace(System.err);
245:                            if (buildException == null) {
246:                                buildException = new BuildException(
247:                                        thrownException);
248:                            }
249:                        }
250:                        if (verbose && subdirPath != null) {
251:                            log("Leaving directory: " + subdirPath + "\n",
252:                                    Project.MSG_INFO);
253:                        }
254:                    }
255:                }
256:                // check if one of the builds failed in keep going mode
257:                if (buildException != null) {
258:                    throw buildException;
259:                }
260:            }
261:
262:            /**
263:             * Runs the given target on the provided build file.
264:             *
265:             * @param  file the build file to execute
266:             * @param  directory the directory of the current iteration
267:             * @throws BuildException is the file cannot be found, read, is
268:             *         a directory, or the target called failed, but only if
269:             *         <code>failOnError</code> is <code>true</code>. Otherwise,
270:             *         a warning log message is simply output.
271:             */
272:            private void execute(File file, File directory)
273:                    throws BuildException {
274:                if (!file.exists() || file.isDirectory() || !file.canRead()) {
275:                    String msg = "Invalid file: " + file;
276:                    if (failOnError) {
277:                        throw new BuildException(msg);
278:                    }
279:                    log(msg, Project.MSG_WARN);
280:                    return;
281:                }
282:
283:                ant = createAntTask(directory);
284:                String antfilename = file.getAbsolutePath();
285:                ant.setAntfile(antfilename);
286:                for (int i = 0; i < targets.size(); i++) {
287:                    TargetElement targetElement = (TargetElement) targets
288:                            .get(i);
289:                    ant.addConfiguredTarget(targetElement);
290:                }
291:
292:                try {
293:                    ant.execute();
294:                } catch (BuildException e) {
295:                    if (failOnError) {
296:                        throw e;
297:                    }
298:                    log("Failure for target '" + subTarget + "' of: "
299:                            + antfilename + "\n" + e.getMessage(),
300:                            Project.MSG_WARN);
301:                } catch (Throwable e) {
302:                    if (failOnError) {
303:                        throw new BuildException(e);
304:                    }
305:                    log("Failure for target '" + subTarget + "' of: "
306:                            + antfilename + "\n" + e.toString(),
307:                            Project.MSG_WARN);
308:                } finally {
309:                    ant = null;
310:                }
311:            }
312:
313:            /**
314:             * This method builds the file name to use in conjunction with directories.
315:             *
316:             * <p>Defaults to "build.xml".
317:             * If <code>genericantfile</code> is set, this attribute is ignored.</p>
318:             *
319:             * @param  antfile the short build file name. Defaults to "build.xml".
320:             */
321:            public void setAntfile(String antfile) {
322:                this .antfile = antfile;
323:            }
324:
325:            /**
326:             * This method builds a file path to use in conjunction with directories.
327:             *
328:             * <p>Use <code>genericantfile</code>, in order to run the same build file
329:             * with different basedirs.</p>
330:             * If this attribute is set, <code>antfile</code> is ignored.
331:             *
332:             * @param afile (path of the generic ant file, absolute or relative to
333:             *               project base directory)
334:             * */
335:            public void setGenericAntfile(File afile) {
336:                this .genericantfile = afile;
337:            }
338:
339:            /**
340:             * Sets whether to fail with a build exception on error, or go on.
341:             *
342:             * @param  failOnError the new value for this boolean flag.
343:             */
344:            public void setFailonerror(boolean failOnError) {
345:                this .failOnError = failOnError;
346:            }
347:
348:            /**
349:             * The target to call on the different sub-builds. Set to "" to execute
350:             * the default target.
351:             * @param target the target
352:             * <p>
353:             */
354:            //     REVISIT: Defaults to the target name that contains this task if not specified.
355:            public void setTarget(String target) {
356:                this .subTarget = target;
357:            }
358:
359:            /**
360:             * Add a target to this Ant invocation.
361:             * @param t the <code>TargetElement</code> to add.
362:             * @since Ant 1.7
363:             */
364:            public void addConfiguredTarget(TargetElement t) {
365:                String name = t.getName();
366:                if ("".equals(name)) {
367:                    throw new BuildException("target name must not be empty");
368:                }
369:                targets.add(t);
370:            }
371:
372:            /**
373:             * Enable/ disable verbose log messages showing when each sub-build path is entered/ exited.
374:             * The default value is "false".
375:             * @param on true to enable verbose mode, false otherwise (default).
376:             */
377:            public void setVerbose(boolean on) {
378:                this .verbose = on;
379:            }
380:
381:            /**
382:             * Corresponds to <code>&lt;ant&gt;</code>'s
383:             * <code>output</code> attribute.
384:             *
385:             * @param  s the filename to write the output to.
386:             */
387:            public void setOutput(String s) {
388:                this .output = s;
389:            }
390:
391:            /**
392:             * Corresponds to <code>&lt;ant&gt;</code>'s
393:             * <code>inheritall</code> attribute.
394:             *
395:             * @param  b the new value for this boolean flag.
396:             */
397:            public void setInheritall(boolean b) {
398:                this .inheritAll = b;
399:            }
400:
401:            /**
402:             * Corresponds to <code>&lt;ant&gt;</code>'s
403:             * <code>inheritrefs</code> attribute.
404:             *
405:             * @param  b the new value for this boolean flag.
406:             */
407:            public void setInheritrefs(boolean b) {
408:                this .inheritRefs = b;
409:            }
410:
411:            /**
412:             * Corresponds to <code>&lt;ant&gt;</code>'s
413:             * nested <code>&lt;property&gt;</code> element.
414:             *
415:             * @param  p the property to pass on explicitly to the sub-build.
416:             */
417:            public void addProperty(Property p) {
418:                properties.addElement(p);
419:            }
420:
421:            /**
422:             * Corresponds to <code>&lt;ant&gt;</code>'s
423:             * nested <code>&lt;reference&gt;</code> element.
424:             *
425:             * @param  r the reference to pass on explicitly to the sub-build.
426:             */
427:            public void addReference(Ant.Reference r) {
428:                references.addElement(r);
429:            }
430:
431:            /**
432:             * Corresponds to <code>&lt;ant&gt;</code>'s
433:             * nested <code>&lt;propertyset&gt;</code> element.
434:             * @param ps the propertset
435:             */
436:            public void addPropertyset(PropertySet ps) {
437:                propertySets.addElement(ps);
438:            }
439:
440:            /**
441:             * Adds a directory set to the implicit build path.
442:             * <p>
443:             * <em>Note that the directories will be added to the build path
444:             * in no particular order, so if order is significant, one should
445:             * use a file list instead!</em>
446:             *
447:             * @param  set the directory set to add.
448:             */
449:            public void addDirset(DirSet set) {
450:                add(set);
451:            }
452:
453:            /**
454:             * Adds a file set to the implicit build path.
455:             * <p>
456:             * <em>Note that the directories will be added to the build path
457:             * in no particular order, so if order is significant, one should
458:             * use a file list instead!</em>
459:             *
460:             * @param  set the file set to add.
461:             */
462:            public void addFileset(FileSet set) {
463:                add(set);
464:            }
465:
466:            /**
467:             * Adds an ordered file list to the implicit build path.
468:             * <p>
469:             * <em>Note that contrary to file and directory sets, file lists
470:             * can reference non-existent files or directories!</em>
471:             *
472:             * @param  list the file list to add.
473:             */
474:            public void addFilelist(FileList list) {
475:                add(list);
476:            }
477:
478:            /**
479:             * Adds a resource collection to the implicit build path.
480:             *
481:             * @param  rc the resource collection to add.
482:             * @since Ant 1.7
483:             */
484:            public void add(ResourceCollection rc) {
485:                getBuildpath().add(rc);
486:            }
487:
488:            /**
489:             * Set the buildpath to be used to find sub-projects.
490:             *
491:             * @param  s an Ant Path object containing the buildpath.
492:             */
493:            public void setBuildpath(Path s) {
494:                getBuildpath().append(s);
495:            }
496:
497:            /**
498:             * Creates a nested build path, and add it to the implicit build path.
499:             *
500:             * @return the newly created nested build path.
501:             */
502:            public Path createBuildpath() {
503:                return getBuildpath().createPath();
504:            }
505:
506:            /**
507:             * Creates a nested <code>&lt;buildpathelement&gt;</code>,
508:             * and add it to the implicit build path.
509:             *
510:             * @return the newly created nested build path element.
511:             */
512:            public Path.PathElement createBuildpathElement() {
513:                return getBuildpath().createPathElement();
514:            }
515:
516:            /**
517:             * Gets the implicit build path, creating it if <code>null</code>.
518:             *
519:             * @return the implicit build path.
520:             */
521:            private Path getBuildpath() {
522:                if (buildpath == null) {
523:                    buildpath = new Path(getProject());
524:                }
525:                return buildpath;
526:            }
527:
528:            /**
529:             * Buildpath to use, by reference.
530:             *
531:             * @param  r a reference to an Ant Path object containing the buildpath.
532:             */
533:            public void setBuildpathRef(Reference r) {
534:                createBuildpath().setRefid(r);
535:            }
536:
537:            /**
538:             * Creates the &lt;ant&gt; task configured to run a specific target.
539:             *
540:             * @param directory : if not null the directory where the build should run
541:             *
542:             * @return the ant task, configured with the explicit properties and
543:             *         references necessary to run the sub-build.
544:             */
545:            private Ant createAntTask(File directory) {
546:                Ant antTask = new Ant(this );
547:                antTask.init();
548:                if (subTarget != null && subTarget.length() > 0) {
549:                    antTask.setTarget(subTarget);
550:                }
551:
552:                if (output != null) {
553:                    antTask.setOutput(output);
554:                }
555:
556:                if (directory != null) {
557:                    antTask.setDir(directory);
558:                }
559:
560:                antTask.setInheritAll(inheritAll);
561:                for (Enumeration i = properties.elements(); i.hasMoreElements();) {
562:                    copyProperty(antTask.createProperty(), (Property) i
563:                            .nextElement());
564:                }
565:
566:                for (Enumeration i = propertySets.elements(); i
567:                        .hasMoreElements();) {
568:                    antTask.addPropertyset((PropertySet) i.nextElement());
569:                }
570:
571:                antTask.setInheritRefs(inheritRefs);
572:                for (Enumeration i = references.elements(); i.hasMoreElements();) {
573:                    antTask.addReference((Ant.Reference) i.nextElement());
574:                }
575:
576:                return antTask;
577:            }
578:
579:            /**
580:             * Assigns an Ant property to another.
581:             *
582:             * @param  to the destination property whose content is modified.
583:             * @param  from the source property whose content is copied.
584:             */
585:            private static void copyProperty(Property to, Property from) {
586:                to.setName(from.getName());
587:
588:                if (from.getValue() != null) {
589:                    to.setValue(from.getValue());
590:                }
591:                if (from.getFile() != null) {
592:                    to.setFile(from.getFile());
593:                }
594:                if (from.getResource() != null) {
595:                    to.setResource(from.getResource());
596:                }
597:                if (from.getPrefix() != null) {
598:                    to.setPrefix(from.getPrefix());
599:                }
600:                if (from.getRefid() != null) {
601:                    to.setRefid(from.getRefid());
602:                }
603:                if (from.getEnvironment() != null) {
604:                    to.setEnvironment(from.getEnvironment());
605:                }
606:                if (from.getClasspath() != null) {
607:                    to.setClasspath(from.getClasspath());
608:                }
609:            }
610:
611:        } // END class SubAnt
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.