git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269745 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -1,5 +1,5 @@ | |||||
| Changes from Ant 1.4 to current CVS version | |||||
| =========================================== | |||||
| Changes from Ant 1.4.1 to current CVS version | |||||
| ============================================== | |||||
| Changes that could break older environments: | Changes that could break older environments: | ||||
| -------------------------------------------- | -------------------------------------------- | ||||
| @@ -20,6 +20,49 @@ Fixed bugs: | |||||
| * Fixed bug where ant would not copy system properties into new Project | * Fixed bug where ant would not copy system properties into new Project | ||||
| in ant/antcall tasks when inheritall="false" is set. | in ant/antcall tasks when inheritall="false" is set. | ||||
| Changes from Ant 1.4 to Ant 1.4.1 | |||||
| =========================================== | |||||
| Fixed bugs: | |||||
| ----------- | |||||
| * <ant>'s antfile attribute will now also be considered an absolute path on | |||||
| Windows systems, if it starts with a \ and no drive specifier. | |||||
| * The fullpath attribute of <zipfileset> has been ignored if you used | |||||
| the src attribute at the same time. | |||||
| * The manifest file is now always placed as the second entry (after /META-INF) | |||||
| in generated jars. This allows the manifest to be read by JarInputStreams | |||||
| * Fixed bug in depend task which would fail with a NullPointerException if no | |||||
| dependency cache was specified. | |||||
| * sql task now handles REM statements correctly so that lines starying with rem | |||||
| but which are not comments are actually processed. | |||||
| * XMLLogger now uses the task's name rather than the classname | |||||
| * <mapper>s will now work as expected if the to pattern expands to an | |||||
| absolute pathname. | |||||
| * <javac> didn't ignore memory settings in non-fork mode | |||||
| * <cab> didn't split the options attribute into several command line | |||||
| arguments correctly. | |||||
| Other changes: | |||||
| -------------- | |||||
| * New source attribute for <javac> to enable assertion in JDK 1.4 | |||||
| * XmlLogger and <antstructure> now add an encoding declaration to the | |||||
| XML files they generate. | |||||
| * <fileset> has a new attribute "casesensitive" to make it match | |||||
| filenames in a case insensitive way (if you set it to false) - by | |||||
| default filesets remain case sensitive. | |||||
| Changes from Ant 1.3 to Ant 1.4 | Changes from Ant 1.3 to Ant 1.4 | ||||
| =========================================== | =========================================== | ||||
| @@ -185,7 +185,7 @@ task can be used to invoke them. It is best to specify that you want a | |||||
| new JVM for these tests, so that a significant crash does not break the | new JVM for these tests, so that a significant crash does not break the | ||||
| full build. The Junit extensions such as | full build. The Junit extensions such as | ||||
| <a href="http://httpunit.sourceforge.net/">HttpUnit</a> for web pages, and | <a href="http://httpunit.sourceforge.net/">HttpUnit</a> for web pages, and | ||||
| <a href="http://jakarta.apache.org/commons/cactus/">Cactus</a> for J2EE and servlet | |||||
| <a href="http://jakarta.apache.org/cactus/">Cactus</a> for J2EE and servlet | |||||
| testing help to expand the testing framework. To test properly you will still | testing help to expand the testing framework. To test properly you will still | ||||
| need to invest a lot of effort in getting these to work with your project, and | need to invest a lot of effort in getting these to work with your project, and | ||||
| deriving great unit, system and regression tests -but your customers will love | deriving great unit, system and regression tests -but your customers will love | ||||
| @@ -659,10 +659,16 @@ Faster compiles with Jikes | |||||
| </b><dd> | </b><dd> | ||||
| The <a href="http://www.jikes.org/">jikes compiler</a> is usually much | The <a href="http://www.jikes.org/">jikes compiler</a> is usually much | ||||
| faster than javac, and does dependency checking. Get it. Then set | |||||
| build.compiler to "jikes" for it to be used in your build files. Better | |||||
| yet, set the JIKES_HOME environment variable for jikes to automatically | |||||
| get used, without changing your build files to only work with jikes. | |||||
| faster than javac, does dependency checking and has better error | |||||
| messages (usually). Get it. Then set | |||||
| build.compiler to "jikes" for it to be used in your build files. | |||||
| Doing this explicitly in your build files is a bit dubious as it requires the | |||||
| whole team (and sub projects) to be using jikes too -something you can only | |||||
| control in small, closed source projects. But if you set | |||||
| <tt>ANT_OPTS = -Dbuild.compiler=jikes</tt> | |||||
| in your environment, then all your builds on your system will use | |||||
| Jikes automatically, while others can choose their own compiler, or let | |||||
| ant choose whichever is appropriate for the current version of Java. | |||||
| <dt><b> | <dt><b> | ||||
| #include targets to simplify multi build.xml projects | #include targets to simplify multi build.xml projects | ||||
| @@ -924,6 +930,25 @@ complicated. Use XML comments so that the file you wrote last month | |||||
| still makes sense when you get back to it, and use Antidote to edit the | still makes sense when you get back to it, and use Antidote to edit the | ||||
| files if you prefer it. | files if you prefer it. | ||||
| <h3>Big projects still get complicated fast</h3> | |||||
| Large software projects create their own complexity, with inter-dependent | |||||
| libraries, long test cycles, hard deployment processes and a multitude of | |||||
| people each working on their own bit of the solution. That's even before | |||||
| the deadlines loom close, the integration problems become insurmountable, | |||||
| weekends become indistinguishable from weekdays in terms of workload and | |||||
| half the team stops talking to the other half. Ant may simplify the | |||||
| build and test process, and can eliminate the full time 'makefile engineer' | |||||
| role, but that doesn't mean that someone can stop 'owning the build'. | |||||
| Being in charge of the build has to mean more than they type 'ant all' on | |||||
| their system, it means they need to set the standards of what build tools to | |||||
| use, what the common targets, what property names and files should be | |||||
| and generally oversee the sub projects build processes. On a small project, | |||||
| you don't need to do that -but remember: small projects become big projects | |||||
| when you aren't looking. If you start off with a little bit of process, then | |||||
| you can scale it if needed. Ff you start with none, by the time you need | |||||
| it it will be too late. | |||||
| <h3>You still need all the other foundational bits of a software | <h3>You still need all the other foundational bits of a software | ||||
| project</h3> | project</h3> | ||||
| @@ -988,4 +1013,4 @@ instead. | |||||
| <hr> | <hr> | ||||
| <p align="center">Copyright © 2000, 2001 Apache Software Foundation. All rights | <p align="center">Copyright © 2000, 2001 Apache Software Foundation. All rights | ||||
| Reserved.</p> | Reserved.</p> | ||||
| </body> | |||||
| </body> | |||||
| @@ -166,7 +166,7 @@ the command line.</p> | |||||
| <blockquote><pre> | <blockquote><pre> | ||||
| <apply executable="somecommand" parallel="false" > | <apply executable="somecommand" parallel="false" > | ||||
| <arg value="arg1"/> | <arg value="arg1"/> | ||||
| <srfile/> | |||||
| <srcfile/> | |||||
| <arg value="arg2"/> | <arg value="arg2"/> | ||||
| <fileset dir="/tmp"/> | <fileset dir="/tmp"/> | ||||
| </apply> | </apply> | ||||
| @@ -215,6 +215,15 @@ files/directories from the CLASSPATH it passes to the compiler.</p> | |||||
| </td> | </td> | ||||
| <td align="center" valign="top">No</td> | <td align="center" valign="top">No</td> | ||||
| </tr> | </tr> | ||||
| <tr> | |||||
| <td valign="top">source</td> | |||||
| <td valign="top">Value of the <code>-source</code> command line | |||||
| switch, will be ignored by all implementations except | |||||
| <code>modern</code>, legal values are "1.3" and | |||||
| "1.4" - by default, no <code>-source</code> argument | |||||
| will be used at all.</td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| </table> | </table> | ||||
| <h3>Parameters specified as nested elements</h3> | <h3>Parameters specified as nested elements</h3> | ||||
| @@ -291,15 +300,7 @@ or elements to filter for these packages. If you include part of your package-st | |||||
| <h3>Jikes Notes</h3> | <h3>Jikes Notes</h3> | ||||
| If the environment variable <tt>JIKES_HOME</tt> is set to the location | |||||
| of the jikes compiler, then the standard Ant invocation scripts | |||||
| automatically set build.compiler to "jikes". This enables one to use | |||||
| jikes when available, without having to commit the build file to a | |||||
| single choice of compiler. | |||||
| <p> | |||||
| Jikes also supports some extra options, which can be set be defining | |||||
| Jikes supports some extra options, which can be set be defining | |||||
| properties prior to invoking the task. The ant developers are aware that | properties prior to invoking the task. The ant developers are aware that | ||||
| this is ugly and inflexible -expect a better solution in the future. All | this is ugly and inflexible -expect a better solution in the future. All | ||||
| the options are boolean, and must be set to "true" or "yes" to be | the options are boolean, and must be set to "true" or "yes" to be | ||||
| @@ -129,6 +129,12 @@ on the same schema.</p> | |||||
| <td valign="top" align="center">Yes, unless statements enclosed within tags</td> | <td valign="top" align="center">Yes, unless statements enclosed within tags</td> | ||||
| </tr> | </tr> | ||||
| </table> | </table> | ||||
| <h4>fileset</h4> | |||||
| <p>You can specify multiple source files via nested <a | |||||
| href="../CoreTypes/fileset.html">fileset</a> elements. Each file of | |||||
| the fileset will be run in a transaction of its own, the order by | |||||
| which the files of a single fileset will be executed is not | |||||
| defined.</p> | |||||
| <h4>classpath</h4> | <h4>classpath</h4> | ||||
| <p><code>Sql</code>'s <em>classpath</em> attribute is a <a | <p><code>Sql</code>'s <em>classpath</em> attribute is a <a | ||||
| href="../using.html#path">PATH like structure</a> and can also be set via a nested | href="../using.html#path">PATH like structure</a> and can also be set via a nested | ||||
| @@ -205,6 +211,25 @@ operation on <i>some_other_table</i>.</p> | |||||
| </sql> | </sql> | ||||
| </pre></blockquote> | </pre></blockquote> | ||||
| <p>The following example does the same as (and may execute additional | |||||
| SQL files if there are more files matching the pattern | |||||
| <code>data*.sql</code>) but doesn't guarantee that data1.sql will be | |||||
| run before <code>data2.sql</code>.</p> | |||||
| <blockquote><pre><sql | |||||
| driver="org.database.jdbcDriver" | |||||
| url="jdbc:database-url" | |||||
| userid="sa" | |||||
| password="pass" > | |||||
| <fileset dir="."> | |||||
| <include name="data*.sql" /> | |||||
| </fileset> | |||||
| <transaction> | |||||
| truncate table some_other_table; | |||||
| </transaction> | |||||
| </sql> | |||||
| </pre></blockquote> | |||||
| <p>The following connects to the database given in url as the sa user using the | <p>The following connects to the database given in url as the sa user using the | ||||
| org.database.jdbcDriver and executes the SQL statements contained within the | org.database.jdbcDriver and executes the SQL statements contained within the | ||||
| file data.sql, with output piped to outputfile.txt, searching /some/jdbc.jar | file data.sql, with output piped to outputfile.txt, searching /some/jdbc.jar | ||||
| @@ -62,11 +62,17 @@ attributes.</p> | |||||
| taken to be an exclude pattern.</td> | taken to be an exclude pattern.</td> | ||||
| <td valign="top" align="center">No</td> | <td valign="top" align="center">No</td> | ||||
| </tr> | </tr> | ||||
| <tr> | |||||
| <td valign="top">casesensitive</td> | |||||
| <td valign="top">Must the file system be treated in a case sensitive way? | |||||
| Defaults to true.</td> | |||||
| <td valign="top" align="center">No</td> | |||||
| </tr> | |||||
| </table> | </table> | ||||
| <h4>Examples</h4> | <h4>Examples</h4> | ||||
| <blockquote><pre> | <blockquote><pre> | ||||
| <fileset dir="${server.src}" > | |||||
| <fileset dir="${server.src}" casesensitive="yes" > | |||||
| <patternset id="non.test.sources" > | <patternset id="non.test.sources" > | ||||
| <include name="**/*.java"/> | <include name="**/*.java"/> | ||||
| <exclude name="**/*Test*"/> | <exclude name="**/*Test*"/> | ||||
| @@ -28,7 +28,7 @@ replacements in tasks like copy etc.<BR> | |||||
| <TD vAlign=top align="center"><B>Required</B></TD> | <TD vAlign=top align="center"><B>Required</B></TD> | ||||
| </TR> | </TR> | ||||
| <TR> | <TR> | ||||
| <TD vAlign=top>starttoken</TD> | |||||
| <TD vAlign=top>begintoken</TD> | |||||
| <TD vAlign=top>The string marking the beginning of a token. eg | <TD vAlign=top>The string marking the beginning of a token. eg | ||||
| <STRONG>@</STRONG>Date@</TD> | <STRONG>@</STRONG>Date@</TD> | ||||
| <TD vAlign=top>@</TD> | <TD vAlign=top>@</TD> | ||||
| @@ -82,7 +82,7 @@ replacements in tasks like copy etc.<BR> | |||||
| <p>You are copying the version.txt file to the dist directory from the build directory | <p>You are copying the version.txt file to the dist directory from the build directory | ||||
| but wish to replace the token @DATE@ with todays date.</p> | but wish to replace the token @DATE@ with todays date.</p> | ||||
| <BLOCKQUOTE><PRE> | <BLOCKQUOTE><PRE> | ||||
| <copy file="${build.home}/version.txt" toFile="${dist.home}/version.txt"< | |||||
| <copy file="${build.home}/version.txt" toFile="${dist.home}/version.txt"> | |||||
| <filterset> | <filterset> | ||||
| <filter token="DATE" value="${DATE}"/> | <filter token="DATE" value="${DATE}"/> | ||||
| </filterset> | </filterset> | ||||
| @@ -533,20 +533,6 @@ include: </p> | |||||
| <li>TOPLink for WebLogic 2.5.1-enabled entity beans</li> | <li>TOPLink for WebLogic 2.5.1-enabled entity beans</li> | ||||
| </ul> | </ul> | ||||
| <p>This task supports two approaches to creating ejb jar files. The first | |||||
| approach assumes a particular naming convention for deployment descriptor files. | |||||
| For an Account bean, for example, the deployment descriptor would be named | |||||
| <code>Account-ejb-jar.xml</code>. This naming convention allows the task to | |||||
| distinguish deployment descriptors without relying on their positioning within a | |||||
| source tree. It is also used to derive the name of the .jar file which is | |||||
| generated. For the example this would be <code>Account.jar</code>. Vendor | |||||
| specific files are assumed to be named in a similar fashion. The deployment | |||||
| descriptor file which defines additional weblogic specific information for the | |||||
| above bean would be <code>Account-weblogic-ejb-jar.xml</code>. The second | |||||
| approach does not require a naming convention. This approach uses a specified a | |||||
| jar name for the resultant ejb jar. If the jar name is present, then no naming | |||||
| convention is required. If the jar name is not specified, then the default | |||||
| naming convention is expected for the deployment descriptor files.</p> | |||||
| <p>The task works as a directory scanning task, and performs an action for each | <p>The task works as a directory scanning task, and performs an action for each | ||||
| deployment descriptor found. As such the includes and excludes should be set | deployment descriptor found. As such the includes and excludes should be set | ||||
| @@ -571,6 +557,75 @@ respect to the class files and deployment descriptors that make up the bean. If | |||||
| any of these files are newer than the jar file the jar will be rebuilt otherwise | any of these files are newer than the jar file the jar will be rebuilt otherwise | ||||
| a message is logged that the jar file is up to date.</p> | a message is logged that the jar file is up to date.</p> | ||||
| <h3>Naming Convention</h3> | |||||
| Ejbjar handles the processing of multiple beans, and it uses a set of naming | |||||
| conventions to determine the name of the generated EJB jars. The naming convention | |||||
| that is used is controlled by the "naming" attribute. It supports the | |||||
| following values | |||||
| <ul> | |||||
| <li>descriptor</li> | |||||
| <p>This is the default naming scheme. The name of the generated bean is derived from the | |||||
| name of the deployment descriptor. For an Account bean, for example, the deployment | |||||
| descriptor would be named <code>Account-ejb-jar.xml</code>. Vendor specific descriptors are | |||||
| located using the same naming convention. The weblogic bean, for example, would be named | |||||
| <code>Account-weblogic-ejb-jar.xml</code>. Under this arrangment, the deployment descriptors | |||||
| can be separated from the code implementing the beans, which can be useful whe the same bean code | |||||
| is deployed in separate beans. | |||||
| </p> | |||||
| <p>This scheme is useful when you are using one bean per EJB jar and where you may be | |||||
| deploying the same bean classes in different beans, with different deployment characteristics. | |||||
| <li>ejb-name</li> | |||||
| <p> This naming scheme uses the <ejb-name> element from the deployment descriptor to | |||||
| determine the bean name. In this situation, the descriptors normally use the generic | |||||
| descriptor names, such as <code>ejb-jar.xml</code> along with any associated vendor specific descriptor | |||||
| names. For example, If the value of the <ejb-name> were to be given in the deployment descriptor | |||||
| as follows: | |||||
| <pre> | |||||
| <ejb-jar> | |||||
| <enterprise-beans> | |||||
| <entity> | |||||
| <ejb-name>Sample</ejb-name> | |||||
| <home>org.apache.ant.ejbsample.SampleHome</home> | |||||
| </pre> | |||||
| then the name of the generated bean would be <code>Sample.jar</code> | |||||
| </p> | |||||
| <p> This scheme is useful where you want to use the standard deployment descriptor names, which may be more | |||||
| compatible with other EJB tools. This scheme must have one bean per jar. | |||||
| </p> | |||||
| <li>directory</li> | |||||
| <p> | |||||
| In this mode, the name of the generated bean jar is derived from the directory | |||||
| containing the deployment descriptors. Again the deployment descriptors typically use | |||||
| the standard filenames. For example, if the path to the deployment descriptor is | |||||
| <code>/home/user/dev/appserver/dd/sample</code>, then the generated | |||||
| bean will be named <code>sample.jar</code> | |||||
| </p> | |||||
| <p> | |||||
| This scheme is also useful when you want to use standard style descriptor names. It is often | |||||
| most useful when the descriptors are located in the same directory as the bean source code, | |||||
| although that is not mandatory. This scheme can handle multiple beans per jar. | |||||
| </p> | |||||
| <li>basejarname</li> | |||||
| <p> | |||||
| The final scheme supported by the <ejbjar> task is used when you want to specify the generated | |||||
| bean jar name directly. In this case the name of the generated jar is specified by the | |||||
| "basejarname" attribute. Since all generated beans will have the same name, this task should | |||||
| be only used when each descriptor is in its own directory. | |||||
| </p> | |||||
| <p> | |||||
| This scheme is most appropriate when you are using multiple beans per jar and only process a single | |||||
| deployment descriptor. You typically want to specify the name of the jar and not derive it from the | |||||
| beans in the jar. | |||||
| </p> | |||||
| </ul> | |||||
| <h3>Parameters:</h3> | <h3>Parameters:</h3> | ||||
| <table border="1" cellpadding="2" cellspacing="0"> | <table border="1" cellpadding="2" cellspacing="0"> | ||||
| <tr> | <tr> | ||||
| @@ -605,6 +660,12 @@ a message is logged that the jar file is up to date.</p> | |||||
| deployment elements have been specified).</td> | deployment elements have been specified).</td> | ||||
| <td valign="top" align="center">Yes</td> | <td valign="top" align="center">Yes</td> | ||||
| </tr> | </tr> | ||||
| <tr> | |||||
| <td valign="top">naming</td> | |||||
| <td valign="top">Controls the naming convention used to name generated | |||||
| EJB jars. Please refer to the description above.</td> | |||||
| <td valign="top" align="center">No</td> | |||||
| </tr> | |||||
| <tr> | <tr> | ||||
| <td valign="top">basejarname</td> | <td valign="top">basejarname</td> | ||||
| <td valign="top">The base name that is used for the generated jar files. | <td valign="top">The base name that is used for the generated jar files. | ||||
| @@ -1,14 +0,0 @@ | |||||
| <?xml version="1.0"?> | |||||
| <project name="xxx-test" basedir="." default="test1"> | |||||
| <target name="test1"> | |||||
| </target> | |||||
| <target name="test2"> | |||||
| </target> | |||||
| <target name="test3"> | |||||
| </target> | |||||
| </project> | |||||
| @@ -113,6 +113,9 @@ import java.util.*; | |||||
| * "**\test\**\XYZ*" matches all files/dirs that start with "XYZ" and where | * "**\test\**\XYZ*" matches all files/dirs that start with "XYZ" and where | ||||
| * there is a parent directory called test (e.g. "abc\test\def\ghi\XYZ123"). | * there is a parent directory called test (e.g. "abc\test\def\ghi\XYZ123"). | ||||
| * <p> | * <p> | ||||
| * Case sensitivity may be turned off if necessary. By default, it is | |||||
| * turned on. | |||||
| * <p> | |||||
| * Example of usage: | * Example of usage: | ||||
| * <pre> | * <pre> | ||||
| * String[] includes = {"**\\*.class"}; | * String[] includes = {"**\\*.class"}; | ||||
| @@ -120,6 +123,7 @@ import java.util.*; | |||||
| * ds.setIncludes(includes); | * ds.setIncludes(includes); | ||||
| * ds.setExcludes(excludes); | * ds.setExcludes(excludes); | ||||
| * ds.setBasedir(new File("test")); | * ds.setBasedir(new File("test")); | ||||
| * ds.setCaseSensitive(true); | |||||
| * ds.scan(); | * ds.scan(); | ||||
| * | * | ||||
| * System.out.println("FILES:"); | * System.out.println("FILES:"); | ||||
| @@ -132,6 +136,7 @@ import java.util.*; | |||||
| * .class files in all directories under a directory called "modules" | * .class files in all directories under a directory called "modules" | ||||
| * | * | ||||
| * @author Arnout J. Kuiper <a href="mailto:ajkuiper@wxs.nl">ajkuiper@wxs.nl</a> | * @author Arnout J. Kuiper <a href="mailto:ajkuiper@wxs.nl">ajkuiper@wxs.nl</a> | ||||
| * @author <a href="mailto:umagesh@rediffmail.com">Magesh Umasankar</a> | |||||
| */ | */ | ||||
| public class DirectoryScanner implements FileScanner { | public class DirectoryScanner implements FileScanner { | ||||
| @@ -207,6 +212,11 @@ public class DirectoryScanner implements FileScanner { | |||||
| */ | */ | ||||
| protected boolean haveSlowResults = false; | protected boolean haveSlowResults = false; | ||||
| /** | |||||
| * Should the file system be treated as a case sensitive one? | |||||
| */ | |||||
| protected boolean isCaseSensitive = true; | |||||
| /** | /** | ||||
| * Constructor. | * Constructor. | ||||
| */ | */ | ||||
| @@ -216,7 +226,7 @@ public class DirectoryScanner implements FileScanner { | |||||
| /** | /** | ||||
| * Does the path match the start of this pattern up to the first "**". | * Does the path match the start of this pattern up to the first "**". | ||||
| + | |||||
| * | |||||
| * <p>This is not a general purpose test and should only be used if you | * <p>This is not a general purpose test and should only be used if you | ||||
| * can live with false positives.</p> | * can live with false positives.</p> | ||||
| * | * | ||||
| @@ -226,6 +236,23 @@ public class DirectoryScanner implements FileScanner { | |||||
| * @param str the (non-null) string (path) to match | * @param str the (non-null) string (path) to match | ||||
| */ | */ | ||||
| protected static boolean matchPatternStart(String pattern, String str) { | protected static boolean matchPatternStart(String pattern, String str) { | ||||
| return matchPatternStart(pattern, str, true); | |||||
| } | |||||
| /** | |||||
| * Does the path match the start of this pattern up to the first "**". | |||||
| * | |||||
| * <p>This is not a general purpose test and should only be used if you | |||||
| * can live with false positives.</p> | |||||
| * | |||||
| * <p><code>pattern=**\\a</code> and <code>str=b</code> will yield true. | |||||
| * | |||||
| * @param pattern the (non-null) pattern to match against | |||||
| * @param str the (non-null) string (path) to match | |||||
| * @param isCaseSensitive must matches be case sensitive? | |||||
| */ | |||||
| protected static boolean matchPatternStart(String pattern, String str, | |||||
| boolean isCaseSensitive) { | |||||
| // When str starts with a File.separator, pattern has to start with a | // When str starts with a File.separator, pattern has to start with a | ||||
| // File.separator. | // File.separator. | ||||
| // When pattern starts with a File.separator, str has to start with a | // When pattern starts with a File.separator, str has to start with a | ||||
| @@ -258,7 +285,7 @@ public class DirectoryScanner implements FileScanner { | |||||
| if (patDir.equals("**")) { | if (patDir.equals("**")) { | ||||
| break; | break; | ||||
| } | } | ||||
| if (!match(patDir,(String)strDirs.elementAt(strIdxStart))) { | |||||
| if (!match(patDir,(String)strDirs.elementAt(strIdxStart), isCaseSensitive)) { | |||||
| return false; | return false; | ||||
| } | } | ||||
| patIdxStart++; | patIdxStart++; | ||||
| @@ -288,6 +315,20 @@ public class DirectoryScanner implements FileScanner { | |||||
| * <code>false</code> otherwise. | * <code>false</code> otherwise. | ||||
| */ | */ | ||||
| protected static boolean matchPath(String pattern, String str) { | protected static boolean matchPath(String pattern, String str) { | ||||
| return matchPath(pattern, str, true); | |||||
| } | |||||
| /** | |||||
| * Matches a path against a pattern. | |||||
| * | |||||
| * @param pattern the (non-null) pattern to match against | |||||
| * @param str the (non-null) string (path) to match | |||||
| * @param isCaseSensitive must a case sensitive match be done? | |||||
| * | |||||
| * @return <code>true</code> when the pattern matches against the string. | |||||
| * <code>false</code> otherwise. | |||||
| */ | |||||
| protected static boolean matchPath(String pattern, String str, boolean isCaseSensitive) { | |||||
| // When str starts with a File.separator, pattern has to start with a | // When str starts with a File.separator, pattern has to start with a | ||||
| // File.separator. | // File.separator. | ||||
| // When pattern starts with a File.separator, str has to start with a | // When pattern starts with a File.separator, str has to start with a | ||||
| @@ -320,7 +361,7 @@ public class DirectoryScanner implements FileScanner { | |||||
| if (patDir.equals("**")) { | if (patDir.equals("**")) { | ||||
| break; | break; | ||||
| } | } | ||||
| if (!match(patDir,(String)strDirs.elementAt(strIdxStart))) { | |||||
| if (!match(patDir,(String)strDirs.elementAt(strIdxStart), isCaseSensitive)) { | |||||
| return false; | return false; | ||||
| } | } | ||||
| patIdxStart++; | patIdxStart++; | ||||
| @@ -347,7 +388,7 @@ public class DirectoryScanner implements FileScanner { | |||||
| if (patDir.equals("**")) { | if (patDir.equals("**")) { | ||||
| break; | break; | ||||
| } | } | ||||
| if (!match(patDir,(String)strDirs.elementAt(strIdxEnd))) { | |||||
| if (!match(patDir,(String)strDirs.elementAt(strIdxEnd), isCaseSensitive)) { | |||||
| return false; | return false; | ||||
| } | } | ||||
| patIdxEnd--; | patIdxEnd--; | ||||
| @@ -386,7 +427,7 @@ strLoop: | |||||
| for (int j = 0; j < patLength; j++) { | for (int j = 0; j < patLength; j++) { | ||||
| String subPat = (String)patDirs.elementAt(patIdxStart+j+1); | String subPat = (String)patDirs.elementAt(patIdxStart+j+1); | ||||
| String subStr = (String)strDirs.elementAt(strIdxStart+i+j); | String subStr = (String)strDirs.elementAt(strIdxStart+i+j); | ||||
| if (!match(subPat,subStr)) { | |||||
| if (!match(subPat,subStr, isCaseSensitive)) { | |||||
| continue strLoop; | continue strLoop; | ||||
| } | } | ||||
| } | } | ||||
| @@ -413,7 +454,6 @@ strLoop: | |||||
| } | } | ||||
| /** | /** | ||||
| * Matches a string against a pattern. The pattern contains two special | * Matches a string against a pattern. The pattern contains two special | ||||
| * characters: | * characters: | ||||
| @@ -428,6 +468,24 @@ strLoop: | |||||
| * <code>false</code> otherwise. | * <code>false</code> otherwise. | ||||
| */ | */ | ||||
| protected static boolean match(String pattern, String str) { | protected static boolean match(String pattern, String str) { | ||||
| return match(pattern, str, true); | |||||
| } | |||||
| /** | |||||
| * Matches a string against a pattern. The pattern contains two special | |||||
| * characters: | |||||
| * '*' which means zero or more characters, | |||||
| * '?' which means one and only one character. | |||||
| * | |||||
| * @param pattern the (non-null) pattern to match against | |||||
| * @param str the (non-null) string that must be matched against the | |||||
| * pattern | |||||
| * | |||||
| * @return <code>true</code> when the string matches against the pattern, | |||||
| * <code>false</code> otherwise. | |||||
| */ | |||||
| protected static boolean match(String pattern, String str, boolean isCaseSensitive) { | |||||
| char[] patArr = pattern.toCharArray(); | char[] patArr = pattern.toCharArray(); | ||||
| char[] strArr = str.toCharArray(); | char[] strArr = str.toCharArray(); | ||||
| int patIdxStart = 0; | int patIdxStart = 0; | ||||
| @@ -451,21 +509,33 @@ strLoop: | |||||
| } | } | ||||
| for (int i = 0; i <= patIdxEnd; i++) { | for (int i = 0; i <= patIdxEnd; i++) { | ||||
| ch = patArr[i]; | ch = patArr[i]; | ||||
| if (ch != '?' && ch != strArr[i]) { | |||||
| return false; // Character mismatch | |||||
| if (ch != '?') { | |||||
| if (isCaseSensitive && ch != strArr[i]) { | |||||
| return false;// Character mismatch | |||||
| } | |||||
| if (!isCaseSensitive && Character.toUpperCase(ch) != | |||||
| Character.toUpperCase(strArr[i])) { | |||||
| return false; // Character mismatch | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| return true; // String matches against pattern | return true; // String matches against pattern | ||||
| } | } | ||||
| if (patIdxEnd == 0) { | if (patIdxEnd == 0) { | ||||
| return true; // Pattern contains only '*', which matches anything | return true; // Pattern contains only '*', which matches anything | ||||
| } | } | ||||
| // Process characters before first star | // Process characters before first star | ||||
| while((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) { | while((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) { | ||||
| if (ch != '?' && ch != strArr[strIdxStart]) { | |||||
| return false; | |||||
| if (ch != '?') { | |||||
| if (isCaseSensitive && ch != strArr[strIdxStart]) { | |||||
| return false;// Character mismatch | |||||
| } | |||||
| if (!isCaseSensitive && Character.toUpperCase(ch) != | |||||
| Character.toUpperCase(strArr[strIdxStart])) { | |||||
| return false;// Character mismatch | |||||
| } | |||||
| } | } | ||||
| patIdxStart++; | patIdxStart++; | ||||
| strIdxStart++; | strIdxStart++; | ||||
| @@ -483,8 +553,14 @@ strLoop: | |||||
| // Process characters after last star | // Process characters after last star | ||||
| while((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) { | while((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) { | ||||
| if (ch != '?' && ch != strArr[strIdxEnd]) { | |||||
| return false; | |||||
| if (ch != '?') { | |||||
| if (isCaseSensitive && ch != strArr[strIdxEnd]) { | |||||
| return false;// Character mismatch | |||||
| } | |||||
| if (!isCaseSensitive && Character.toUpperCase(ch) != | |||||
| Character.toUpperCase(strArr[strIdxEnd])) { | |||||
| return false;// Character mismatch | |||||
| } | |||||
| } | } | ||||
| patIdxEnd--; | patIdxEnd--; | ||||
| strIdxEnd--; | strIdxEnd--; | ||||
| @@ -520,12 +596,18 @@ strLoop: | |||||
| int patLength = (patIdxTmp-patIdxStart-1); | int patLength = (patIdxTmp-patIdxStart-1); | ||||
| int strLength = (strIdxEnd-strIdxStart+1); | int strLength = (strIdxEnd-strIdxStart+1); | ||||
| int foundIdx = -1; | int foundIdx = -1; | ||||
| strLoop: | |||||
| strLoop: | |||||
| for (int i = 0; i <= strLength - patLength; i++) { | for (int i = 0; i <= strLength - patLength; i++) { | ||||
| for (int j = 0; j < patLength; j++) { | for (int j = 0; j < patLength; j++) { | ||||
| ch = patArr[patIdxStart+j+1]; | ch = patArr[patIdxStart+j+1]; | ||||
| if (ch != '?' && ch != strArr[strIdxStart+i+j]) { | |||||
| continue strLoop; | |||||
| if (ch != '?') { | |||||
| if (isCaseSensitive && ch != strArr[strIdxStart+i+j]) { | |||||
| continue strLoop; | |||||
| } | |||||
| if (!isCaseSensitive && Character.toUpperCase(ch) != | |||||
| Character.toUpperCase(strArr[strIdxStart+i+j])) { | |||||
| continue strLoop; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -591,6 +673,15 @@ strLoop: | |||||
| /** | |||||
| * Sets the case sensitivity of the file system | |||||
| * | |||||
| * @param specifies if the filesystem is case sensitive | |||||
| */ | |||||
| public void setCaseSensitive(boolean isCaseSensitive) { | |||||
| this.isCaseSensitive = isCaseSensitive; | |||||
| } | |||||
| /** | /** | ||||
| * Sets the set of include patterns to use. All '/' and '\' characters are | * Sets the set of include patterns to use. All '/' and '\' characters are | ||||
| * replaced by <code>File.separatorChar</code>. So the separator used need | * replaced by <code>File.separatorChar</code>. So the separator used need | ||||
| @@ -808,7 +899,7 @@ strLoop: | |||||
| */ | */ | ||||
| protected boolean isIncluded(String name) { | protected boolean isIncluded(String name) { | ||||
| for (int i = 0; i < includes.length; i++) { | for (int i = 0; i < includes.length; i++) { | ||||
| if (matchPath(includes[i],name)) { | |||||
| if (matchPath(includes[i],name, isCaseSensitive)) { | |||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| @@ -824,7 +915,7 @@ strLoop: | |||||
| */ | */ | ||||
| protected boolean couldHoldIncluded(String name) { | protected boolean couldHoldIncluded(String name) { | ||||
| for (int i = 0; i < includes.length; i++) { | for (int i = 0; i < includes.length; i++) { | ||||
| if (matchPatternStart(includes[i],name)) { | |||||
| if (matchPatternStart(includes[i],name, isCaseSensitive)) { | |||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| @@ -840,7 +931,7 @@ strLoop: | |||||
| */ | */ | ||||
| protected boolean isExcluded(String name) { | protected boolean isExcluded(String name) { | ||||
| for (int i = 0; i < excludes.length; i++) { | for (int i = 0; i < excludes.length; i++) { | ||||
| if (matchPath(excludes[i],name)) { | |||||
| if (matchPath(excludes[i],name, isCaseSensitive)) { | |||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| @@ -152,4 +152,11 @@ public interface FileScanner { | |||||
| * @param includes list of include patterns | * @param includes list of include patterns | ||||
| */ | */ | ||||
| void setIncludes(String[] includes); | void setIncludes(String[] includes); | ||||
| /** | |||||
| * Sets the case sensitivity of the file system | |||||
| * | |||||
| * @param specifies if the filesystem is case sensitive | |||||
| */ | |||||
| void setCaseSensitive(boolean isCaseSensitive); | |||||
| } | } | ||||
| @@ -421,11 +421,7 @@ public class ProjectHelper { | |||||
| // take care of dependencies | // take care of dependencies | ||||
| if (depends.length() > 0) { | if (depends.length() > 0) { | ||||
| StringTokenizer tok = | |||||
| new StringTokenizer(depends, ",", false); | |||||
| while (tok.hasMoreTokens()) { | |||||
| target.addDependency(tok.nextToken().trim()); | |||||
| } | |||||
| target.setDepends(depends); | |||||
| } | } | ||||
| } | } | ||||
| @@ -85,7 +85,10 @@ public class Target implements TaskContainer { | |||||
| StringTokenizer tok = | StringTokenizer tok = | ||||
| new StringTokenizer(depS, ",", false); | new StringTokenizer(depS, ",", false); | ||||
| while (tok.hasMoreTokens()) { | while (tok.hasMoreTokens()) { | ||||
| addDependency(tok.nextToken().trim()); | |||||
| String token = tok.nextToken().trim(); | |||||
| if (!token.equals("")) { | |||||
| addDependency(token); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -201,11 +201,7 @@ public class XmlLogger implements BuildListener { | |||||
| taskElement.startTime = System.currentTimeMillis(); | taskElement.startTime = System.currentTimeMillis(); | ||||
| taskElement.element = doc.createElement(TASK_TAG); | taskElement.element = doc.createElement(TASK_TAG); | ||||
| String name = task.getClass().getName(); | |||||
| int pos = name.lastIndexOf("."); | |||||
| if (pos != -1) { | |||||
| name = name.substring(pos + 1); | |||||
| } | |||||
| String name = event.getTask().getTaskName(); | |||||
| taskElement.element.setAttribute(NAME_ATTR, name); | taskElement.element.setAttribute(NAME_ATTR, name); | ||||
| taskElement.element.setAttribute(LOCATION_ATTR, event.getTask().getLocation().toString()); | taskElement.element.setAttribute(LOCATION_ATTR, event.getTask().getLocation().toString()); | ||||
| tasks.put(task, taskElement); | tasks.put(task, taskElement); | ||||
| @@ -80,28 +80,40 @@ import java.util.*; | |||||
| */ | */ | ||||
| public class Ant extends Task { | public class Ant extends Task { | ||||
| /** the basedir where is executed the build file */ | |||||
| private File dir = null; | private File dir = null; | ||||
| /** the build.xml file (can be absolute) in this case dir will be ignored */ | |||||
| private String antFile = null; | private String antFile = null; | ||||
| /** the target to call if any */ | |||||
| private String target = null; | private String target = null; | ||||
| /** the output */ | |||||
| private String output = null; | private String output = null; | ||||
| /** should we inherit properties from the parent ? */ | |||||
| private boolean inheritAll = true; | private boolean inheritAll = true; | ||||
| Vector properties = new Vector(); | |||||
| Project p1; | |||||
| /** the properties to pass to the new project */ | |||||
| private Vector properties = new Vector(); | |||||
| /** the temporary project created to run the build file */ | |||||
| private Project newProject; | |||||
| /** | /** | ||||
| * If true, inherit all properties from parent Project | * If true, inherit all properties from parent Project | ||||
| * If false, inherit only userProperties and those defined | * If false, inherit only userProperties and those defined | ||||
| * inside the ant call itself | * inside the ant call itself | ||||
| **/ | |||||
| public void setInheritAll(boolean inherit) { | |||||
| inheritAll = inherit; | |||||
| } //-- setInheritAll | |||||
| */ | |||||
| public void setInheritAll(boolean value) { | |||||
| inheritAll = value; | |||||
| } | |||||
| public void init() { | public void init() { | ||||
| p1 = new Project(); | |||||
| p1.setJavaVersionProperty(); | |||||
| p1.addTaskDefinition("property", | |||||
| newProject = new Project(); | |||||
| newProject.setJavaVersionProperty(); | |||||
| newProject.addTaskDefinition("property", | |||||
| (Class)project.getTaskDefinitions().get("property")); | (Class)project.getTaskDefinitions().get("property")); | ||||
| } | } | ||||
| @@ -109,7 +121,7 @@ public class Ant extends Task { | |||||
| init(); | init(); | ||||
| for (int i=0; i<properties.size(); i++) { | for (int i=0; i<properties.size(); i++) { | ||||
| Property p = (Property) properties.elementAt(i); | Property p = (Property) properties.elementAt(i); | ||||
| Property newP = (Property) p1.createTask("property"); | |||||
| Property newP = (Property) newProject.createTask("property"); | |||||
| newP.setName(p.getName()); | newP.setName(p.getName()); | ||||
| if (p.getValue() != null) { | if (p.getValue() != null) { | ||||
| newP.setValue(p.getValue()); | newP.setValue(p.getValue()); | ||||
| @@ -127,7 +139,7 @@ public class Ant extends Task { | |||||
| private void initializeProject() { | private void initializeProject() { | ||||
| Vector listeners = project.getBuildListeners(); | Vector listeners = project.getBuildListeners(); | ||||
| for (int i = 0; i < listeners.size(); i++) { | for (int i = 0; i < listeners.size(); i++) { | ||||
| p1.addBuildListener((BuildListener)listeners.elementAt(i)); | |||||
| newProject.addBuildListener((BuildListener)listeners.elementAt(i)); | |||||
| } | } | ||||
| if (output != null) { | if (output != null) { | ||||
| @@ -137,7 +149,7 @@ public class Ant extends Task { | |||||
| logger.setMessageOutputLevel(Project.MSG_INFO); | logger.setMessageOutputLevel(Project.MSG_INFO); | ||||
| logger.setOutputPrintStream(out); | logger.setOutputPrintStream(out); | ||||
| logger.setErrorPrintStream(out); | logger.setErrorPrintStream(out); | ||||
| p1.addBuildListener(logger); | |||||
| newProject.addBuildListener(logger); | |||||
| } | } | ||||
| catch( IOException ex ) { | catch( IOException ex ) { | ||||
| log( "Ant: Can't set output to " + output ); | log( "Ant: Can't set output to " + output ); | ||||
| @@ -149,7 +161,7 @@ public class Ant extends Task { | |||||
| while (et.hasMoreElements()) { | while (et.hasMoreElements()) { | ||||
| String taskName = (String) et.nextElement(); | String taskName = (String) et.nextElement(); | ||||
| Class taskClass = (Class) taskdefs.get(taskName); | Class taskClass = (Class) taskdefs.get(taskName); | ||||
| p1.addTaskDefinition(taskName, taskClass); | |||||
| newProject.addTaskDefinition(taskName, taskClass); | |||||
| } | } | ||||
| Hashtable typedefs = project.getDataTypeDefinitions(); | Hashtable typedefs = project.getDataTypeDefinitions(); | ||||
| @@ -157,7 +169,7 @@ public class Ant extends Task { | |||||
| while (e.hasMoreElements()) { | while (e.hasMoreElements()) { | ||||
| String typeName = (String) e.nextElement(); | String typeName = (String) e.nextElement(); | ||||
| Class typeClass = (Class) typedefs.get(typeName); | Class typeClass = (Class) typedefs.get(typeName); | ||||
| p1.addDataTypeDefinition(typeName, typeClass); | |||||
| newProject.addDataTypeDefinition(typeName, typeClass); | |||||
| } | } | ||||
| // set user-defined or all properties from calling project | // set user-defined or all properties from calling project | ||||
| @@ -170,23 +182,24 @@ public class Ant extends Task { | |||||
| // set Java built-in properties separately, | // set Java built-in properties separately, | ||||
| // b/c we won't inherit them. | // b/c we won't inherit them. | ||||
| p1.setSystemProperties(); | |||||
| newProject.setSystemProperties(); | |||||
| } | } | ||||
| e = prop1.keys(); | e = prop1.keys(); | ||||
| while (e.hasMoreElements()) { | while (e.hasMoreElements()) { | ||||
| String arg = (String) e.nextElement(); | String arg = (String) e.nextElement(); | ||||
| String value = (String) prop1.get(arg); | String value = (String) prop1.get(arg); | ||||
| if (inheritAll == true) | |||||
| p1.setProperty(arg, value); | |||||
| else | |||||
| p1.setUserProperty(arg, value); | |||||
| if (inheritAll == true){ | |||||
| newProject.setProperty(arg, value); | |||||
| } else { | |||||
| newProject.setUserProperty(arg, value); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| protected void handleOutput(String line) { | protected void handleOutput(String line) { | ||||
| if (p1 != null) { | |||||
| p1.demuxOutput(line, false); | |||||
| if (newProject != null) { | |||||
| newProject.demuxOutput(line, false); | |||||
| } | } | ||||
| else { | else { | ||||
| super.handleOutput(line); | super.handleOutput(line); | ||||
| @@ -194,8 +207,8 @@ public class Ant extends Task { | |||||
| } | } | ||||
| protected void handleErrorOutput(String line) { | protected void handleErrorOutput(String line) { | ||||
| if (p1 != null) { | |||||
| p1.demuxOutput(line, true); | |||||
| if (newProject != null) { | |||||
| newProject.demuxOutput(line, true); | |||||
| } | } | ||||
| else { | else { | ||||
| super.handleErrorOutput(line); | super.handleErrorOutput(line); | ||||
| @@ -207,17 +220,18 @@ public class Ant extends Task { | |||||
| */ | */ | ||||
| public void execute() throws BuildException { | public void execute() throws BuildException { | ||||
| try { | try { | ||||
| if (p1 == null) { | |||||
| if (newProject == null) { | |||||
| reinit(); | reinit(); | ||||
| } | } | ||||
| if(dir == null) | |||||
| if (dir == null) { | |||||
| dir = project.getBaseDir(); | dir = project.getBaseDir(); | ||||
| } | |||||
| initializeProject(); | initializeProject(); | ||||
| p1.setBaseDir(dir); | |||||
| p1.setUserProperty("basedir" , dir.getAbsolutePath()); | |||||
| newProject.setBaseDir(dir); | |||||
| newProject.setUserProperty("basedir" , dir.getAbsolutePath()); | |||||
| // Override with local-defined properties | // Override with local-defined properties | ||||
| Enumeration e = properties.elements(); | Enumeration e = properties.elements(); | ||||
| @@ -226,43 +240,59 @@ public class Ant extends Task { | |||||
| p.execute(); | p.execute(); | ||||
| } | } | ||||
| if (antFile == null) | |||||
| if (antFile == null) { | |||||
| antFile = "build.xml"; | antFile = "build.xml"; | ||||
| } | |||||
| File file = FileUtils.newFileUtils().resolveFile(dir, antFile); | File file = FileUtils.newFileUtils().resolveFile(dir, antFile); | ||||
| antFile = file.getAbsolutePath(); | antFile = file.getAbsolutePath(); | ||||
| p1.setUserProperty( "ant.file" , antFile ); | |||||
| ProjectHelper.configureProject(p1, new File(antFile)); | |||||
| newProject.setUserProperty( "ant.file" , antFile ); | |||||
| ProjectHelper.configureProject(newProject, new File(antFile)); | |||||
| if (target == null) { | if (target == null) { | ||||
| target = p1.getDefaultTarget(); | |||||
| target = newProject.getDefaultTarget(); | |||||
| } | } | ||||
| // Are we trying to call the target in which we are defined? | // Are we trying to call the target in which we are defined? | ||||
| if (p1.getBaseDir().equals(project.getBaseDir()) && | |||||
| p1.getProperty("ant.file").equals(project.getProperty("ant.file")) && | |||||
| if (newProject.getBaseDir().equals(project.getBaseDir()) && | |||||
| newProject.getProperty("ant.file").equals(project.getProperty("ant.file")) && | |||||
| getOwningTarget() != null && | getOwningTarget() != null && | ||||
| target.equals(this.getOwningTarget().getName())) { | target.equals(this.getOwningTarget().getName())) { | ||||
| throw new BuildException("ant task calling its own parent target"); | throw new BuildException("ant task calling its own parent target"); | ||||
| } | } | ||||
| p1.executeTarget(target); | |||||
| newProject.executeTarget(target); | |||||
| } finally { | } finally { | ||||
| // help the gc | // help the gc | ||||
| p1 = null; | |||||
| newProject = null; | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * ... | |||||
| */ | |||||
| public void setDir(File d) { | public void setDir(File d) { | ||||
| this.dir = d; | this.dir = d; | ||||
| } | } | ||||
| /** | |||||
| * set the build file, it can be either absolute or relative. | |||||
| * If it is absolute, <tt>dir</tt> will be ignored, if it is | |||||
| * relative it will be resolved relative to <tt>dir</tt>. | |||||
| */ | |||||
| public void setAntfile(String s) { | public void setAntfile(String s) { | ||||
| // @note: it is a string and not a file to handle relative/absolute | |||||
| // otherwise a relative file will be resolved based on the current | |||||
| // basedir. | |||||
| this.antFile = s; | this.antFile = s; | ||||
| } | } | ||||
| /** | |||||
| * set the target to execute. If none is defined it will | |||||
| * execute the default target of the build file | |||||
| */ | |||||
| public void setTarget(String s) { | public void setTarget(String s) { | ||||
| this.target = s; | this.target = s; | ||||
| } | } | ||||
| @@ -271,12 +301,12 @@ public class Ant extends Task { | |||||
| this.output = s; | this.output = s; | ||||
| } | } | ||||
| /** create a property to pass to the new project as a 'user property' */ | |||||
| public Property createProperty() { | public Property createProperty() { | ||||
| if (p1 == null) { | |||||
| if (newProject == null) { | |||||
| reinit(); | reinit(); | ||||
| } | } | ||||
| Property p=(Property)p1.createTask("property"); | |||||
| Property p=(Property)newProject.createTask("property"); | |||||
| p.setUserProperty(true); | p.setUserProperty(true); | ||||
| properties.addElement( p ); | properties.addElement( p ); | ||||
| return p; | return p; | ||||
| @@ -146,7 +146,7 @@ public class AntStructure extends Task { | |||||
| private void printHead(PrintWriter out, Enumeration tasks, | private void printHead(PrintWriter out, Enumeration tasks, | ||||
| Enumeration types) { | Enumeration types) { | ||||
| out.println("<?xml version=\"1.0\" ?>"); | |||||
| out.println("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); | |||||
| out.println("<!ENTITY % boolean \"(true|false|on|off|yes|no)\">"); | out.println("<!ENTITY % boolean \"(true|false|on|off|yes|no)\">"); | ||||
| out.print("<!ENTITY % tasks \""); | out.print("<!ENTITY % tasks \""); | ||||
| boolean first = true; | boolean first = true; | ||||
| @@ -141,20 +141,29 @@ public class Jar extends Zip { | |||||
| throws IOException, BuildException | throws IOException, BuildException | ||||
| { | { | ||||
| try { | try { | ||||
| // If no manifest is specified, add the default one. | |||||
| if (manifest == null) { | |||||
| execManifest = null; | |||||
| } | |||||
| else { | |||||
| execManifest = new Manifest(); | |||||
| execManifest = getDefaultManifest(); | |||||
| if (manifest != null) { | |||||
| execManifest.merge(manifest); | execManifest.merge(manifest); | ||||
| } | } | ||||
| for (Enumeration e = execManifest.getWarnings(); e.hasMoreElements(); ) { | |||||
| log("Manifest warning: " + (String)e.nextElement(), Project.MSG_WARN); | |||||
| } | |||||
| zipDir(null, zOut, "META-INF/"); | zipDir(null, zOut, "META-INF/"); | ||||
| // time to write the manifest | |||||
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |||||
| PrintWriter writer = new PrintWriter(baos); | |||||
| execManifest.write(writer); | |||||
| writer.flush(); | |||||
| ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); | |||||
| super.zipFile(bais, zOut, "META-INF/MANIFEST.MF", System.currentTimeMillis()); | |||||
| super.initZipOutputStream(zOut); | super.initZipOutputStream(zOut); | ||||
| } | } | ||||
| catch (ManifestException e) { | catch (ManifestException e) { | ||||
| log("Manifest is invalid: " + e.getMessage(), Project.MSG_ERR); | |||||
| throw new BuildException("Invalid Manifest", e, getLocation()); | |||||
| log("Manifest is invalid: " + e.getMessage(), Project.MSG_ERR); | |||||
| throw new BuildException("Invalid Manifest", e, getLocation()); | |||||
| } | } | ||||
| } | } | ||||
| @@ -175,28 +184,6 @@ public class Jar extends Zip { | |||||
| } | } | ||||
| } | } | ||||
| protected void finalizeZipOutputStream(ZipOutputStream zOut) | |||||
| throws IOException, BuildException { | |||||
| if (execManifest == null) { | |||||
| execManifest = getDefaultManifest(); | |||||
| } | |||||
| for (Enumeration e = execManifest.getWarnings(); e.hasMoreElements(); ) { | |||||
| log("Manifest warning: " + (String)e.nextElement(), Project.MSG_WARN); | |||||
| } | |||||
| // time to write the manifest | |||||
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |||||
| PrintWriter writer = new PrintWriter(baos); | |||||
| execManifest.write(writer); | |||||
| writer.flush(); | |||||
| ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); | |||||
| super.zipFile(bais, zOut, "META-INF/MANIFEST.MF", System.currentTimeMillis()); | |||||
| super.finalizeZipOutputStream(zOut); | |||||
| } | |||||
| /** | /** | ||||
| * Handle situation when we encounter a manifest file | * Handle situation when we encounter a manifest file | ||||
| * | * | ||||
| @@ -223,30 +210,17 @@ public class Jar extends Zip { | |||||
| protected void zipFile(File file, ZipOutputStream zOut, String vPath) | protected void zipFile(File file, ZipOutputStream zOut, String vPath) | ||||
| throws IOException | throws IOException | ||||
| { | { | ||||
| // If the file being added is META-INF/MANIFEST.MF, we merge it with the | |||||
| // current manifest | |||||
| // If the file being added is META-INF/MANIFEST.MF, we warn if it's not the | |||||
| // one specified in the "manifest" attribute - or if it's being added twice, | |||||
| // meaning the same file is specified by the "manifeset" attribute and in | |||||
| // a <fileset> element. | |||||
| if (vPath.equalsIgnoreCase("META-INF/MANIFEST.MF")) { | if (vPath.equalsIgnoreCase("META-INF/MANIFEST.MF")) { | ||||
| InputStream is = null; | |||||
| try { | |||||
| is = new FileInputStream(file); | |||||
| zipManifestEntry(is); | |||||
| } | |||||
| catch (IOException e) { | |||||
| throw new BuildException("Unable to read manifest file: " + file, e); | |||||
| } | |||||
| finally { | |||||
| if (is != null) { | |||||
| try { | |||||
| is.close(); | |||||
| } | |||||
| catch (IOException e) { | |||||
| // do nothing | |||||
| } | |||||
| } | |||||
| } | |||||
| log("Warning: selected "+archiveType+" files include a META-INF/MANIFEST.MF which will be ignored " + | |||||
| "(please use manifest attribute to "+archiveType+" task)", Project.MSG_WARN); | |||||
| } else { | } else { | ||||
| super.zipFile(file, zOut, vPath); | super.zipFile(file, zOut, vPath); | ||||
| } | } | ||||
| } | } | ||||
| protected void zipFile(InputStream is, ZipOutputStream zOut, String vPath, long lastModified) | protected void zipFile(InputStream is, ZipOutputStream zOut, String vPath, long lastModified) | ||||
| @@ -82,6 +82,7 @@ import java.io.File; | |||||
| * <li>failonerror | * <li>failonerror | ||||
| * <li>includeantruntime | * <li>includeantruntime | ||||
| * <li>includejavaruntime | * <li>includejavaruntime | ||||
| * <li>source | |||||
| * </ul> | * </ul> | ||||
| * Of these arguments, the <b>sourcedir</b> and <b>destdir</b> are required. | * Of these arguments, the <b>sourcedir</b> and <b>destdir</b> are required. | ||||
| * <p> | * <p> | ||||
| @@ -122,6 +123,24 @@ public class Javac extends MatchingTask { | |||||
| protected boolean failOnError = true; | protected boolean failOnError = true; | ||||
| protected File[] compileList = new File[0]; | protected File[] compileList = new File[0]; | ||||
| private String source; | |||||
| /** | |||||
| * Get the value of source. | |||||
| * @return value of source. | |||||
| */ | |||||
| public String getSource() { | |||||
| return source; | |||||
| } | |||||
| /** | |||||
| * Set the value of source. | |||||
| * @param v Value to assign to source. | |||||
| */ | |||||
| public void setSource(String v) { | |||||
| this.source = v; | |||||
| } | |||||
| /** | /** | ||||
| * Create a nested <src ...> element for multiple source path | * Create a nested <src ...> element for multiple source path | ||||
| * support. | * support. | ||||
| @@ -433,7 +452,15 @@ public class Javac extends MatchingTask { | |||||
| */ | */ | ||||
| public void setFork(boolean fork) | public void setFork(boolean fork) | ||||
| { | { | ||||
| this.fork = fork; | |||||
| this.fork = fork; | |||||
| } | |||||
| /** | |||||
| * Is this a forked invocation of JDK's javac? | |||||
| */ | |||||
| public boolean isForkedJavac() { | |||||
| return fork || | |||||
| "extJavac".equals(project.getProperty("build.compiler")); | |||||
| } | } | ||||
| @@ -489,8 +516,8 @@ public class Javac extends MatchingTask { | |||||
| String compiler = project.getProperty("build.compiler"); | String compiler = project.getProperty("build.compiler"); | ||||
| if (fork) { | |||||
| if (compiler != null) { | |||||
| if (fork) { | |||||
| if (compiler != null) { | |||||
| if (isJdkCompiler(compiler)) { | if (isJdkCompiler(compiler)) { | ||||
| log("Since fork is true, ignoring build.compiler setting.", | log("Since fork is true, ignoring build.compiler setting.", | ||||
| Project.MSG_WARN); | Project.MSG_WARN); | ||||
| @@ -499,13 +526,13 @@ public class Javac extends MatchingTask { | |||||
| else { | else { | ||||
| log("Since build.compiler setting isn't classic or modern, ignoring fork setting.", Project.MSG_WARN); | log("Since build.compiler setting isn't classic or modern, ignoring fork setting.", Project.MSG_WARN); | ||||
| } | } | ||||
| } | |||||
| } | |||||
| else { | else { | ||||
| compiler = "extJavac"; | compiler = "extJavac"; | ||||
| } | } | ||||
| } | |||||
| } | |||||
| if (compiler == null) { | |||||
| if (compiler == null) { | |||||
| if (Project.getJavaVersion() != Project.JAVA_1_1 && | if (Project.getJavaVersion() != Project.JAVA_1_1 && | ||||
| Project.getJavaVersion() != Project.JAVA_1_2) { | Project.getJavaVersion() != Project.JAVA_1_2) { | ||||
| compiler = "modern"; | compiler = "modern"; | ||||
| @@ -512,8 +512,13 @@ public class SQLExec extends Task { | |||||
| project.getProperties()); | project.getProperties()); | ||||
| if (line.startsWith("//")) continue; | if (line.startsWith("//")) continue; | ||||
| if (line.startsWith("--")) continue; | if (line.startsWith("--")) continue; | ||||
| if (line.length() > 2 && | |||||
| line.substring(0,3).equalsIgnoreCase("REM")) continue; | |||||
| StringTokenizer st = new StringTokenizer(line); | |||||
| if (st.hasMoreTokens()) { | |||||
| String token = st.nextToken(); | |||||
| if ("REM".equalsIgnoreCase(token)) { | |||||
| continue; | |||||
| } | |||||
| } | |||||
| sql += " " + line; | sql += " " + line; | ||||
| sql = sql.trim(); | sql = sql.trim(); | ||||
| @@ -216,11 +216,21 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { | |||||
| boolean usingJava1_1 = Project.getJavaVersion().equals(Project.JAVA_1_1); | boolean usingJava1_1 = Project.getJavaVersion().equals(Project.JAVA_1_1); | ||||
| String memoryParameterPrefix = usingJava1_1 ? "-J-" : "-J-X"; | String memoryParameterPrefix = usingJava1_1 ? "-J-" : "-J-X"; | ||||
| if (memoryInitialSize != null) { | if (memoryInitialSize != null) { | ||||
| cmd.createArgument().setValue(memoryParameterPrefix+"ms"+memoryInitialSize); | |||||
| if (!attributes.isForkedJavac()) { | |||||
| attributes.log("Since fork is false, ignoring memoryInitialSize setting.", | |||||
| Project.MSG_WARN); | |||||
| } else { | |||||
| cmd.createArgument().setValue(memoryParameterPrefix+"ms"+memoryInitialSize); | |||||
| } | |||||
| } | } | ||||
| if (memoryMaximumSize != null) { | if (memoryMaximumSize != null) { | ||||
| cmd.createArgument().setValue(memoryParameterPrefix+"mx"+memoryMaximumSize); | |||||
| if (!attributes.isForkedJavac()) { | |||||
| attributes.log("Since fork is false, ignoring memoryMaximumSize setting.", | |||||
| Project.MSG_WARN); | |||||
| } else { | |||||
| cmd.createArgument().setValue(memoryParameterPrefix+"mx"+memoryMaximumSize); | |||||
| } | |||||
| } | } | ||||
| if (attributes.getNowarn()) { | if (attributes.getNowarn()) { | ||||
| @@ -303,6 +313,23 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { | |||||
| return cmd; | return cmd; | ||||
| } | } | ||||
| /** | |||||
| * Does the command line argument processing common to classic and | |||||
| * modern and adds the files to compile as well. | |||||
| */ | |||||
| protected Commandline setupModernJavacCommand() { | |||||
| Commandline cmd = new Commandline(); | |||||
| setupJavacCommandlineSwitches(cmd); | |||||
| if (attributes.getSource() != null) { | |||||
| cmd.createArgument().setValue("-source"); | |||||
| cmd.createArgument().setValue(attributes.getSource()); | |||||
| } | |||||
| logAndAddFilesToCompile(cmd); | |||||
| return cmd; | |||||
| } | |||||
| /** | /** | ||||
| * Does the command line argument processing common to classic and | * Does the command line argument processing common to classic and | ||||
| * modern and adds the files to compile as well. | * modern and adds the files to compile as well. | ||||
| @@ -81,7 +81,7 @@ public class Javac13 extends DefaultCompilerAdapter { | |||||
| public boolean execute() throws BuildException { | public boolean execute() throws BuildException { | ||||
| attributes.log("Using modern compiler", Project.MSG_VERBOSE); | attributes.log("Using modern compiler", Project.MSG_VERBOSE); | ||||
| Commandline cmd = setupJavacCommand(); | |||||
| Commandline cmd = setupModernJavacCommand(); | |||||
| // Use reflection to be able to build on all JDKs >= 1.1: | // Use reflection to be able to build on all JDKs >= 1.1: | ||||
| try { | try { | ||||
| @@ -200,7 +200,7 @@ public class Cab extends MatchingTask { | |||||
| if (cmdOptions != null) | if (cmdOptions != null) | ||||
| { | { | ||||
| command.createArgument().setValue(cmdOptions); | |||||
| command.createArgument().setLine(cmdOptions); | |||||
| } | } | ||||
| command.createArgument().setValue("n"); | command.createArgument().setValue("n"); | ||||
| @@ -257,7 +257,7 @@ public class Depend extends MatchingTask { | |||||
| classFileInfoMap = new Hashtable(); | classFileInfoMap = new Hashtable(); | ||||
| boolean cacheDirty = false; | boolean cacheDirty = false; | ||||
| Hashtable dependencyMap = null; | |||||
| Hashtable dependencyMap = new Hashtable(); | |||||
| File depCacheFile = null; | File depCacheFile = null; | ||||
| boolean depCacheFileExists = true; | boolean depCacheFileExists = true; | ||||
| long depCacheFileLastModified = Long.MAX_VALUE; | long depCacheFileLastModified = Long.MAX_VALUE; | ||||
| @@ -806,12 +806,12 @@ public class FTP | |||||
| } | } | ||||
| if( ! ftp.makeDirectory( dir ) ) { | if( ! ftp.makeDirectory( dir ) ) { | ||||
| // Both codes 550 and 553 can be produced by FTP Servers | |||||
| // codes 521, 550 and 553 can be produced by FTP Servers | |||||
| // to indicate that an attempt to create a directory has | // to indicate that an attempt to create a directory has | ||||
| // failed because the directory already exists. | // failed because the directory already exists. | ||||
| int rc = ftp.getReplyCode(); | int rc = ftp.getReplyCode(); | ||||
| if( rc != 550 && rc != 553 && !ignoreNoncriticalErrors) { | |||||
| if( !(ignoreNoncriticalErrors && (rc == 550 || rc == 553 || rc==521))) { | |||||
| throw new BuildException( "could not create directory: " + | throw new BuildException( "could not create directory: " + | ||||
| ftp.getReplyString() ); | ftp.getReplyString() ); | ||||
| } | } | ||||
| @@ -84,303 +84,303 @@ import java.io.*; | |||||
| * @author <a href="sbailliez@imediation.com">Stephane Bailliez</a> | * @author <a href="sbailliez@imediation.com">Stephane Bailliez</a> | ||||
| */ | */ | ||||
| public class CovReport extends Task { | public class CovReport extends Task { | ||||
| /* | |||||
| jpcoverport [options] -output=file -snapshot=snapshot.jpc | |||||
| jpcovreport [options] [-paramfile=file] -output=<fileName> -snapshot=<fileName> | |||||
| Generate a report based on the indicated snapshot | |||||
| /* | |||||
| jpcoverport [options] -output=file -snapshot=snapshot.jpc | |||||
| jpcovreport [options] [-paramfile=file] -output=<fileName> -snapshot=<fileName> | |||||
| -paramfile=file | |||||
| A text file containing the report generation options. | |||||
| Generate a report based on the indicated snapshot | |||||
| -format=(html|text|xml) defaults to html | |||||
| The format of the generated report. | |||||
| -paramfile=file | |||||
| A text file containing the report generation options. | |||||
| -type=(executive|summary|detailed|verydetailed) defaults to detailed | |||||
| The type of report to be generated. For -format=xml, | |||||
| use -type=verydetailed to include source code lines. | |||||
| -format=(html|text|xml) defaults to html | |||||
| The format of the generated report. | |||||
| Note: A very detailed report can be VERY large. | |||||
| -type=(executive|summary|detailed|verydetailed) defaults to detailed | |||||
| The type of report to be generated. For -format=xml, | |||||
| use -type=verydetailed to include source code lines. | |||||
| -percent=num Min 1 Max 101 Default 101 | |||||
| An integer representing a percentage of coverage. | |||||
| Only methods with test case coverage less than the | |||||
| percentage are included in reports. | |||||
| Note: A very detailed report can be VERY large. | |||||
| -filters=string | |||||
| A comma-separated list of filters in the form | |||||
| <package>.<class>:V, where V can be I for Include or | |||||
| E for Exclude. For the default package, omit <package>. | |||||
| -percent=num Min 1 Max 101 Default 101 | |||||
| An integer representing a percentage of coverage. | |||||
| Only methods with test case coverage less than the | |||||
| percentage are included in reports. | |||||
| -filters_method=string | |||||
| Optional. A comma-separated list of methods that | |||||
| correspond one-to-one with the entries in -filters. | |||||
| -filters=string | |||||
| A comma-separated list of filters in the form | |||||
| <package>.<class>:V, where V can be I for Include or | |||||
| E for Exclude. For the default package, omit <package>. | |||||
| -output=string Must be specified | |||||
| The absolute path and file name for the generated | |||||
| report file. | |||||
| -filters_method=string | |||||
| Optional. A comma-separated list of methods that | |||||
| correspond one-to-one with the entries in -filters. | |||||
| -snapshot=string Must be specified | |||||
| The absolute path and file name of the snapshot file. | |||||
| -output=string Must be specified | |||||
| The absolute path and file name for the generated | |||||
| report file. | |||||
| -inc_src_text=(on|off) defaults to on | |||||
| Include text of the source code lines. | |||||
| Only applies for -format=xml and -type=verydetailed. | |||||
| -snapshot=string Must be specified | |||||
| The absolute path and file name of the snapshot file. | |||||
| -sourcepath=string defaults to . | |||||
| A semicolon-separated list of source paths. | |||||
| /* | |||||
| -inc_src_text=(on|off) defaults to on | |||||
| Include text of the source code lines. | |||||
| Only applies for -format=xml and -type=verydetailed. | |||||
| /** coverage home, mandatory */ | |||||
| private File home = null; | |||||
| /** format of generated report, optional */ | |||||
| private String format = null; | |||||
| /** the name of the output snapshot, mandatory */ | |||||
| private File tofile = null; | |||||
| /** type of report, optional */ | |||||
| private String type = null; | |||||
| /** threshold value for printing methods, optional */ | |||||
| private Integer percent = null; | |||||
| /** comma separated list of filters (???)*/ | |||||
| private String filters = null; | |||||
| /** name of the snapshot file to create report from */ | |||||
| private File snapshot = null; | |||||
| /** sourcepath to use */ | |||||
| private Path sourcePath = null; | |||||
| /** include the text for each line of code (xml report verydetailed)*/ | |||||
| private boolean includeSource = true; | |||||
| private Path coveragePath = null; | |||||
| /** */ | |||||
| private Reference reference = null; | |||||
| /** | |||||
| * Set the coverage home. it must point to JProbe coverage | |||||
| * directories where are stored native libraries and jars. | |||||
| */ | |||||
| public void setHome(File value) { | |||||
| this.home = value; | |||||
| } | |||||
| public static class ReportFormat extends EnumeratedAttribute { | |||||
| public String[] getValues(){ | |||||
| return new String[]{"html", "text", "xml"}; | |||||
| } | |||||
| } | |||||
| /** set the format of the report html|text|xml*/ | |||||
| public void setFormat(ReportFormat value){ | |||||
| this.format = value.getValue(); | |||||
| } | |||||
| public static class ReportType extends EnumeratedAttribute { | |||||
| public String[] getValues(){ | |||||
| return new String[]{"executive", "summary", "detailed", "verydetailed"}; | |||||
| } | |||||
| } | |||||
| /** sets the report type executive|summary|detailed|verydetailed */ | |||||
| public void setType(ReportType value){ | |||||
| this.type = value.getValue(); | |||||
| } | |||||
| /** include source code lines. XML report only */ | |||||
| public void setIncludesource(boolean value){ | |||||
| this.includeSource = value; | |||||
| } | |||||
| /** sets the threshold printing method 0-100*/ | |||||
| public void setPercent(Integer value){ | |||||
| this.percent = value; | |||||
| } | |||||
| /** set the filters */ | |||||
| public void setFilters(String values){ | |||||
| this.filters = values; | |||||
| } | |||||
| public Path createSourcepath(){ | |||||
| if (sourcePath == null) { | |||||
| sourcePath = new Path(project); | |||||
| } | |||||
| return sourcePath.createPath(); | |||||
| } | |||||
| public void setSnapshot(File value){ | |||||
| this.snapshot = value; | |||||
| } | |||||
| /** | |||||
| * Set the output snapshot file | |||||
| */ | |||||
| public void setTofile(File value) { | |||||
| this.tofile = value; | |||||
| } | |||||
| //@todo to remove | |||||
| public Path createCoveragepath(){ | |||||
| if (coveragePath == null) { | |||||
| coveragePath = new Path(project); | |||||
| } | |||||
| return coveragePath.createPath(); | |||||
| } | |||||
| public Reference createReference(){ | |||||
| if (reference == null){ | |||||
| reference = new Reference(); | |||||
| } | |||||
| return reference; | |||||
| } | |||||
| public CovReport() { | |||||
| } | |||||
| /** check for mandatory options */ | |||||
| protected void checkOptions() throws BuildException { | |||||
| if (tofile == null) { | |||||
| throw new BuildException("'tofile' attribute must be set."); | |||||
| } | |||||
| if (snapshot == null) { | |||||
| throw new BuildException("'snapshot' attribute must be set."); | |||||
| } | |||||
| if (home == null) { | |||||
| throw new BuildException("'home' attribute must be set to JProbe home directory"); | |||||
| } | |||||
| home = new File(home,"Coverage"); | |||||
| File jar = new File(home, "coverage.jar"); | |||||
| if (!jar.exists()) { | |||||
| throw new BuildException("Cannot find Coverage directory: " + home); | |||||
| } | |||||
| if (reference != null && !"xml".equals(format)){ | |||||
| log("Ignored reference. It cannot be used in non XML report."); | |||||
| reference = null; // nullify it so that there is no ambiguity | |||||
| } | |||||
| } | |||||
| public void execute() throws BuildException { | |||||
| checkOptions(); | |||||
| try { | |||||
| Commandline cmdl = new Commandline(); | |||||
| // we need to run Coverage from his directory due to dll/jar issues | |||||
| cmdl.setExecutable( new File(home, "jpcovreport").getAbsolutePath() ); | |||||
| String[] params = getParameters(); | |||||
| for (int i = 0; i < params.length; i++) { | |||||
| cmdl.createArgument().setValue(params[i]); | |||||
| } | |||||
| // use the custom handler for stdin issues | |||||
| LogStreamHandler handler = new LogStreamHandler(this,Project.MSG_INFO,Project.MSG_WARN); | |||||
| Execute exec = new Execute( handler ); | |||||
| log(cmdl.toString(), Project.MSG_VERBOSE); | |||||
| exec.setCommandline(cmdl.getCommandline()); | |||||
| int exitValue = exec.execute(); | |||||
| if (exitValue != 0) { | |||||
| throw new BuildException("JProbe Coverage Report failed (" + exitValue + ")"); | |||||
| } | |||||
| log("coveragePath: " + coveragePath, Project.MSG_VERBOSE); | |||||
| log("format: " + format, Project.MSG_VERBOSE); | |||||
| if (reference != null && "xml".equals(format)){ | |||||
| reference.createEnhancedXMLReport(); | |||||
| } | |||||
| } catch (IOException e){ | |||||
| throw new BuildException("Failed to execute JProbe Coverage Report.", e); | |||||
| } | |||||
| } | |||||
| protected String[] getParameters(){ | |||||
| Vector v = new Vector(); | |||||
| if (format != null) { | |||||
| v.addElement("-format=" + format); | |||||
| } | |||||
| if (type != null) { | |||||
| v.addElement("-type=" + type); | |||||
| } | |||||
| if (percent != null) { | |||||
| v.addElement("-percent=" + percent); | |||||
| } | |||||
| if (filters != null) { | |||||
| v.addElement("-filters=" + filters); | |||||
| } | |||||
| v.addElement("-output=" + project.resolveFile(tofile.getPath())); | |||||
| v.addElement("-snapshot=" + project.resolveFile(snapshot.getPath())); | |||||
| // as a default -sourcepath use . in JProbe, so use project . | |||||
| if (sourcePath == null) { | |||||
| sourcePath = new Path(project); | |||||
| sourcePath.createPath().setLocation(project.resolveFile(".")); | |||||
| } | |||||
| v.addElement("-sourcepath=" + sourcePath); | |||||
| if ("verydetailed".equalsIgnoreCase(format) && "xml".equalsIgnoreCase(type)) { | |||||
| v.addElement("-inc_src_text=" + (includeSource ? "on" : "off")); | |||||
| } | |||||
| String[] params = new String[v.size()]; | |||||
| v.copyInto(params); | |||||
| return params; | |||||
| } | |||||
| public class Reference { | |||||
| protected Path classPath; | |||||
| protected ReportFilters filters; | |||||
| public Path createClasspath(){ | |||||
| if (classPath == null) { | |||||
| classPath = new Path(project); | |||||
| } | |||||
| return classPath.createPath(); | |||||
| } | |||||
| public ReportFilters createFilters(){ | |||||
| if (filters == null){ | |||||
| filters = new ReportFilters(); | |||||
| } | |||||
| return filters; | |||||
| } | |||||
| protected void createEnhancedXMLReport() throws BuildException { | |||||
| // we need a classpath element | |||||
| if (classPath == null){ | |||||
| throw new BuildException("Need a 'classpath' element."); | |||||
| } | |||||
| // and a valid one... | |||||
| String[] paths = classPath.list(); | |||||
| if (paths.length == 0){ | |||||
| throw new BuildException("Coverage path is invalid. It does not contain any existing path."); | |||||
| } | |||||
| // and we need at least one filter include/exclude. | |||||
| if (filters == null || filters.size() == 0){ | |||||
| createFilters(); | |||||
| log("Adding default include filter to *.*()", Project.MSG_VERBOSE); | |||||
| ReportFilters.Include include = new ReportFilters.Include(); | |||||
| filters.addInclude( include ); | |||||
| } | |||||
| try { | |||||
| log("Creating enhanced XML report", Project.MSG_VERBOSE); | |||||
| XMLReport report = new XMLReport(CovReport.this, tofile); | |||||
| report.setReportFilters(filters); | |||||
| report.setJProbehome( new File(home.getParent()) ); | |||||
| Document doc = report.createDocument(paths); | |||||
| TransformerFactory tfactory = TransformerFactory.newInstance(); | |||||
| Transformer transformer = tfactory.newTransformer(); | |||||
| transformer.setOutputProperty(OutputKeys.INDENT, "yes"); | |||||
| transformer.setOutputProperty(OutputKeys.METHOD, "xml"); | |||||
| Source src = new DOMSource(doc); | |||||
| Result res = new StreamResult( "file:///" + tofile.toString() ); | |||||
| transformer.transform(src, res); | |||||
| } catch (Exception e){ | |||||
| throw new BuildException("Error while performing enhanced XML report from file " + tofile, e); | |||||
| } | |||||
| } | |||||
| } | |||||
| -sourcepath=string defaults to . | |||||
| A semicolon-separated list of source paths. | |||||
| /* | |||||
| /** coverage home, mandatory */ | |||||
| private File home = null; | |||||
| /** format of generated report, optional */ | |||||
| private String format = null; | |||||
| /** the name of the output snapshot, mandatory */ | |||||
| private File tofile = null; | |||||
| /** type of report, optional */ | |||||
| private String type = null; | |||||
| /** threshold value for printing methods, optional */ | |||||
| private Integer percent = null; | |||||
| /** comma separated list of filters (???)*/ | |||||
| private String filters = null; | |||||
| /** name of the snapshot file to create report from */ | |||||
| private File snapshot = null; | |||||
| /** sourcepath to use */ | |||||
| private Path sourcePath = null; | |||||
| /** include the text for each line of code (xml report verydetailed)*/ | |||||
| private boolean includeSource = true; | |||||
| private Path coveragePath = null; | |||||
| /** */ | |||||
| private Reference reference = null; | |||||
| /** | |||||
| * Set the coverage home. it must point to JProbe coverage | |||||
| * directories where are stored native libraries and jars. | |||||
| */ | |||||
| public void setHome(File value) { | |||||
| this.home = value; | |||||
| } | |||||
| public static class ReportFormat extends EnumeratedAttribute { | |||||
| public String[] getValues(){ | |||||
| return new String[]{"html", "text", "xml"}; | |||||
| } | |||||
| } | |||||
| /** set the format of the report html|text|xml*/ | |||||
| public void setFormat(ReportFormat value){ | |||||
| this.format = value.getValue(); | |||||
| } | |||||
| public static class ReportType extends EnumeratedAttribute { | |||||
| public String[] getValues(){ | |||||
| return new String[]{"executive", "summary", "detailed", "verydetailed"}; | |||||
| } | |||||
| } | |||||
| /** sets the report type executive|summary|detailed|verydetailed */ | |||||
| public void setType(ReportType value){ | |||||
| this.type = value.getValue(); | |||||
| } | |||||
| /** include source code lines. XML report only */ | |||||
| public void setIncludesource(boolean value){ | |||||
| this.includeSource = value; | |||||
| } | |||||
| /** sets the threshold printing method 0-100*/ | |||||
| public void setPercent(Integer value){ | |||||
| this.percent = value; | |||||
| } | |||||
| /** set the filters */ | |||||
| public void setFilters(String values){ | |||||
| this.filters = values; | |||||
| } | |||||
| public Path createSourcepath(){ | |||||
| if (sourcePath == null) { | |||||
| sourcePath = new Path(project); | |||||
| } | |||||
| return sourcePath.createPath(); | |||||
| } | |||||
| public void setSnapshot(File value){ | |||||
| this.snapshot = value; | |||||
| } | |||||
| /** | |||||
| * Set the output snapshot file | |||||
| */ | |||||
| public void setTofile(File value) { | |||||
| this.tofile = value; | |||||
| } | |||||
| //@todo to remove | |||||
| public Path createCoveragepath(){ | |||||
| if (coveragePath == null) { | |||||
| coveragePath = new Path(project); | |||||
| } | |||||
| return coveragePath.createPath(); | |||||
| } | |||||
| public Reference createReference(){ | |||||
| if (reference == null){ | |||||
| reference = new Reference(); | |||||
| } | |||||
| return reference; | |||||
| } | |||||
| public CovReport() { | |||||
| } | |||||
| /** check for mandatory options */ | |||||
| protected void checkOptions() throws BuildException { | |||||
| if (tofile == null) { | |||||
| throw new BuildException("'tofile' attribute must be set."); | |||||
| } | |||||
| if (snapshot == null) { | |||||
| throw new BuildException("'snapshot' attribute must be set."); | |||||
| } | |||||
| if (home == null) { | |||||
| throw new BuildException("'home' attribute must be set to JProbe home directory"); | |||||
| } | |||||
| home = new File(home,"Coverage"); | |||||
| File jar = new File(home, "coverage.jar"); | |||||
| if (!jar.exists()) { | |||||
| throw new BuildException("Cannot find Coverage directory: " + home); | |||||
| } | |||||
| if (reference != null && !"xml".equals(format)){ | |||||
| log("Ignored reference. It cannot be used in non XML report."); | |||||
| reference = null; // nullify it so that there is no ambiguity | |||||
| } | |||||
| } | |||||
| public void execute() throws BuildException { | |||||
| checkOptions(); | |||||
| try { | |||||
| Commandline cmdl = new Commandline(); | |||||
| // we need to run Coverage from his directory due to dll/jar issues | |||||
| cmdl.setExecutable( new File(home, "jpcovreport").getAbsolutePath() ); | |||||
| String[] params = getParameters(); | |||||
| for (int i = 0; i < params.length; i++) { | |||||
| cmdl.createArgument().setValue(params[i]); | |||||
| } | |||||
| // use the custom handler for stdin issues | |||||
| LogStreamHandler handler = new LogStreamHandler(this,Project.MSG_INFO,Project.MSG_WARN); | |||||
| Execute exec = new Execute( handler ); | |||||
| log(cmdl.toString(), Project.MSG_VERBOSE); | |||||
| exec.setCommandline(cmdl.getCommandline()); | |||||
| int exitValue = exec.execute(); | |||||
| if (exitValue != 0) { | |||||
| throw new BuildException("JProbe Coverage Report failed (" + exitValue + ")"); | |||||
| } | |||||
| log("coveragePath: " + coveragePath, Project.MSG_VERBOSE); | |||||
| log("format: " + format, Project.MSG_VERBOSE); | |||||
| if (reference != null && "xml".equals(format)){ | |||||
| reference.createEnhancedXMLReport(); | |||||
| } | |||||
| } catch (IOException e){ | |||||
| throw new BuildException("Failed to execute JProbe Coverage Report.", e); | |||||
| } | |||||
| } | |||||
| protected String[] getParameters(){ | |||||
| Vector v = new Vector(); | |||||
| if (format != null) { | |||||
| v.addElement("-format=" + format); | |||||
| } | |||||
| if (type != null) { | |||||
| v.addElement("-type=" + type); | |||||
| } | |||||
| if (percent != null) { | |||||
| v.addElement("-percent=" + percent); | |||||
| } | |||||
| if (filters != null) { | |||||
| v.addElement("-filters=" + filters); | |||||
| } | |||||
| v.addElement("-output=" + project.resolveFile(tofile.getPath())); | |||||
| v.addElement("-snapshot=" + project.resolveFile(snapshot.getPath())); | |||||
| // as a default -sourcepath use . in JProbe, so use project . | |||||
| if (sourcePath == null) { | |||||
| sourcePath = new Path(project); | |||||
| sourcePath.createPath().setLocation(project.resolveFile(".")); | |||||
| } | |||||
| v.addElement("-sourcepath=" + sourcePath); | |||||
| if ("verydetailed".equalsIgnoreCase(format) && "xml".equalsIgnoreCase(type)) { | |||||
| v.addElement("-inc_src_text=" + (includeSource ? "on" : "off")); | |||||
| } | |||||
| String[] params = new String[v.size()]; | |||||
| v.copyInto(params); | |||||
| return params; | |||||
| } | |||||
| public class Reference { | |||||
| protected Path classPath; | |||||
| protected ReportFilters filters; | |||||
| public Path createClasspath(){ | |||||
| if (classPath == null) { | |||||
| classPath = new Path(CovReport.this.project); | |||||
| } | |||||
| return classPath.createPath(); | |||||
| } | |||||
| public ReportFilters createFilters(){ | |||||
| if (filters == null){ | |||||
| filters = new ReportFilters(); | |||||
| } | |||||
| return filters; | |||||
| } | |||||
| protected void createEnhancedXMLReport() throws BuildException { | |||||
| // we need a classpath element | |||||
| if (classPath == null){ | |||||
| throw new BuildException("Need a 'classpath' element."); | |||||
| } | |||||
| // and a valid one... | |||||
| String[] paths = classPath.list(); | |||||
| if (paths.length == 0){ | |||||
| throw new BuildException("Coverage path is invalid. It does not contain any existing path."); | |||||
| } | |||||
| // and we need at least one filter include/exclude. | |||||
| if (filters == null || filters.size() == 0){ | |||||
| createFilters(); | |||||
| log("Adding default include filter to *.*()", Project.MSG_VERBOSE); | |||||
| ReportFilters.Include include = new ReportFilters.Include(); | |||||
| filters.addInclude( include ); | |||||
| } | |||||
| try { | |||||
| log("Creating enhanced XML report", Project.MSG_VERBOSE); | |||||
| XMLReport report = new XMLReport(CovReport.this, tofile); | |||||
| report.setReportFilters(filters); | |||||
| report.setJProbehome( new File(home.getParent()) ); | |||||
| Document doc = report.createDocument(paths); | |||||
| TransformerFactory tfactory = TransformerFactory.newInstance(); | |||||
| Transformer transformer = tfactory.newTransformer(); | |||||
| transformer.setOutputProperty(OutputKeys.INDENT, "yes"); | |||||
| transformer.setOutputProperty(OutputKeys.METHOD, "xml"); | |||||
| Source src = new DOMSource(doc); | |||||
| Result res = new StreamResult( "file:///" + tofile.toString() ); | |||||
| transformer.transform(src, res); | |||||
| } catch (Exception e){ | |||||
| throw new BuildException("Error while performing enhanced XML report from file " + tofile, e); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -72,6 +72,7 @@ import java.util.Vector; | |||||
| * @author Sam Ruby <a href="mailto:rubys@us.ibm.com">rubys@us.ibm.com</a> | * @author Sam Ruby <a href="mailto:rubys@us.ibm.com">rubys@us.ibm.com</a> | ||||
| * @author Jon S. Stevens <a href="mailto:jon@clearink.com">jon@clearink.com</a> | * @author Jon S. Stevens <a href="mailto:jon@clearink.com">jon@clearink.com</a> | ||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | ||||
| * @author <a href="mailto:umagesh@rediffmail.com">Magesh Umasankar</a> | |||||
| */ | */ | ||||
| public class FileSet extends DataType { | public class FileSet extends DataType { | ||||
| @@ -80,6 +81,7 @@ public class FileSet extends DataType { | |||||
| private File dir; | private File dir; | ||||
| private boolean useDefaultExcludes = true; | private boolean useDefaultExcludes = true; | ||||
| private boolean isCaseSensitive = true; | |||||
| public FileSet() { | public FileSet() { | ||||
| super(); | super(); | ||||
| @@ -90,6 +92,7 @@ public class FileSet extends DataType { | |||||
| this.defaultPatterns = fileset.defaultPatterns; | this.defaultPatterns = fileset.defaultPatterns; | ||||
| this.additionalPatterns = fileset.additionalPatterns; | this.additionalPatterns = fileset.additionalPatterns; | ||||
| this.useDefaultExcludes = fileset.useDefaultExcludes; | this.useDefaultExcludes = fileset.useDefaultExcludes; | ||||
| this.isCaseSensitive = fileset.isCaseSensitive; | |||||
| } | } | ||||
| @@ -244,6 +247,16 @@ public class FileSet extends DataType { | |||||
| this.useDefaultExcludes = useDefaultExcludes; | this.useDefaultExcludes = useDefaultExcludes; | ||||
| } | } | ||||
| /** | |||||
| * Sets case sensitivity of the file system | |||||
| * | |||||
| * @param isCaseSensitive "true"|"on"|"yes" if file system is case | |||||
| * sensitive, "false"|"off"|"no" when not. | |||||
| */ | |||||
| public void setCaseSensitive(boolean isCaseSensitive) { | |||||
| this.isCaseSensitive = isCaseSensitive; | |||||
| } | |||||
| /** | /** | ||||
| * Returns the directory scanner needed to access the files to process. | * Returns the directory scanner needed to access the files to process. | ||||
| */ | */ | ||||
| @@ -287,6 +300,7 @@ public class FileSet extends DataType { | |||||
| ds.setIncludes(defaultPatterns.getIncludePatterns(p)); | ds.setIncludes(defaultPatterns.getIncludePatterns(p)); | ||||
| ds.setExcludes(defaultPatterns.getExcludePatterns(p)); | ds.setExcludes(defaultPatterns.getExcludePatterns(p)); | ||||
| if (useDefaultExcludes) ds.addDefaultExcludes(); | if (useDefaultExcludes) ds.addDefaultExcludes(); | ||||
| ds.setCaseSensitive(isCaseSensitive); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -72,7 +72,7 @@ import org.apache.tools.ant.Task; | |||||
| /** | /** | ||||
| * A set of filters to be applied to something. | * A set of filters to be applied to something. | ||||
| * | * | ||||
| * A filter set may have starttoken and endtokens defined. | |||||
| * A filter set may have begintoken and endtokens defined. | |||||
| * | * | ||||
| * @author <A href="mailto:gholam@xtra.co.nz"> Michael McCallum </A> | * @author <A href="mailto:gholam@xtra.co.nz"> Michael McCallum </A> | ||||
| * @created 14 March 2001 | * @created 14 March 2001 | ||||
| @@ -324,7 +324,7 @@ public class FilterSet extends DataType { | |||||
| /** | /** | ||||
| * Does replacement on the given string with token matching. | * Does replacement on the given string with token matching. | ||||
| * This uses the defined starttoken and endtoken values which default to @ for both. | |||||
| * This uses the defined begintoken and endtoken values which default to @ for both. | |||||
| * | * | ||||
| * @param line The line to process the tokens in. | * @param line The line to process the tokens in. | ||||
| * @return The string with the tokens replaced. | * @return The string with the tokens replaced. | ||||
| @@ -93,7 +93,7 @@ public class FilterSetCollection { | |||||
| /** | /** | ||||
| * Does replacement on the given string with token matching. | * Does replacement on the given string with token matching. | ||||
| * This uses the defined starttoken and endtoken values which default to @ for both. | |||||
| * This uses the defined begintoken and endtoken values which default to @ for both. | |||||
| * | * | ||||
| * @param line The line to process the tokens in. | * @param line The line to process the tokens in. | ||||
| * @return The string with the tokens replaced. | * @return The string with the tokens replaced. | ||||
| @@ -74,11 +74,14 @@ public class SourceFileScanner { | |||||
| protected Task task; | protected Task task; | ||||
| private FileUtils fileUtils; | |||||
| /** | /** | ||||
| * @param task The task we should log messages through | * @param task The task we should log messages through | ||||
| */ | */ | ||||
| public SourceFileScanner(Task task) { | public SourceFileScanner(Task task) { | ||||
| this.task = task; | this.task = task; | ||||
| fileUtils = FileUtils.newFileUtils(); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -118,7 +121,7 @@ public class SourceFileScanner { | |||||
| continue; | continue; | ||||
| } | } | ||||
| File src = new File(srcDir, files[i]); | |||||
| File src = fileUtils.resolveFile(srcDir, files[i]); | |||||
| if (src.lastModified() > now) { | if (src.lastModified() > now) { | ||||
| task.log("Warning: "+files[i]+" modified in the future.", | task.log("Warning: "+files[i]+" modified in the future.", | ||||
| Project.MSG_WARN); | Project.MSG_WARN); | ||||
| @@ -131,7 +134,7 @@ public class SourceFileScanner { | |||||
| if (destDir == null) { | if (destDir == null) { | ||||
| dest = new File(targets[j]); | dest = new File(targets[j]); | ||||
| } else { | } else { | ||||
| dest = new File(destDir, targets[j]); | |||||
| dest = fileUtils.resolveFile(destDir, targets[j]); | |||||
| } | } | ||||
| if (!dest.exists()) { | if (!dest.exists()) { | ||||