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: | |||
| -------------------------------------------- | |||
| @@ -20,6 +20,49 @@ Fixed bugs: | |||
| * Fixed bug where ant would not copy system properties into new Project | |||
| 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 | |||
| =========================================== | |||
| @@ -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 | |||
| full build. The Junit extensions such as | |||
| <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 | |||
| 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 | |||
| @@ -659,10 +659,16 @@ Faster compiles with Jikes | |||
| </b><dd> | |||
| 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> | |||
| #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 | |||
| 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 | |||
| project</h3> | |||
| @@ -988,4 +1013,4 @@ instead. | |||
| <hr> | |||
| <p align="center">Copyright © 2000, 2001 Apache Software Foundation. All rights | |||
| Reserved.</p> | |||
| </body> | |||
| </body> | |||
| @@ -166,7 +166,7 @@ the command line.</p> | |||
| <blockquote><pre> | |||
| <apply executable="somecommand" parallel="false" > | |||
| <arg value="arg1"/> | |||
| <srfile/> | |||
| <srcfile/> | |||
| <arg value="arg2"/> | |||
| <fileset dir="/tmp"/> | |||
| </apply> | |||
| @@ -215,6 +215,15 @@ files/directories from the CLASSPATH it passes to the compiler.</p> | |||
| </td> | |||
| <td align="center" valign="top">No</td> | |||
| </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> | |||
| <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> | |||
| 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 | |||
| 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 | |||
| @@ -129,6 +129,12 @@ on the same schema.</p> | |||
| <td valign="top" align="center">Yes, unless statements enclosed within tags</td> | |||
| </tr> | |||
| </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> | |||
| <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 | |||
| @@ -205,6 +211,25 @@ operation on <i>some_other_table</i>.</p> | |||
| </sql> | |||
| </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 | |||
| org.database.jdbcDriver and executes the SQL statements contained within the | |||
| 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> | |||
| <td valign="top" align="center">No</td> | |||
| </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> | |||
| <h4>Examples</h4> | |||
| <blockquote><pre> | |||
| <fileset dir="${server.src}" > | |||
| <fileset dir="${server.src}" casesensitive="yes" > | |||
| <patternset id="non.test.sources" > | |||
| <include name="**/*.java"/> | |||
| <exclude name="**/*Test*"/> | |||
| @@ -28,7 +28,7 @@ replacements in tasks like copy etc.<BR> | |||
| <TD vAlign=top align="center"><B>Required</B></TD> | |||
| </TR> | |||
| <TR> | |||
| <TD vAlign=top>starttoken</TD> | |||
| <TD vAlign=top>begintoken</TD> | |||
| <TD vAlign=top>The string marking the beginning of a token. eg | |||
| <STRONG>@</STRONG>Date@</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 | |||
| but wish to replace the token @DATE@ with todays date.</p> | |||
| <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> | |||
| <filter token="DATE" value="${DATE}"/> | |||
| </filterset> | |||
| @@ -533,20 +533,6 @@ include: </p> | |||
| <li>TOPLink for WebLogic 2.5.1-enabled entity beans</li> | |||
| </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 | |||
| 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 | |||
| 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> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| @@ -605,6 +660,12 @@ a message is logged that the jar file is up to date.</p> | |||
| deployment elements have been specified).</td> | |||
| <td valign="top" align="center">Yes</td> | |||
| </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> | |||
| <td valign="top">basejarname</td> | |||
| <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 | |||
| * there is a parent directory called test (e.g. "abc\test\def\ghi\XYZ123"). | |||
| * <p> | |||
| * Case sensitivity may be turned off if necessary. By default, it is | |||
| * turned on. | |||
| * <p> | |||
| * Example of usage: | |||
| * <pre> | |||
| * String[] includes = {"**\\*.class"}; | |||
| @@ -120,6 +123,7 @@ import java.util.*; | |||
| * ds.setIncludes(includes); | |||
| * ds.setExcludes(excludes); | |||
| * ds.setBasedir(new File("test")); | |||
| * ds.setCaseSensitive(true); | |||
| * ds.scan(); | |||
| * | |||
| * System.out.println("FILES:"); | |||
| @@ -132,6 +136,7 @@ import java.util.*; | |||
| * .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 <a href="mailto:umagesh@rediffmail.com">Magesh Umasankar</a> | |||
| */ | |||
| public class DirectoryScanner implements FileScanner { | |||
| @@ -207,6 +212,11 @@ public class DirectoryScanner implements FileScanner { | |||
| */ | |||
| protected boolean haveSlowResults = false; | |||
| /** | |||
| * Should the file system be treated as a case sensitive one? | |||
| */ | |||
| protected boolean isCaseSensitive = true; | |||
| /** | |||
| * Constructor. | |||
| */ | |||
| @@ -216,7 +226,7 @@ public class DirectoryScanner implements FileScanner { | |||
| /** | |||
| * 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> | |||
| * | |||
| @@ -226,6 +236,23 @@ public class DirectoryScanner implements FileScanner { | |||
| * @param str the (non-null) string (path) to match | |||
| */ | |||
| 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 | |||
| // File.separator. | |||
| // 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("**")) { | |||
| break; | |||
| } | |||
| if (!match(patDir,(String)strDirs.elementAt(strIdxStart))) { | |||
| if (!match(patDir,(String)strDirs.elementAt(strIdxStart), isCaseSensitive)) { | |||
| return false; | |||
| } | |||
| patIdxStart++; | |||
| @@ -288,6 +315,20 @@ public class DirectoryScanner implements FileScanner { | |||
| * <code>false</code> otherwise. | |||
| */ | |||
| 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 | |||
| // File.separator. | |||
| // 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("**")) { | |||
| break; | |||
| } | |||
| if (!match(patDir,(String)strDirs.elementAt(strIdxStart))) { | |||
| if (!match(patDir,(String)strDirs.elementAt(strIdxStart), isCaseSensitive)) { | |||
| return false; | |||
| } | |||
| patIdxStart++; | |||
| @@ -347,7 +388,7 @@ public class DirectoryScanner implements FileScanner { | |||
| if (patDir.equals("**")) { | |||
| break; | |||
| } | |||
| if (!match(patDir,(String)strDirs.elementAt(strIdxEnd))) { | |||
| if (!match(patDir,(String)strDirs.elementAt(strIdxEnd), isCaseSensitive)) { | |||
| return false; | |||
| } | |||
| patIdxEnd--; | |||
| @@ -386,7 +427,7 @@ strLoop: | |||
| for (int j = 0; j < patLength; j++) { | |||
| String subPat = (String)patDirs.elementAt(patIdxStart+j+1); | |||
| String subStr = (String)strDirs.elementAt(strIdxStart+i+j); | |||
| if (!match(subPat,subStr)) { | |||
| if (!match(subPat,subStr, isCaseSensitive)) { | |||
| continue strLoop; | |||
| } | |||
| } | |||
| @@ -413,7 +454,6 @@ strLoop: | |||
| } | |||
| /** | |||
| * Matches a string against a pattern. The pattern contains two special | |||
| * characters: | |||
| @@ -428,6 +468,24 @@ strLoop: | |||
| * <code>false</code> otherwise. | |||
| */ | |||
| 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[] strArr = str.toCharArray(); | |||
| int patIdxStart = 0; | |||
| @@ -451,21 +509,33 @@ strLoop: | |||
| } | |||
| for (int i = 0; i <= patIdxEnd; 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 | |||
| } | |||
| if (patIdxEnd == 0) { | |||
| return true; // Pattern contains only '*', which matches anything | |||
| } | |||
| // Process characters before first star | |||
| 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++; | |||
| strIdxStart++; | |||
| @@ -483,8 +553,14 @@ strLoop: | |||
| // Process characters after last star | |||
| 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--; | |||
| strIdxEnd--; | |||
| @@ -520,12 +596,18 @@ strLoop: | |||
| int patLength = (patIdxTmp-patIdxStart-1); | |||
| int strLength = (strIdxEnd-strIdxStart+1); | |||
| int foundIdx = -1; | |||
| strLoop: | |||
| strLoop: | |||
| for (int i = 0; i <= strLength - patLength; i++) { | |||
| for (int j = 0; j < patLength; j++) { | |||
| 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 | |||
| * replaced by <code>File.separatorChar</code>. So the separator used need | |||
| @@ -808,7 +899,7 @@ strLoop: | |||
| */ | |||
| protected boolean isIncluded(String name) { | |||
| for (int i = 0; i < includes.length; i++) { | |||
| if (matchPath(includes[i],name)) { | |||
| if (matchPath(includes[i],name, isCaseSensitive)) { | |||
| return true; | |||
| } | |||
| } | |||
| @@ -824,7 +915,7 @@ strLoop: | |||
| */ | |||
| protected boolean couldHoldIncluded(String name) { | |||
| for (int i = 0; i < includes.length; i++) { | |||
| if (matchPatternStart(includes[i],name)) { | |||
| if (matchPatternStart(includes[i],name, isCaseSensitive)) { | |||
| return true; | |||
| } | |||
| } | |||
| @@ -840,7 +931,7 @@ strLoop: | |||
| */ | |||
| protected boolean isExcluded(String name) { | |||
| for (int i = 0; i < excludes.length; i++) { | |||
| if (matchPath(excludes[i],name)) { | |||
| if (matchPath(excludes[i],name, isCaseSensitive)) { | |||
| return true; | |||
| } | |||
| } | |||
| @@ -152,4 +152,11 @@ public interface FileScanner { | |||
| * @param includes list of include patterns | |||
| */ | |||
| 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 | |||
| 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 = | |||
| new StringTokenizer(depS, ",", false); | |||
| 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.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(LOCATION_ATTR, event.getTask().getLocation().toString()); | |||
| tasks.put(task, taskElement); | |||
| @@ -80,28 +80,40 @@ import java.util.*; | |||
| */ | |||
| public class Ant extends Task { | |||
| /** the basedir where is executed the build file */ | |||
| private File dir = null; | |||
| /** the build.xml file (can be absolute) in this case dir will be ignored */ | |||
| private String antFile = null; | |||
| /** the target to call if any */ | |||
| private String target = null; | |||
| /** the output */ | |||
| private String output = null; | |||
| /** should we inherit properties from the parent ? */ | |||
| 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 false, inherit only userProperties and those defined | |||
| * inside the ant call itself | |||
| **/ | |||
| public void setInheritAll(boolean inherit) { | |||
| inheritAll = inherit; | |||
| } //-- setInheritAll | |||
| */ | |||
| public void setInheritAll(boolean value) { | |||
| inheritAll = value; | |||
| } | |||
| public void init() { | |||
| p1 = new Project(); | |||
| p1.setJavaVersionProperty(); | |||
| p1.addTaskDefinition("property", | |||
| newProject = new Project(); | |||
| newProject.setJavaVersionProperty(); | |||
| newProject.addTaskDefinition("property", | |||
| (Class)project.getTaskDefinitions().get("property")); | |||
| } | |||
| @@ -109,7 +121,7 @@ public class Ant extends Task { | |||
| init(); | |||
| for (int i=0; i<properties.size(); i++) { | |||
| Property p = (Property) properties.elementAt(i); | |||
| Property newP = (Property) p1.createTask("property"); | |||
| Property newP = (Property) newProject.createTask("property"); | |||
| newP.setName(p.getName()); | |||
| if (p.getValue() != null) { | |||
| newP.setValue(p.getValue()); | |||
| @@ -127,7 +139,7 @@ public class Ant extends Task { | |||
| private void initializeProject() { | |||
| Vector listeners = project.getBuildListeners(); | |||
| for (int i = 0; i < listeners.size(); i++) { | |||
| p1.addBuildListener((BuildListener)listeners.elementAt(i)); | |||
| newProject.addBuildListener((BuildListener)listeners.elementAt(i)); | |||
| } | |||
| if (output != null) { | |||
| @@ -137,7 +149,7 @@ public class Ant extends Task { | |||
| logger.setMessageOutputLevel(Project.MSG_INFO); | |||
| logger.setOutputPrintStream(out); | |||
| logger.setErrorPrintStream(out); | |||
| p1.addBuildListener(logger); | |||
| newProject.addBuildListener(logger); | |||
| } | |||
| catch( IOException ex ) { | |||
| log( "Ant: Can't set output to " + output ); | |||
| @@ -149,7 +161,7 @@ public class Ant extends Task { | |||
| while (et.hasMoreElements()) { | |||
| String taskName = (String) et.nextElement(); | |||
| Class taskClass = (Class) taskdefs.get(taskName); | |||
| p1.addTaskDefinition(taskName, taskClass); | |||
| newProject.addTaskDefinition(taskName, taskClass); | |||
| } | |||
| Hashtable typedefs = project.getDataTypeDefinitions(); | |||
| @@ -157,7 +169,7 @@ public class Ant extends Task { | |||
| while (e.hasMoreElements()) { | |||
| String typeName = (String) e.nextElement(); | |||
| Class typeClass = (Class) typedefs.get(typeName); | |||
| p1.addDataTypeDefinition(typeName, typeClass); | |||
| newProject.addDataTypeDefinition(typeName, typeClass); | |||
| } | |||
| // set user-defined or all properties from calling project | |||
| @@ -170,23 +182,24 @@ public class Ant extends Task { | |||
| // set Java built-in properties separately, | |||
| // b/c we won't inherit them. | |||
| p1.setSystemProperties(); | |||
| newProject.setSystemProperties(); | |||
| } | |||
| e = prop1.keys(); | |||
| while (e.hasMoreElements()) { | |||
| String arg = (String) e.nextElement(); | |||
| 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) { | |||
| if (p1 != null) { | |||
| p1.demuxOutput(line, false); | |||
| if (newProject != null) { | |||
| newProject.demuxOutput(line, false); | |||
| } | |||
| else { | |||
| super.handleOutput(line); | |||
| @@ -194,8 +207,8 @@ public class Ant extends Task { | |||
| } | |||
| protected void handleErrorOutput(String line) { | |||
| if (p1 != null) { | |||
| p1.demuxOutput(line, true); | |||
| if (newProject != null) { | |||
| newProject.demuxOutput(line, true); | |||
| } | |||
| else { | |||
| super.handleErrorOutput(line); | |||
| @@ -207,17 +220,18 @@ public class Ant extends Task { | |||
| */ | |||
| public void execute() throws BuildException { | |||
| try { | |||
| if (p1 == null) { | |||
| if (newProject == null) { | |||
| reinit(); | |||
| } | |||
| if(dir == null) | |||
| if (dir == null) { | |||
| dir = project.getBaseDir(); | |||
| } | |||
| initializeProject(); | |||
| p1.setBaseDir(dir); | |||
| p1.setUserProperty("basedir" , dir.getAbsolutePath()); | |||
| newProject.setBaseDir(dir); | |||
| newProject.setUserProperty("basedir" , dir.getAbsolutePath()); | |||
| // Override with local-defined properties | |||
| Enumeration e = properties.elements(); | |||
| @@ -226,43 +240,59 @@ public class Ant extends Task { | |||
| p.execute(); | |||
| } | |||
| if (antFile == null) | |||
| if (antFile == null) { | |||
| antFile = "build.xml"; | |||
| } | |||
| File file = FileUtils.newFileUtils().resolveFile(dir, antFile); | |||
| 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) { | |||
| target = p1.getDefaultTarget(); | |||
| target = newProject.getDefaultTarget(); | |||
| } | |||
| // 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 && | |||
| target.equals(this.getOwningTarget().getName())) { | |||
| throw new BuildException("ant task calling its own parent target"); | |||
| } | |||
| p1.executeTarget(target); | |||
| newProject.executeTarget(target); | |||
| } finally { | |||
| // help the gc | |||
| p1 = null; | |||
| newProject = null; | |||
| } | |||
| } | |||
| /** | |||
| * ... | |||
| */ | |||
| public void setDir(File 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) { | |||
| // @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; | |||
| } | |||
| /** | |||
| * set the target to execute. If none is defined it will | |||
| * execute the default target of the build file | |||
| */ | |||
| public void setTarget(String s) { | |||
| this.target = s; | |||
| } | |||
| @@ -271,12 +301,12 @@ public class Ant extends Task { | |||
| this.output = s; | |||
| } | |||
| /** create a property to pass to the new project as a 'user property' */ | |||
| public Property createProperty() { | |||
| if (p1 == null) { | |||
| if (newProject == null) { | |||
| reinit(); | |||
| } | |||
| Property p=(Property)p1.createTask("property"); | |||
| Property p=(Property)newProject.createTask("property"); | |||
| p.setUserProperty(true); | |||
| properties.addElement( p ); | |||
| return p; | |||
| @@ -146,7 +146,7 @@ public class AntStructure extends Task { | |||
| private void printHead(PrintWriter out, Enumeration tasks, | |||
| 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.print("<!ENTITY % tasks \""); | |||
| boolean first = true; | |||
| @@ -141,20 +141,29 @@ public class Jar extends Zip { | |||
| throws IOException, BuildException | |||
| { | |||
| 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); | |||
| } | |||
| for (Enumeration e = execManifest.getWarnings(); e.hasMoreElements(); ) { | |||
| log("Manifest warning: " + (String)e.nextElement(), Project.MSG_WARN); | |||
| } | |||
| 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); | |||
| } | |||
| 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 | |||
| * | |||
| @@ -223,30 +210,17 @@ public class Jar extends Zip { | |||
| protected void zipFile(File file, ZipOutputStream zOut, String vPath) | |||
| 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")) { | |||
| 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 { | |||
| super.zipFile(file, zOut, vPath); | |||
| } | |||
| } | |||
| protected void zipFile(InputStream is, ZipOutputStream zOut, String vPath, long lastModified) | |||
| @@ -82,6 +82,7 @@ import java.io.File; | |||
| * <li>failonerror | |||
| * <li>includeantruntime | |||
| * <li>includejavaruntime | |||
| * <li>source | |||
| * </ul> | |||
| * Of these arguments, the <b>sourcedir</b> and <b>destdir</b> are required. | |||
| * <p> | |||
| @@ -122,6 +123,24 @@ public class Javac extends MatchingTask { | |||
| protected boolean failOnError = true; | |||
| 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 | |||
| * support. | |||
| @@ -433,7 +452,15 @@ public class Javac extends MatchingTask { | |||
| */ | |||
| 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"); | |||
| if (fork) { | |||
| if (compiler != null) { | |||
| if (fork) { | |||
| if (compiler != null) { | |||
| if (isJdkCompiler(compiler)) { | |||
| log("Since fork is true, ignoring build.compiler setting.", | |||
| Project.MSG_WARN); | |||
| @@ -499,13 +526,13 @@ public class Javac extends MatchingTask { | |||
| else { | |||
| log("Since build.compiler setting isn't classic or modern, ignoring fork setting.", Project.MSG_WARN); | |||
| } | |||
| } | |||
| } | |||
| else { | |||
| compiler = "extJavac"; | |||
| } | |||
| } | |||
| } | |||
| if (compiler == null) { | |||
| if (compiler == null) { | |||
| if (Project.getJavaVersion() != Project.JAVA_1_1 && | |||
| Project.getJavaVersion() != Project.JAVA_1_2) { | |||
| compiler = "modern"; | |||
| @@ -512,8 +512,13 @@ public class SQLExec extends Task { | |||
| project.getProperties()); | |||
| 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 = sql.trim(); | |||
| @@ -216,11 +216,21 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { | |||
| boolean usingJava1_1 = Project.getJavaVersion().equals(Project.JAVA_1_1); | |||
| String memoryParameterPrefix = usingJava1_1 ? "-J-" : "-J-X"; | |||
| 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) { | |||
| 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()) { | |||
| @@ -303,6 +313,23 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { | |||
| 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 | |||
| * modern and adds the files to compile as well. | |||
| @@ -81,7 +81,7 @@ public class Javac13 extends DefaultCompilerAdapter { | |||
| public boolean execute() throws BuildException { | |||
| 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: | |||
| try { | |||
| @@ -200,7 +200,7 @@ public class Cab extends MatchingTask { | |||
| if (cmdOptions != null) | |||
| { | |||
| command.createArgument().setValue(cmdOptions); | |||
| command.createArgument().setLine(cmdOptions); | |||
| } | |||
| command.createArgument().setValue("n"); | |||
| @@ -257,7 +257,7 @@ public class Depend extends MatchingTask { | |||
| classFileInfoMap = new Hashtable(); | |||
| boolean cacheDirty = false; | |||
| Hashtable dependencyMap = null; | |||
| Hashtable dependencyMap = new Hashtable(); | |||
| File depCacheFile = null; | |||
| boolean depCacheFileExists = true; | |||
| long depCacheFileLastModified = Long.MAX_VALUE; | |||
| @@ -806,12 +806,12 @@ public class FTP | |||
| } | |||
| 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 | |||
| // failed because the directory already exists. | |||
| 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: " + | |||
| ftp.getReplyString() ); | |||
| } | |||
| @@ -84,303 +84,303 @@ import java.io.*; | |||
| * @author <a href="sbailliez@imediation.com">Stephane Bailliez</a> | |||
| */ | |||
| 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 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:umagesh@rediffmail.com">Magesh Umasankar</a> | |||
| */ | |||
| public class FileSet extends DataType { | |||
| @@ -80,6 +81,7 @@ public class FileSet extends DataType { | |||
| private File dir; | |||
| private boolean useDefaultExcludes = true; | |||
| private boolean isCaseSensitive = true; | |||
| public FileSet() { | |||
| super(); | |||
| @@ -90,6 +92,7 @@ public class FileSet extends DataType { | |||
| this.defaultPatterns = fileset.defaultPatterns; | |||
| this.additionalPatterns = fileset.additionalPatterns; | |||
| this.useDefaultExcludes = fileset.useDefaultExcludes; | |||
| this.isCaseSensitive = fileset.isCaseSensitive; | |||
| } | |||
| @@ -244,6 +247,16 @@ public class FileSet extends DataType { | |||
| 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. | |||
| */ | |||
| @@ -287,6 +300,7 @@ public class FileSet extends DataType { | |||
| ds.setIncludes(defaultPatterns.getIncludePatterns(p)); | |||
| ds.setExcludes(defaultPatterns.getExcludePatterns(p)); | |||
| 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 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> | |||
| * @created 14 March 2001 | |||
| @@ -324,7 +324,7 @@ public class FilterSet extends DataType { | |||
| /** | |||
| * 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. | |||
| * @return The string with the tokens replaced. | |||
| @@ -93,7 +93,7 @@ public class FilterSetCollection { | |||
| /** | |||
| * 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. | |||
| * @return The string with the tokens replaced. | |||
| @@ -74,11 +74,14 @@ public class SourceFileScanner { | |||
| protected Task task; | |||
| private FileUtils fileUtils; | |||
| /** | |||
| * @param task The task we should log messages through | |||
| */ | |||
| public SourceFileScanner(Task task) { | |||
| this.task = task; | |||
| fileUtils = FileUtils.newFileUtils(); | |||
| } | |||
| /** | |||
| @@ -118,7 +121,7 @@ public class SourceFileScanner { | |||
| continue; | |||
| } | |||
| File src = new File(srcDir, files[i]); | |||
| File src = fileUtils.resolveFile(srcDir, files[i]); | |||
| if (src.lastModified() > now) { | |||
| task.log("Warning: "+files[i]+" modified in the future.", | |||
| Project.MSG_WARN); | |||
| @@ -131,7 +134,7 @@ public class SourceFileScanner { | |||
| if (destDir == null) { | |||
| dest = new File(targets[j]); | |||
| } else { | |||
| dest = new File(destDir, targets[j]); | |||
| dest = fileUtils.resolveFile(destDir, targets[j]); | |||
| } | |||
| if (!dest.exists()) { | |||