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()) { | |||